001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 * Florent Guillaume 019 */ 020package org.nuxeo.ecm.admin; 021 022import static org.jboss.seam.ScopeType.CONVERSATION; 023 024import java.io.IOException; 025import java.io.Serializable; 026import java.lang.management.ManagementFactory; 027import java.lang.management.RuntimeMXBean; 028import java.util.ArrayList; 029import java.util.List; 030 031import javax.faces.context.FacesContext; 032import javax.servlet.http.HttpServletRequest; 033 034import org.apache.commons.logging.Log; 035import org.apache.commons.logging.LogFactory; 036import org.jboss.seam.ScopeType; 037import org.jboss.seam.annotations.Factory; 038import org.jboss.seam.annotations.Name; 039import org.jboss.seam.annotations.Scope; 040import org.jboss.seam.contexts.Contexts; 041import org.nuxeo.common.utils.ExceptionUtils; 042import org.nuxeo.ecm.admin.repo.RepoStat; 043import org.nuxeo.ecm.admin.repo.RepoStatInfo; 044import org.nuxeo.ecm.admin.runtime.PlatformVersionHelper; 045import org.nuxeo.ecm.admin.runtime.RuntimeInstrospection; 046import org.nuxeo.ecm.admin.runtime.SimplifiedServerInfo; 047import org.nuxeo.ecm.core.api.CoreInstance; 048import org.nuxeo.ecm.core.api.PathRef; 049import org.nuxeo.ecm.core.api.repository.Repository; 050import org.nuxeo.ecm.core.api.repository.RepositoryManager; 051import org.nuxeo.ecm.core.blob.binary.BinaryManagerStatus; 052import org.nuxeo.ecm.core.storage.sql.management.SQLRepositoryStatus; 053import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants; 054import org.nuxeo.ecm.platform.ui.web.util.BaseURL; 055import org.nuxeo.runtime.api.Framework; 056 057/** 058 * Seam Bean to export System info. 059 */ 060@Name("systemInfo") 061@Scope(CONVERSATION) 062public class SystemInfoManager implements Serializable { 063 064 private static final Log log = LogFactory.getLog(SystemInfoManager.class); 065 066 protected static final String RESTART_PATH = "site/connectClient/restartView"; 067 068 private static final long serialVersionUID = 1L; 069 070 protected List<Repository> repositories; 071 072 protected String currentRepositoryName; 073 074 protected RepoStat runningStat; 075 076 protected RepoStatInfo statResult; 077 078 protected volatile boolean binaryManagerStatusInvalidation; 079 080 protected volatile BinaryManagerStatus binaryManagerStatus; 081 082 protected boolean binariesGCDelete; 083 084 protected boolean binariesWereDeleted; 085 086 // ********************************* 087 // Host info Management 088 089 public String getHostInfo() { 090 091 StringBuilder sb = new StringBuilder(); 092 093 sb.append("\nOS : "); 094 sb.append(System.getProperty("os.name")); 095 sb.append(" ("); 096 sb.append(System.getProperty("os.arch")); 097 sb.append(")"); 098 099 sb.append("\n"); 100 101 sb.append("\nCPU(s) : "); 102 sb.append(Runtime.getRuntime().availableProcessors()); 103 104 sb.append("\n"); 105 106 sb.append("\nJVM : "); 107 sb.append(System.getProperty("java.runtime.name")); 108 sb.append(" "); 109 sb.append(System.getProperty("java.runtime.version")); 110 sb.append(" - build "); 111 sb.append(System.getProperty("java.vm.version")); 112 sb.append(" ("); 113 sb.append(System.getProperty("java.vendor")); 114 sb.append(")"); 115 116 sb.append("\n"); 117 118 sb.append("\nPlatform language : "); 119 sb.append(System.getProperty("user.language")); 120 sb.append(" "); 121 sb.append(System.getenv("LANG")); 122 123 sb.append("\n"); 124 125 sb.append("\nJava Memory:"); 126 sb.append("\n Heap size : "); 127 sb.append(Runtime.getRuntime().totalMemory() / (1024 * 1024)); 128 sb.append(" MB"); 129 sb.append("\n Used : "); 130 sb.append((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)); 131 sb.append(" MB"); 132 sb.append("\n Free : "); 133 sb.append(Runtime.getRuntime().freeMemory() / (1024 * 1024)); 134 sb.append(" MB"); 135 sb.append("\n Max size : "); 136 sb.append(Runtime.getRuntime().maxMemory() / (1024 * 1024)); 137 sb.append(" MB"); 138 139 return sb.toString(); 140 } 141 142 public String getUptime() { 143 RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); 144 long ut = bean.getUptime(); 145 long uts = ut / 1000; 146 147 StringBuffer sb = new StringBuffer("Nuxeo Server UpTime : "); 148 long nbDays = uts / (24 * 3600); 149 if (nbDays > 0) { 150 sb.append(nbDays + " days, "); 151 uts = uts % (24 * 3600); 152 } 153 long nbHours = uts / 3600; 154 sb.append(nbHours + " h "); 155 uts = uts % 3600; 156 157 long nbMin = uts / 60; 158 sb.append(nbMin + " m "); 159 uts = uts % 60; 160 161 sb.append(uts + " s "); 162 163 return sb.toString(); 164 } 165 166 @Factory(value = "nuxeoPlatformIdentifier", scope = ScopeType.APPLICATION) 167 public String getNuxeoPlatformIdentifier() { 168 return PlatformVersionHelper.getPlatformFilter(); 169 } 170 171 @Factory(value = "nuxeoServerInfo", scope = ScopeType.EVENT) 172 public SimplifiedServerInfo getNuxeoServerInfo() { 173 return RuntimeInstrospection.getInfo(); 174 } 175 176 public boolean isBundleDeployed(String bundleId) { 177 return RuntimeInstrospection.getBundleIds().contains(bundleId); 178 } 179 180 // ********************************* 181 // Repo settings Management 182 183 public boolean isMultiRepo() { 184 return listAvailableRepositories().size() > 1; 185 } 186 187 public List<Repository> listAvailableRepositories() { 188 if (repositories == null) { 189 RepositoryManager repositoryManager = Framework.getLocalService(RepositoryManager.class); 190 repositories = new ArrayList<Repository>(repositoryManager.getRepositories()); 191 currentRepositoryName = repositoryManager.getDefaultRepositoryName(); 192 } 193 return repositories; 194 } 195 196 public String getCurrentRepositoryName() { 197 if (currentRepositoryName == null) { 198 listAvailableRepositories(); 199 } 200 return currentRepositoryName; 201 } 202 203 public void setCurrentRepositoryName(String name) { 204 currentRepositoryName = name; 205 } 206 207 public int getOpenSessionNumber() { 208 return CoreInstance.getInstance().getNumberOfSessions(); 209 } 210 211 public int getActiveSessionNumber() { 212 SQLRepositoryStatus status = new SQLRepositoryStatus(); 213 return status.getActiveSessionsCount(); 214 } 215 216 // ********************************* 217 // Repo stats Management 218 219 public void startRepoStats() { 220 if (runningStat != null) { 221 return; 222 } 223 224 statResult = null; 225 runningStat = new RepoStat(getCurrentRepositoryName(), 5, true); 226 runningStat.run(new PathRef("/")); 227 } 228 229 public boolean isStatInfoInProgress() { 230 if (isStatInfoAvailable()) { 231 return false; 232 } 233 return runningStat != null; 234 } 235 236 public boolean isStatInfoAvailable() { 237 if (statResult != null) { 238 return true; 239 } 240 if (runningStat != null) { 241 if (!runningStat.isRunning()) { 242 statResult = runningStat.getInfo(); 243 Contexts.getEventContext().remove("repoStatResult"); 244 runningStat = null; 245 return true; 246 } 247 } 248 return false; 249 } 250 251 @Factory(value = "repoStatResult", scope = ScopeType.EVENT) 252 public RepoStatInfo getStatInfo() { 253 return statResult; 254 } 255 256 public String getRepoUsage() { 257 StringBuilder sb = new StringBuilder(); 258 259 int nbSessions = CoreInstance.getInstance().getNumberOfSessions(); 260 261 sb.append("Number of open repository session : "); 262 sb.append(nbSessions); 263 264 RepoStat stat = new RepoStat("default", 5, true); 265 stat.run(new PathRef("/")); 266 267 try { 268 Thread.sleep(100); 269 do { 270 Thread.sleep(1000); 271 } while (stat.isRunning()); 272 } catch (InterruptedException e) { 273 throw ExceptionUtils.runtimeException(e); 274 } 275 276 sb.append(stat.getInfo().toString()); 277 278 return sb.toString(); 279 } 280 281 // ********************************* 282 // Server restart 283 284 public String restartServer() { 285 FacesContext context = FacesContext.getCurrentInstance(); 286 HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); 287 request.setAttribute(NXAuthConstants.DISABLE_REDIRECT_REQUEST_KEY, Boolean.TRUE); 288 String restartUrl = BaseURL.getBaseURL(request) + RESTART_PATH; 289 try { 290 context.getExternalContext().redirect(restartUrl); 291 } catch (IOException e) { 292 log.error("Error while redirecting to restart page", e); 293 } 294 return null; 295 } 296 297 // ********************************* 298 // Binaries GC 299 300 public void setBinariesGCDelete(boolean binariesGCDelete) { 301 this.binariesGCDelete = binariesGCDelete; 302 } 303 304 public boolean getBinariesGCDelete() { 305 return binariesGCDelete; 306 } 307 308 public boolean getBinariesWereDeleted() { 309 return binariesWereDeleted; 310 } 311 312 public void startBinariesGC() { 313 if (isBinariesGCInProgress()) { 314 return; 315 } 316 binaryManagerStatus = null; 317 binaryManagerStatusInvalidation = false; 318 Runnable gcTask = new BinariesGCTask(binariesGCDelete); 319 Thread t = new Thread(gcTask, "NuxeoBinariesGCUI"); 320 t.setDaemon(true); 321 t.start(); 322 binariesWereDeleted = binariesGCDelete; 323 binariesGCDelete = false; 324 } 325 326 public boolean isBinariesGCInProgress() { 327 return new SQLRepositoryStatus().isBinariesGCInProgress(); 328 } 329 330 public boolean isBinaryManagerStatusAvailable() { 331 if (binaryManagerStatusInvalidation) { 332 // invalidate Seam value in context 333 Contexts.getEventContext().remove("binaryManagerStatus"); 334 binaryManagerStatusInvalidation = false; 335 } 336 return binaryManagerStatus != null; 337 } 338 339 @Factory(value = "binaryManagerStatus", scope = ScopeType.EVENT) 340 public BinaryManagerStatus getBinaryManagerStatus() { 341 return binaryManagerStatus; 342 343 } 344 345 public class BinariesGCTask implements Runnable { 346 public boolean delete; 347 348 public BinariesGCTask(boolean delete) { 349 this.delete = delete; 350 } 351 352 @Override 353 public void run() { 354 try { 355 binaryManagerStatus = new SQLRepositoryStatus().gcBinaries(delete); 356 binaryManagerStatusInvalidation = true; 357 } catch (RuntimeException e) { 358 log.error("Error while executing BinariesGCTask", e); 359 } 360 } 361 } 362 363}