package org.gcube.application.geoportal.service.engine.providers; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.caches.AbstractScopedMap; import org.gcube.application.cms.plugins.InitializablePlugin; import org.gcube.application.cms.plugins.LifecycleManager; import org.gcube.application.cms.plugins.Plugin; import org.gcube.application.cms.plugins.PluginManagerInterface; import org.gcube.application.cms.plugins.faults.InitializationException; import org.gcube.application.cms.plugins.faults.ShutDownException; import org.gcube.application.cms.plugins.reports.InitializationReport; import org.gcube.application.geoportal.common.utils.ContextUtils; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.reflections.Reflections; import org.reflections.util.ConfigurationBuilder; import org.reflections.util.FilterBuilder; import java.util.HashMap; import java.util.Map; @Slf4j public class PluginManager extends AbstractScopedMap> implements PluginManagerInterface { Map implementations=new HashMap<>(); public PluginManager(){ super("Plugin Cache"); // reflections Reflections reflections = new Reflections( new ConfigurationBuilder() .forPackage("org.gcube.application.cms") .filterInputsBy(new FilterBuilder().includePackage("org.gcube.application.cms"))); reflections.getSubTypesOf(Plugin.class).iterator().forEachRemaining(pluginClass->{ if(!pluginClass.isInterface()){ try { Plugin plugin = pluginClass.newInstance(); log.debug("Loading {} descriptiorn : ", plugin, plugin.getDescriptor()); implementations.put(plugin.getDescriptor().getId(), plugin); if(plugin instanceof LifecycleManager) ((LifecycleManager)plugin).setPluginManager(this); }catch (Throwable t){ log.warn("Unable to instantiate Plugin "+pluginClass,t); } } }); log.info("Loaded {} plugins",implementations.keySet().size()); // Init plugins implementations.forEach((id,p)->{ if(p instanceof InitializablePlugin){ log.info("INIT Plugin {}",id); try { InitializablePlugin ip=(InitializablePlugin) p; logReport(ip,ip.init()); }catch (InitializationException e){ log.error("Failed to initialize "+id,e); }catch(Throwable t){ log.error("Unable to initialize "+id,t); } } }); } @Override protected Map retrieveObject() throws ConfigurationException { // Init plugins implementations.forEach((id,p)->{ if(p instanceof InitializablePlugin){ log.info("INIT Plugin {} in context {} ",id, ContextUtils.getCurrentScope()); try { InitializablePlugin ip=(InitializablePlugin) p; logReport(ip,ip.initInContext()); }catch (InitializationException e){ log.error("Failed to initialize "+id,e); }catch(Throwable t){ log.error("Unable to initialize "+id,t); } } }); return implementations; } @Override protected void dispose(Map toDispose) { // ShutDown plugins implementations.forEach((id,p)->{ if(p instanceof InitializablePlugin){ log.info("Shutting down Plugin {}",id); try { InitializablePlugin ip=(InitializablePlugin) p; ip.shutdown(); }catch (ShutDownException e){ log.error("Failed to shutdown "+id,e); }catch(Throwable t){ log.error("Unable to shutdown "+id,t); } } }); } @Override public void init() { } @Override public Plugin getById(String pluginID) throws ConfigurationException { return getObject().get(pluginID); } private static final void logReport(Plugin p, InitializationReport report){ switch(report.getStatus()){ case ERROR: { log.error("Plugin [{}] STATUS : {}, INFO {} ",p.getDescriptor().getId(),report.getStatus(),report.getMessages()); break; } case WARNING: { log.warn("Plugin [{}] STATUS : {}, INFO {} ",p.getDescriptor().getId(),report.getStatus(),report.getMessages()); break; } default :{ log.info("Plugin [{}] STATUS : {}, INFO {} ",p.getDescriptor().getId(),report.getStatus(),report.getMessages()); } } } }