/* * 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 com.bunjlabs.fuga.services; import com.bunjlabs.fuga.FugaApp; import com.bunjlabs.fuga.dependency.InjectException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ServiceManager { private final Logger log = LogManager.getLogger(ServiceManager.class); private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private final Map<Class<? extends Service>, ServiceAgent> services = new HashMap<>(); private final FugaApp app; /** * Create service manager for the specified fuga application. * * @param app Fuga application. */ public ServiceManager(FugaApp app) { this.app = app; } /** * Register specified service class. * * @param service Service class. */ public void register(Class<? extends Service> service) { try { Service serviceInstance = app.getDependencyManager().registerAndInject(service); services.put(service, new ServiceAgent(serviceInstance)); serviceInstance.onCreate(); } catch (InjectException ex) { log.error("Unable to inject dependencies to the service", ex); } } /** * Register specified service class and shedule service updates. * * Calling this method is identical to: * <pre> * register(service); * schedule(service, updateTime, timeUnit); * </pre> * * @param service Service class. * @param updateTime Update time period. * @param timeUnit Period time unit. */ public void register(Class<? extends Service> service, long updateTime, TimeUnit timeUnit) { register(service); schedule(service, updateTime, timeUnit); } /** * Shedule specified service updates. * * @param service Service class. * @param updateTime Update time period. * @param timeUnit Period time unit. */ public void schedule(Class<? extends Service> service, long updateTime, TimeUnit timeUnit) { ServiceAgent serviceAgent = services.get(service); if (serviceAgent == null) { log.error("Unable to shedule service update. Service " + service.getName() + " not found."); return; } if (serviceAgent.isSheduled()) { log.error("Unable to shedule service update. Service " + service.getName() + " already scheduled."); return; } serviceAgent.setScheduledFuture(scheduler.scheduleAtFixedRate(serviceAgent.getService()::onUpdate, 0, updateTime, timeUnit)); } /** * Unregister specified service and remove shedule if it presents. * * @param service Service class. */ public void unregister(Class<? extends Service> service) { ServiceAgent serviceAgent = services.get(service); if (serviceAgent.isSheduled()) { serviceAgent.getScheduledFuture().cancel(true); } services.remove(service); } /** * Get service instance by service class. * * @param <T> Type of service instance. * @param service Service class. * @return Service instance. */ public <T extends Service> T getService(Class<T> service) { ServiceAgent serviceAgent = services.get(service); if (serviceAgent != null) { return (T) serviceAgent.getService(); } return null; } }