/* * * * Copyright (c) 2016. David Sowerby * * * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * * the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * * specific language governing permissions and limitations under the License. * */ package uk.q3c.krail.core.services; import com.google.common.collect.ImmutableList; import com.google.common.collect.MapMaker; import com.google.inject.Inject; import com.google.inject.Singleton; import net.engio.mbassy.listener.Handler; import net.engio.mbassy.listener.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.q3c.krail.core.eventbus.GlobalBusProvider; import javax.annotation.concurrent.ThreadSafe; import java.time.LocalDateTime; import java.util.Map; /** * Uses the GlobalBus to monitor changes to Service status */ @Singleton @Listener @ThreadSafe public class DefaultServicesMonitor implements ServicesMonitor { private static final Logger log = LoggerFactory.getLogger(DefaultServicesMonitor.class); private final Map<Service, ServiceStatusRecord> services; @Inject public DefaultServicesMonitor(GlobalBusProvider globalBusProvider) { this.services = new MapMaker().weakKeys() .makeMap(); globalBusProvider.get() .subscribe(this); } @Handler synchronized public void serviceStatusChange(ServiceBusMessage busMessage) { Service service = busMessage.getService(); if (!services.containsKey(service)) { ServiceStatusRecord serviceStatusRecord = new ServiceStatusRecord(); serviceStatusRecord.setService(service); services.put(service, serviceStatusRecord); log.debug("registered service '{}'", service.getName()); } ServiceStatusRecord status = services.get(service); status.setPreviousState(status.getCurrentState()); status.setCurrentState(busMessage.getToState()); //call LocalDateTime.now() just once, otherwise there are tiny differences between change time & start / stop times LocalDateTime serviceChangeTime = LocalDateTime.now(); status.setStatusChangeTime(serviceChangeTime); if (service.isStarted()) { status.setLastStartTime(LocalDateTime.from(serviceChangeTime)); } if (service.isStopped()) { status.setLastStopTime(LocalDateTime.from(serviceChangeTime)); } services.put(service, status); } /** * Returns a list of services being monitored. If a service has never started, it will not be in the list * * @return a list of services being monitored. */ @Override public synchronized ImmutableList<Service> getMonitoredServices() { return ImmutableList.copyOf(services.keySet()); } @Override public synchronized ServiceStatusRecord getServiceStatus(Service service) { return services.get(service); } public synchronized void clear() { services.clear(); } }