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