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