package org.easysoa.registry.frascati; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.easysoa.frascati.FraSCAtiServiceException; import org.easysoa.frascati.api.FraSCAtiServiceItf; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.event.Event; import org.nuxeo.ecm.core.event.EventListener; import org.nuxeo.frascati.factory.NuxeoFraSCAtiStartedEvent; import org.nuxeo.runtime.model.ComponentContext; import org.nuxeo.runtime.model.ComponentInstance; import org.nuxeo.runtime.model.DefaultComponent; /** * * Component that allows the deployment of FraSCAti apps on startup through * simple XML contributions. * * @author mkalam-alami * */ public class FraSCAtiAppComponent extends DefaultComponent implements EventListener { private static final String APP_EXTENSION_POINT = "apps"; private static final Logger logger = Logger.getLogger(FraSCAtiAppComponent.class); private static List<FraSCAtiAppDescriptor> contributionCache = new LinkedList<FraSCAtiAppDescriptor>(); private FraSCAtiServiceItf frascatiService; /** * Stores composite instance keys in order to be able to stop them. */ private Map<FraSCAtiAppDescriptor, String> compositeInstances = new HashMap<FraSCAtiAppDescriptor, String>(); public void handleEvent(Event event) throws ClientException { if (NuxeoFraSCAtiStartedEvent.ID.equals(event.getName())) { NuxeoFraSCAtiStartedEvent nuxeoFraSCAtiEvent = (NuxeoFraSCAtiStartedEvent) event; frascatiService = nuxeoFraSCAtiEvent.getFraSCAtiService(); synchronized (contributionCache) { if (!contributionCache.isEmpty()) { logger.info("FraSCAti in Nuxeo is ready, handling " + contributionCache.size() + " postponed contributions"); for (FraSCAtiAppDescriptor contribution : contributionCache) { handleContribution(contribution); } } } } } @Override public void deactivate(ComponentContext context) throws Exception { for (String value : compositeInstances.values()) { frascatiService.remove(value); } } @Override public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) throws Exception { if (APP_EXTENSION_POINT.equals(extensionPoint) && contribution instanceof FraSCAtiAppDescriptor) { FraSCAtiAppDescriptor app = (FraSCAtiAppDescriptor) contribution; if (frascatiService == null) { logger.info("Contribution " + app.name + " postponed, FraSCAti in Nuxeo is not ready yet"); synchronized (contributionCache) { contributionCache.add(app); } } else { handleContribution(app); } } } @Override public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) throws Exception { if (APP_EXTENSION_POINT.equals(extensionPoint) && contribution instanceof FraSCAtiAppDescriptor) { FraSCAtiAppDescriptor app = (FraSCAtiAppDescriptor) contribution; String compositeToRemove = compositeInstances.remove(app); if (frascatiService != null && compositeToRemove != null) { try { frascatiService.remove(compositeToRemove); } catch (FraSCAtiServiceException e) { logger.error("Failed to stop and remove application " + app.name, e); } } } } private void handleContribution(FraSCAtiAppDescriptor app) { File appJar = new File(app.jarPath).getAbsoluteFile(); try { URL[] appClasspath = filesToUrls(appJar, new File(app.libsPath).listFiles()); logger.info("Loading app " + app.name); String newCompositeName = frascatiService.processComposite(app.compositeName, FraSCAtiServiceItf.all, null, appClasspath).getName(); compositeInstances.put(app, newCompositeName); logger.info("Successfuly started app " + app.name); } catch (FraSCAtiServiceException e) { logger.error("Failed to load app " + app.name + " (composite " + app.compositeName + " from jar '" + appJar.getAbsolutePath() + "')", e); } catch (MalformedURLException e) { logger.error("Invalid app Jar location", e); } } private URL[] filesToUrls(File jarFile, File[] libFiles) throws MalformedURLException { List<URL> urls = new LinkedList<URL>(); urls.add(jarFile.toURI().toURL()); for (File libFile : libFiles) { if (libFile.getName().endsWith(".jar")) { urls.add(libFile.toURI().toURL()); } }; return urls.toArray(new URL[0]); } }