package org.mobicents.slee.container.deployment.jboss; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import javax.slee.ComponentID; import org.jboss.logging.Logger; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.EventTypeDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.EventTypeDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.LibraryDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.LibraryDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ProfileSpecificationDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ProfileSpecificationDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ResourceAdaptorDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ResourceAdaptorDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ResourceAdaptorTypeDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ResourceAdaptorTypeDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.SbbDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.SbbDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ServiceDescriptorFactory; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ServiceDescriptorImpl; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MResourceAdaptorEntityBinding; import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MResourceAdaptorTypeBinding; import org.mobicents.slee.container.management.jmx.editors.ComponentIDPropertyEditor; /** * This class represents a SLEE Deployable Component such as a Profile Specification, * Event Type Definition, RA Type, Resource Adaptor, SBB or Service. It also contains * the dependencies and the install/uninstall actions needed for that component. * * @author Alexandre Mendon�a * @version 1.0 */ public class DeployableComponent { // The logger. private static Logger logger = Logger.getLogger( DeployableComponent.class ); public final static int PROFILESPEC_COMPONENT = 1; public final static int EVENTTYPE_COMPONENT = 2; public final static int RATYPE_COMPONENT = 3; public final static int RA_COMPONENT = 4; public final static int SBB_COMPONENT = 5; public final static int SERVICE_COMPONENT = 6; public final static int LIBRARY_COMPONENT = 7; // The DeploymentInfo short name private String diShortName; // The DeploymentInfo URL object private URL diURL; // The ID of the component. private ComponentID componentID; // The dependencies for this Component. private Collection<String> dependencies = new ArrayList<String>(); // The actions needed to perform installation for this component. private Collection<Object[]> installActions = new ArrayList<Object[]>(); // The actions needed to perform installation for this component. private Collection<Object[]> uninstallActions = new ArrayList<Object[]>(); // The key identifying the component (type[name#vendor#version]). private String componentKey; // An indicator for the component type. private int componentType = -1; private DeployableUnitWrapper duWrapper; // The components inside this component private Collection<DeployableComponent> subComponents = new ArrayList<DeployableComponent>(); /** * Private constructor for the sub-components. * @param dc the base DeployableComponent * @throws Exception */ private DeployableComponent( DeployableComponent dc ) throws Exception { this.diShortName = dc.diShortName; this.diURL = dc.diURL; // We want no sub-sub-components... this.subComponents = null; } /** * Constructor. * @param di the DeploymentInfo for this component. * @throws Exception */ public DeployableComponent( URL url, String fileName ) throws Exception { this.diShortName = fileName; this.diURL = url; // Parse the component descriptor to obtain dependencies. this.subComponents = parseDescriptor(); } public DeployableComponent( DeployableUnitWrapper duWrapper, URL url, String fileName ) throws Exception { this.duWrapper = duWrapper; this.diShortName = fileName; this.diURL = url; // Parse the component descriptor to obtain dependencies. this.subComponents = parseDescriptor(); } /** * Getter for this component dependencies. * @return a Collection<String> with dependencies IDs. */ public Collection<String> getDependencies() { return this.dependencies; } /** * Method for checking if the component is deployable, ie, meets the pre-reqs. * @param deployedComponents a Collection<String> with the IDs of the already deployed components. * @return true if it can be deployed. */ public boolean isDeployable(Collection<String> deployedComponents) { return deployedComponents.containsAll( dependencies ); } /** * Getter for the Component Key String. * @return a String with the component key (type[name#vendor#version]). */ public String getComponentKey() { return this.componentKey; } /** * Parser for the deployment descriptor. Minimal version obtained from Container. * @return a String containing the Component ID. * @throws IOException */ private Collection<DeployableComponent> parseDescriptor() throws IOException { if( logger.isTraceEnabled() ) logger.trace( "Parsing Descriptor for " + this.diURL.toString() ); Collection<DeployableComponent> deployableComponents = new ArrayList<DeployableComponent>(); // Special case for the services... if( this.diShortName.endsWith( ".xml" ) ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Service Descriptor." ); InputStream is = null; try { is = diURL.openStream(); ServiceDescriptorFactory sdf = new ServiceDescriptorFactory(); List<ServiceDescriptorImpl> serviceDescriptors = sdf.parse( is ); for(ServiceDescriptorImpl sd : serviceDescriptors) { DeployableComponent dc = new DeployableComponent( this ); dc.componentType = SERVICE_COMPONENT; dc.componentID = sd.getServiceID(); dc.componentKey = getComponentIdAsString( dc.componentID ); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> serviceDependencies = sd.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : serviceDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) { logger.trace( "--------------------------- End of Dependencies --------------------------" ); } dc.installActions.add( new Object[] {"activate", dc.componentID} ); dc.uninstallActions.add( new Object[] {"deactivate", dc.componentID} ); deployableComponents.add( dc ); } return deployableComponents; } catch ( Exception e ) { logger.error( "", e ); return null; } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } try { URL descriptorXML = null; // Determine whether the type of this instance is an sbb, event, RA type, etc. if( ( descriptorXML = duWrapper.getEntry( "META-INF/sbb-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing SBB Descriptor." ); InputStream is = null; try { is = descriptorXML.openStream(); // Parse the descriptor using the factory SbbDescriptorFactory sbbdf = new SbbDescriptorFactory(); List<SbbDescriptorImpl> sbbDescriptors = sbbdf.parse( is ); if( sbbDescriptors.size() == 0 ) { logger.warn( "The " + duWrapper.getFileName() + " deployment descriptor contains no sbb definitions" ); return null; } for( SbbDescriptorImpl sbbDescriptor : sbbDescriptors) { DeployableComponent dc = new DeployableComponent( this ); dc.componentType = SBB_COMPONENT; // Get the Component ID dc.componentID = sbbDescriptor.getSbbID(); // Get the Component Key dc.componentKey = getComponentIdAsString( dc.componentID ); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> sbbDependencies = sbbDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : sbbDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) { logger.trace( getComponentIdAsString( dependencyId ) ); } } // FIXME: This is special case for Links. Maybe it should be treated in SbbDescriptorImpl? for(MResourceAdaptorTypeBinding raTypeBinding : sbbDescriptor.getResourceAdaptorTypeBindings()) { for(MResourceAdaptorEntityBinding raEntityBinding : raTypeBinding.getResourceAdaptorEntityBinding()) { String raLink = raEntityBinding.getResourceAdaptorEntityLink(); // Add the dependency dc.dependencies.add( raLink ); if( logger.isTraceEnabled() ) logger.trace( raLink ); } } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else if( ( descriptorXML = duWrapper.getEntry( "META-INF/profile-spec-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Profile Specification Descriptor." ); InputStream is = null; try { // Get the InputStream is = descriptorXML.openStream(); // Parse the descriptor using the factory ProfileSpecificationDescriptorFactory psdf = new ProfileSpecificationDescriptorFactory(); List<ProfileSpecificationDescriptorImpl> psDescriptors = psdf.parse( is ); // Get a list of the profile specifications in the deployable unit. if( psDescriptors.size() == 0 ) { logger.warn( "The " + duWrapper.getFileName() + " deployment descriptor contains no profile-spec definitions" ); return null; } // Iterate through the profile spec nodes for( ProfileSpecificationDescriptorImpl psDescriptor : psDescriptors ) { DeployableComponent dc = new DeployableComponent( this ); // Set Component Type dc.componentType = PROFILESPEC_COMPONENT; // Get the Component ID dc.componentID = psDescriptor.getProfileSpecificationID(); // Get the Component Key dc.componentKey = getComponentIdAsString(dc.componentID); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> psDependencies = psDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : psDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else if( ( descriptorXML = duWrapper.getEntry( "META-INF/event-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Event Definition Descriptor." ); InputStream is = null; try { // Get the InputStream is = descriptorXML.openStream(); // Parse the descriptor using the factory EventTypeDescriptorFactory etdf = new EventTypeDescriptorFactory(); List<EventTypeDescriptorImpl> etDescriptors = etdf.parse( is ); if( etDescriptors == null || etDescriptors.size() == 0 ) { logger.warn( "The " + duWrapper.getFileName() + " deployment descriptor contains no event-type definitions" ); return null; } for( EventTypeDescriptorImpl etDescriptor : etDescriptors ) { DeployableComponent dc = new DeployableComponent( this ); // Set Component Type dc.componentType = EVENTTYPE_COMPONENT; // Get the Component ID dc.componentID = etDescriptor.getEventTypeID(); // Get the Component Key // FIXME: Does the ComponentID still comes with the , ## ? dc.componentKey = dc.componentID.toString().substring( 0, dc.componentID.toString().indexOf( ',' ) ); dc.componentKey = getComponentIdAsString( dc.componentID ); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> etDependencies = etDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : etDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else if( ( descriptorXML = duWrapper.getEntry( "META-INF/resource-adaptor-type-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Resource Adaptor Type Descriptor." ); InputStream is = null; try { // Get the InputStream is = descriptorXML.openStream(); // Parse the descriptor using the factory ResourceAdaptorTypeDescriptorFactory ratdf = new ResourceAdaptorTypeDescriptorFactory(); List<ResourceAdaptorTypeDescriptorImpl> ratDescriptors = ratdf.parse( is ); if( ratDescriptors == null || ratDescriptors.size() == 0 ) { logger.warn( "The " + duWrapper.getFileName() + " deployment descriptor contains no resource-adaptor-type definitions" ); return null; } // Go through all the Resource Adaptor Type Elements for( ResourceAdaptorTypeDescriptorImpl ratDescriptor : ratDescriptors ) { DeployableComponent dc = new DeployableComponent( this ); // Set Component Type dc.componentType = RATYPE_COMPONENT; // Get the Component ID dc.componentID = ratDescriptor.getResourceAdaptorTypeID(); // Get the Component Key dc.componentKey = getComponentIdAsString(dc.componentID); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> ratDependencies = ratDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : ratDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else if( ( descriptorXML = duWrapper.getEntry( "META-INF/resource-adaptor-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Resource Adaptor Descriptor." ); InputStream is = null; try { // Get the InputStream is = descriptorXML.openStream(); // Parse the descriptor using the factory ResourceAdaptorDescriptorFactory radf = new ResourceAdaptorDescriptorFactory(); List<ResourceAdaptorDescriptorImpl> raDescriptors = radf.parse( is ); // Go through all the Resource Adaptor Elements for( ResourceAdaptorDescriptorImpl raDescriptor : raDescriptors ) { DeployableComponent dc = new DeployableComponent( this ); // Set Component Type dc.componentType = RA_COMPONENT; // Set the Component ID dc.componentID = raDescriptor.getResourceAdaptorID(); // Set the Component Key dc.componentKey = getComponentIdAsString(dc.componentID); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> raDependencies = raDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : raDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else if( ( descriptorXML = duWrapper.getEntry( "META-INF/library-jar.xml" ) ) != null ) { if( logger.isTraceEnabled() ) logger.trace( "Parsing Library Descriptor." ); InputStream is = null; try { // Get the InputStream is = descriptorXML.openStream(); // Parse the descriptor using the factory LibraryDescriptorFactory ldf = new LibraryDescriptorFactory(); List<LibraryDescriptorImpl> libraryDescriptors = ldf.parse( is ); // Go through all the Resource Adaptor Elements for( LibraryDescriptorImpl libraryDescriptor : libraryDescriptors ) { DeployableComponent dc = new DeployableComponent( this ); // Set Component Type dc.componentType = LIBRARY_COMPONENT; // Set the Component ID dc.componentID = libraryDescriptor.getLibraryID(); // Set the Component Key dc.componentKey = getComponentIdAsString(dc.componentID); if( logger.isTraceEnabled() ) { logger.trace( "Component ID: " + dc.componentKey ); logger.trace( "------------------------------ Dependencies ------------------------------" ); } // Get the set of this sbb dependencies Set<ComponentID> libraryDependencies = libraryDescriptor.getDependenciesSet(); // Iterate through dependencies set for( ComponentID dependencyId : libraryDependencies ) { // Add the dependency dc.dependencies.add( getComponentIdAsString( dependencyId ) ); if( logger.isTraceEnabled() ) logger.trace( getComponentIdAsString( dependencyId ) ); } if( logger.isTraceEnabled() ) logger.trace( "--------------------------- End of Dependencies --------------------------" ); deployableComponents.add( dc ); } } catch ( Exception e ) { logger.error( "", e ); } finally { // Clean up! if( is != null ) { try { is.close(); } finally { is = null; } } } } else { logger.warn( "\r\n--------------------------------------------------------------------------------\r\n" + "No Component Descriptor found in '" + duWrapper.getFileName() + "'.\r\n" + "--------------------------------------------------------------------------------"); return new ArrayList<DeployableComponent>(); } } finally { } return deployableComponents; } /** * Getter for Install Actions. * @return a Collection of Object[] with the actions needed to install this component. */ public Collection<Object[]> getInstallActions() { return installActions; } /** * Getter for Uninstall Actions. * @return a Collection of Object[] with the actions needed to uninstall this component. */ public Collection<Object[]> getUninstallActions() { return uninstallActions; } /** * Getter for component type. * @return an int identifying the component type. */ public int getComponentType() { return componentType; } /** * Getter for component id. * @return the ComponentID for the component. */ public ComponentID getComponentID() { return componentID; } /** * Getter for the sub components. * @return Collection of DeployableComponents */ public Collection<DeployableComponent> getSubComponents() { return this.subComponents; } /** * Perform extra verifications for undeployment. * @param du the containing Deployable Unit * @return true if the the component can be removed. */ public boolean isUndeployable(DeployableUnit du) { boolean result = false; switch( componentType ) { case PROFILESPEC_COMPONENT: result = true; break; case EVENTTYPE_COMPONENT: result = true; break; case RATYPE_COMPONENT: // FIXME: Check if this is still needed in SLEE 2.x //SleeContainer sC = SleeContainer.lookupFromJndi(); // Get the DU componennts //Collection<String> duComponents = du.getComponents(); // Obtaining the RAs using this RA Type //HashSet<ResourceAdaptorIDImpl> raIDs = sC.getResourceManagement().getResourceAdaptorType( (ResourceAdaptorTypeID) componentID ).getResourceAdaptorIDs(); // Check if the referring RAs are in the same DU //for( ResourceAdaptorIDImpl raID : raIDs ) // if( !duComponents.contains( raID.getAsText() ) ) // return false; // All aboard! Move on.. result = true; break; case RA_COMPONENT: result = true; break; case SBB_COMPONENT: result = true; break; case SERVICE_COMPONENT: result = true; break; case LIBRARY_COMPONENT: result = true; break; } return result; } private String getComponentIdAsString(ComponentID componentId) { ComponentIDPropertyEditor cidPropertyEditor = new ComponentIDPropertyEditor(); cidPropertyEditor.setValue( componentId ); return cidPropertyEditor.getAsText(); } }