001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * mcedica 011 */ 012package org.nuxeo.ecm.core.management.probes; 013 014import java.util.Collection; 015import java.util.Collections; 016import java.util.Date; 017import java.util.HashMap; 018import java.util.HashSet; 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.nuxeo.ecm.core.management.api.Probe; 025import org.nuxeo.ecm.core.management.api.ProbeInfo; 026import org.nuxeo.ecm.core.management.api.ProbeManager; 027import org.nuxeo.ecm.core.management.api.ProbeStatus; 028import org.nuxeo.runtime.management.ManagementRuntimeException; 029 030public class ProbeManagerImpl implements ProbeManager { 031 032 protected static final Log log = LogFactory.getLog(ProbeManagerImpl.class); 033 034 protected final Map<Class<? extends Probe>, ProbeInfo> infosByTypes = new HashMap<Class<? extends Probe>, ProbeInfo>(); 035 036 protected final Map<String, ProbeInfo> infosByShortcuts = new HashMap<String, ProbeInfo>(); 037 038 protected final Map<String, Probe> probesByShortcuts = new HashMap<String, Probe>(); 039 040 protected final Set<ProbeInfo> failed = new HashSet<ProbeInfo>(); 041 042 protected final Set<ProbeInfo> succeed = new HashSet<ProbeInfo>(); 043 044 protected Set<String> doExtractProbesName(Collection<ProbeInfo> runners) { 045 Set<String> names = new HashSet<String>(); 046 for (ProbeInfo runner : runners) { 047 names.add(runner.getShortcutName()); 048 } 049 return names; 050 } 051 052 @Override 053 public Collection<ProbeInfo> getAllProbeInfos() { 054 return Collections.unmodifiableCollection(infosByTypes.values()); 055 } 056 057 @Override 058 public Collection<ProbeInfo> getInSuccessProbeInfos() { 059 return Collections.unmodifiableCollection(succeed); 060 } 061 062 @Override 063 public Collection<ProbeInfo> getInFailureProbeInfos() { 064 return Collections.unmodifiableCollection(failed); 065 } 066 067 @Override 068 public Collection<String> getProbeNames() { 069 return infosByShortcuts.keySet(); 070 } 071 072 @Override 073 public int getProbesCount() { 074 return infosByTypes.size(); 075 } 076 077 @Override 078 public Collection<String> getProbesInError() { 079 return doExtractProbesName(failed); 080 } 081 082 @Override 083 public int getProbesInErrorCount() { 084 return failed.size(); 085 } 086 087 @Override 088 public Collection<String> getProbesInSuccess() { 089 return doExtractProbesName(succeed); 090 } 091 092 @Override 093 public int getProbesInSuccessCount() { 094 return succeed.size(); 095 } 096 097 @Override 098 public ProbeInfo getProbeInfo(Class<? extends Probe> probeClass) { 099 ProbeInfo info = infosByTypes.get(probeClass); 100 if (info == null) { 101 throw new IllegalArgumentException("no probe registered for " + probeClass); 102 } 103 return info; 104 } 105 106 @Override 107 public boolean runAllProbes() { 108 doRun(); 109 return getProbesInErrorCount() <= 0; 110 } 111 112 @Override 113 public ProbeInfo runProbe(ProbeInfo probe) { 114 doRunProbe(probe); 115 return probe; 116 } 117 118 @Override 119 public ProbeInfo runProbe(String name) { 120 ProbeInfo probeInfo = getProbeInfo(name); 121 if (probeInfo == null) { 122 log.warn("Probe " + name + " can not be found"); 123 return null; 124 } 125 return runProbe(probeInfo); 126 } 127 128 @Override 129 public ProbeInfo getProbeInfo(String name) { 130 return infosByShortcuts.get(name); 131 } 132 133 public void registerProbe(ProbeDescriptor descriptor) { 134 Class<? extends Probe> probeClass = descriptor.getProbeClass(); 135 Probe probe; 136 try { 137 probe = probeClass.newInstance(); 138 } catch (ReflectiveOperationException e) { 139 throw new ManagementRuntimeException("Cannot create management probe for " + descriptor); 140 } 141 142 ProbeInfoImpl info = new ProbeInfoImpl(descriptor); 143 infosByTypes.put(probeClass, info); 144 infosByShortcuts.put(descriptor.getShortcut(), info); 145 probesByShortcuts.put(descriptor.getShortcut(), probe); 146 } 147 148 public void unregisterProbe(ProbeDescriptor descriptor) { 149 Class<? extends Probe> probeClass = descriptor.getProbeClass(); 150 infosByTypes.remove(probeClass); 151 infosByShortcuts.remove(descriptor.getShortcut()); 152 } 153 154 protected void doRun() { 155 for (ProbeInfo probe : infosByTypes.values()) { 156 doRunProbe(probe); 157 } 158 } 159 160 protected static Long doGetDuration(Date fromDate, Date toDate) { 161 return toDate.getTime() - fromDate.getTime(); 162 } 163 164 protected void doRunProbe(ProbeInfo probe) { 165 if (!probe.isEnabled()) { 166 return; 167 } 168 boolean ok = false; 169 try { 170 ProbeInfoImpl probeInfoImpl = (ProbeInfoImpl) probe; 171 Thread currentThread = Thread.currentThread(); 172 ClassLoader lastLoader = currentThread.getContextClassLoader(); 173 currentThread.setContextClassLoader(ProbeInfoImpl.class.getClassLoader()); 174 probeInfoImpl.lastRunnedDate = new Date(); 175 probeInfoImpl.runnedCount += 1; 176 try { 177 Probe runnableProbe = probesByShortcuts.get(probe.getShortcutName()); 178 probeInfoImpl.lastStatus = runnableProbe.run(); 179 if (probeInfoImpl.lastStatus.isSuccess()) { 180 probeInfoImpl.lastSucceedDate = probeInfoImpl.lastRunnedDate; 181 probeInfoImpl.lastSuccessStatus = probeInfoImpl.lastStatus; 182 probeInfoImpl.successCount += 1; 183 } else { 184 probeInfoImpl.lastFailureStatus = probeInfoImpl.lastStatus; 185 probeInfoImpl.failureCount += 1; 186 probeInfoImpl.lastFailureDate = probeInfoImpl.lastRunnedDate; 187 } 188 } catch (RuntimeException e) { 189 probeInfoImpl.failureCount += 1; 190 probeInfoImpl.lastFailureDate = new Date(); 191 probeInfoImpl.lastFailureStatus = ProbeStatus.newError(e); 192 // then swallow exception 193 } finally { 194 probeInfoImpl.lastDuration = doGetDuration(probeInfoImpl.lastRunnedDate, new Date()); 195 currentThread.setContextClassLoader(lastLoader); 196 } 197 198 if (probe.isInError()) { 199 succeed.remove(probe); 200 failed.add(probe); 201 } else { 202 failed.remove(probe); 203 succeed.add(probe); 204 } 205 ok = true; 206 } finally { 207 if (!ok) { 208 succeed.remove(probe); 209 failed.add(probe); 210 } 211 } 212 } 213 214}