package streamflow.engine.wrapper; import backtype.storm.task.TopologyContext; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import java.io.Serializable; import java.util.ArrayList; import streamflow.engine.framework.FrameworkException; import streamflow.engine.framework.FrameworkModule; import streamflow.engine.resource.ResourceModule; import streamflow.model.Topology; import streamflow.model.TopologyComponent; import streamflow.model.TopologyResourceEntry; import streamflow.model.config.StreamflowConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import streamflow.engine.framework.FrameworkUtils; public abstract class BaseWrapper<T> implements Serializable { private static final Logger LOG = LoggerFactory.getLogger(BaseWrapper.class); protected transient T delegate; protected Class<T> typeClass; protected Topology topology; protected TopologyComponent component; protected TopologyContext context; protected boolean isCluster; protected StreamflowConfig configuration; public BaseWrapper() { } public BaseWrapper(Topology topology, TopologyComponent component, boolean isCluster, StreamflowConfig configuration, Class<T> typeClass) throws FrameworkException { this.topology = topology; this.component = component; this.isCluster = isCluster; this.configuration = configuration; this.typeClass = typeClass; } protected T getDelegate() throws FrameworkException { if (delegate == null) { try { // Load the delegate class from the framework jar in an isolated class loader delegate = FrameworkUtils.getInstance().loadFrameworkClassInstance( component.getFrameworkHash(), component.getMainClass(), typeClass, topology.getClassLoaderPolicy()); injectModules(); } catch (Exception ex) { LOG.error("Unable to load component class: Class = " + component.getMainClass(), ex); throw new FrameworkException("Unable to load component class: " + component.getMainClass() + ", Exception = " + ex.getMessage()); } } return delegate; } private void injectModules() throws FrameworkException { // Create the new FrameworkModule to inject proxy and property information FrameworkModule frameworkModule = new FrameworkModule( topology, component, configuration, context); // Create the resource module which will inject resource properties ResourceModule resourceModule = new ResourceModule( topology, component.getResources()); // Create the Guice injector and use it to inject the modules Injector injector = Guice.createInjector( (Module) frameworkModule, (Module) resourceModule); ArrayList<Module> resourceModules = new ArrayList<>(); for (TopologyResourceEntry resourceEntry : component.getResources()) { // Load the framework class instance from the framework Class resourceClass = FrameworkUtils.getInstance().loadFrameworkClass( resourceEntry.getFrameworkHash(), resourceEntry.getResourceClass(), topology.getClassLoaderPolicy()); // Create an instance of each resource module save it for injection resourceModules.add((Module) injector.getInstance(resourceClass)); } // Create a child injector with all of the bound resource module implementations injector = injector.createChildInjector(resourceModules); // Finally inject the delegate object with all of the resource bound settings injector.injectMembers(delegate); } }