/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.module.service; import static java.lang.Thread.currentThread; import static java.util.Collections.unmodifiableList; import static org.mule.runtime.api.util.Preconditions.checkArgument; import static org.mule.runtime.container.api.MuleFoldersUtil.getServicesFolder; import static org.mule.runtime.module.service.LifecycleFilterServiceProxy.createLifecycleFilterServiceProxy; import static org.slf4j.LoggerFactory.getLogger; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.api.lifecycle.Startable; import org.mule.runtime.api.lifecycle.Stoppable; import org.mule.runtime.api.service.Service; import org.mule.runtime.core.api.lifecycle.StartException; import java.io.File; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; /** * Service manager to use in the Mule container. */ public class MuleServiceManager implements ServiceManager { private static final Logger logger = getLogger(MuleServiceManager.class); private final ServiceDiscoverer serviceDiscoverer; private List<Service> registeredServices = new ArrayList<>(); private List<Service> wrappedServices; /** * Creates a new instance. * * @param serviceDiscoverer container service discoverer. Non null. */ public MuleServiceManager(ServiceDiscoverer serviceDiscoverer) { checkArgument(serviceDiscoverer != null, "serviceDiscoverer cannot be null"); this.serviceDiscoverer = serviceDiscoverer; } @Override public void start() throws MuleException { File servicesFolder = getServicesFolder(); if (!servicesFolder.exists()) { servicesFolder.mkdir(); } try { registeredServices = serviceDiscoverer.discoverServices(); wrappedServices = wrapServices(registeredServices); startServices(); } catch (Exception e) { throw new StartException(e, this); } } private List<Service> wrapServices(List<Service> registeredServices) { final List<Service> result = new ArrayList<>(registeredServices.size()); for (Service registeredService : registeredServices) { final Service serviceProxy = createLifecycleFilterServiceProxy(registeredService); result.add(serviceProxy); } return unmodifiableList(result); } private void startServices() throws MuleException { for (Service service : registeredServices) { if (service instanceof Startable) { ClassLoader originalContextClassLoader = currentThread().getContextClassLoader(); try { currentThread().setContextClassLoader(service.getClass().getClassLoader()); ((Startable) service).start(); } finally { currentThread().setContextClassLoader(originalContextClassLoader); } } } } @Override public void stop() throws MuleException { for (int i = registeredServices.size() - 1; i >= 0; i--) { Service service = registeredServices.get(i); if (service instanceof Stoppable) { try { ((Stoppable) service).stop(); } catch (Exception e) { logger.warn("Service {s} was not stopped properly: {s}", service.getName(), e.getMessage()); } } } } @Override public List<Service> getServices() { return wrappedServices; } }