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.ecm.admin.repo.RepoStat; 042import org.nuxeo.ecm.admin.repo.RepoStatInfo; 043import org.nuxeo.ecm.admin.runtime.PlatformVersionHelper; 044import org.nuxeo.ecm.admin.runtime.RuntimeInstrospection; 045import org.nuxeo.ecm.admin.runtime.SimplifiedServerInfo; 046import org.nuxeo.ecm.core.api.CoreSessionService; 047import org.nuxeo.ecm.core.api.PathRef; 048import org.nuxeo.ecm.core.api.repository.Repository; 049import org.nuxeo.ecm.core.api.repository.RepositoryManager; 050import org.nuxeo.ecm.core.blob.binary.BinaryManagerStatus; 051import org.nuxeo.ecm.core.storage.sql.management.SQLRepositoryStatus; 052import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants; 053import org.nuxeo.ecm.platform.ui.web.util.BaseURL; 054import org.nuxeo.runtime.api.Framework; 055 056/** 057 * Seam Bean to export System info. 058 */ 059@Name("systemInfo") 060@Scope(CONVERSATION) 061public class SystemInfoManager implements Serializable { 062 063 private static final Log log = LogFactory.getLog(SystemInfoManager.class); 064 065 protected static final String RESTART_PATH = "site/connectClient/restartView"; 066 067 private static final long serialVersionUID = 1L; 068 069 protected List<Repository> repositories; 070 071 protected String currentRepositoryName; 072 073 protected RepoStat runningStat; 074 075 protected RepoStatInfo statResult; 076 077 protected volatile boolean binaryManagerStatusInvalidation; 078 079 protected volatile BinaryManagerStatus binaryManagerStatus; 080 081 protected boolean binariesGCDelete; 082 083 protected boolean binariesWereDeleted; 084 085 // ********************************* 086 // Host info Management 087 088 public String getHostInfo() { 089 090 StringBuilder sb = new StringBuilder(); 091 092 sb.append("\nOS : "); 093 sb.append(System.getProperty("os.name")); 094 sb.append(" ("); 095 sb.append(System.getProperty("os.arch")); 096 sb.append(")"); 097 098 sb.append("\n"); 099 100 sb.append("\nCPU(s) : "); 101 sb.append(Runtime.getRuntime().availableProcessors()); 102 103 sb.append("\n"); 104 105 sb.append("\nJVM : "); 106 sb.append(System.getProperty("java.runtime.name")); 107 sb.append(" "); 108 sb.append(System.getProperty("java.runtime.version")); 109 sb.append(" - build "); 110 sb.append(System.getProperty("java.vm.version")); 111 sb.append(" ("); 112 sb.append(System.getProperty("java.vendor")); 113 sb.append(")"); 114 115 sb.append("\n"); 116 117 sb.append("\nPlatform language : "); 118 sb.append(System.getProperty("user.language")); 119 sb.append(" "); 120 sb.append(System.getenv("LANG")); 121 122 sb.append("\n"); 123 124 sb.append("\nJava Memory:"); 125 sb.append("\n Heap size : "); 126 sb.append(Runtime.getRuntime().totalMemory() / (1024 * 1024)); 127 sb.append(" MB"); 128 sb.append("\n Used : "); 129 sb.append((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)); 130 sb.append(" MB"); 131 sb.append("\n Free : "); 132 sb.append(Runtime.getRuntime().freeMemory() / (1024 * 1024)); 133 sb.append(" MB"); 134 sb.append("\n Max size : "); 135 sb.append(Runtime.getRuntime().maxMemory() / (1024 * 1024)); 136 sb.append(" MB"); 137 138 return sb.toString(); 139 } 140 141 public String getUptime() { 142 RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); 143 long ut = bean.getUptime(); 144 long uts = ut / 1000; 145 146 StringBuffer sb = new StringBuffer("Nuxeo Server UpTime : "); 147 long nbDays = uts / (24 * 3600); 148 if (nbDays > 0) { 149 sb.append(nbDays + " days, "); 150 uts = uts % (24 * 3600); 151 } 152 long nbHours = uts / 3600; 153 sb.append(nbHours + " h "); 154 uts = uts % 3600; 155 156 long nbMin = uts / 60; 157 sb.append(nbMin + " m "); 158 uts = uts % 60; 159 160 sb.append(uts + " s "); 161 162 return sb.toString(); 163 } 164 165 @Factory(value = "nuxeoPlatformIdentifier", scope = ScopeType.APPLICATION) 166 public String getNuxeoPlatformIdentifier() { 167 return PlatformVersionHelper.getPlatformFilter(); 168 } 169 170 @Factory(value = "nuxeoServerInfo", scope = ScopeType.EVENT) 171 public SimplifiedServerInfo getNuxeoServerInfo() { 172 return RuntimeInstrospection.getInfo(); 173 } 174 175 public boolean isBundleDeployed(String bundleId) { 176 return RuntimeInstrospection.getBundleIds().contains(bundleId); 177 } 178 179 // ********************************* 180 // Repo settings Management 181 182 public boolean isMultiRepo() { 183 return listAvailableRepositories().size() > 1; 184 } 185 186 public List<Repository> listAvailableRepositories() { 187 if (repositories == null) { 188 RepositoryManager repositoryManager = Framework.getService(RepositoryManager.class); 189 repositories = new ArrayList<Repository>(repositoryManager.getRepositories()); 190 currentRepositoryName = repositoryManager.getDefaultRepositoryName(); 191 } 192 return repositories; 193 } 194 195 public String getCurrentRepositoryName() { 196 if (currentRepositoryName == null) { 197 listAvailableRepositories(); 198 } 199 return currentRepositoryName; 200 } 201 202 public void setCurrentRepositoryName(String name) { 203 currentRepositoryName = name; 204 } 205 206 public int getOpenSessionNumber() { 207 return Framework.getService(CoreSessionService.class).getNumberOfOpenCoreSessions(); 208 } 209 210 public int getActiveSessionNumber() { 211 SQLRepositoryStatus status = new SQLRepositoryStatus(); 212 return status.getActiveSessionsCount(); 213 } 214 215 // ********************************* 216 // Repo stats Management 217 218 public void startRepoStats() { 219 if (runningStat != null) { 220 return; 221 } 222 223 statResult = null; 224 runningStat = new RepoStat(getCurrentRepositoryName(), 5, true); 225 runningStat.run(new PathRef("/")); 226 } 227 228 public boolean isStatInfoInProgress() { 229 if (isStatInfoAvailable()) { 230 return false; 231 } 232 return runningStat != null; 233 } 234 235 public boolean isStatInfoAvailable() { 236 if (statResult != null) { 237 return true; 238 } 239 if (runningStat != null) { 240 if (!runningStat.isRunning()) { 241 statResult = runningStat.getInfo(); 242 Contexts.getEventContext().remove("repoStatResult"); 243 runningStat = null; 244 return true; 245 } 246 } 247 return false; 248 } 249 250 @Factory(value = "repoStatResult", scope = ScopeType.EVENT) 251 public RepoStatInfo getStatInfo() { 252 return statResult; 253 } 254 255 public String getRepoUsage() { 256 StringBuilder sb = new StringBuilder(); 257 258 int nbSessions = Framework.getService(CoreSessionService.class).getNumberOfOpenCoreSessions(); 259 260 sb.append("Number of open repository session : "); 261 sb.append(nbSessions); 262 263 RepoStat stat = new RepoStat("default", 5, true); 264 stat.run(new PathRef("/")); 265 266 try { 267 Thread.sleep(100); 268 do { 269 Thread.sleep(1000); 270 } while (stat.isRunning()); 271 } catch (InterruptedException e) { 272 Thread.currentThread().interrupt(); 273 throw new 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}