Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java Tue Dec 2 15:38:38 2014 @@ -13,8 +13,10 @@ */ package org.apache.aries.subsystem.core.internal; +import org.apache.aries.subsystem.ContentHandler; import org.apache.aries.subsystem.core.archive.DeployedContentHeader; import org.apache.aries.subsystem.core.archive.DeploymentManifest; +import org.osgi.framework.ServiceReference; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Resource; import org.osgi.service.coordinator.Coordination; @@ -27,28 +29,32 @@ public abstract class ResourceInstaller String type = ResourceHelper.getTypeAttribute(resource); if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) - || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) + || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) { return new SubsystemResourceInstaller(coordination, resource, subsystem); - else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) + } else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) { return new BundleResourceInstaller(coordination, resource, subsystem); - else if (Constants.ResourceTypeSynthesized.equals(type)) { + } else if (Constants.ResourceTypeSynthesized.equals(type)) { return new ResourceInstaller(coordination, resource, subsystem) { - @Override public Resource install() throws Exception { // do nothing; return resource; } }; + } else { + ServiceReference<ContentHandler> handlerRef = CustomResources.getCustomContentHandler(subsystem, type); + if (handlerRef != null) + return new CustomResourceInstaller(coordination, resource, type, subsystem, handlerRef); + } - throw new SubsystemException("No installer exists for resource type: " + type); + throw new SubsystemException("No installer exists for resource type: " + type); } - - protected final Coordination coordination; + + protected final Coordination coordination; protected final BasicSubsystem provisionTo; protected final Resource resource; protected final BasicSubsystem subsystem; - + public ResourceInstaller(Coordination coordination, Resource resource, BasicSubsystem subsystem) { this.coordination = coordination; this.resource = resource; @@ -62,9 +68,9 @@ public abstract class ResourceInstaller else provisionTo = subsystem; } - + public abstract Resource install() throws Exception; - + protected void addConstituent(final Resource resource) { // Don't let a resource become a constituent of itself. if (provisionTo == null || resource.equals(provisionTo)) @@ -82,7 +88,7 @@ public abstract class ResourceInstaller } }); } - + protected void addReference(final Resource resource) { // Don't let a resource reference itself. if (resource.equals(subsystem)) @@ -106,19 +112,19 @@ public abstract class ResourceInstaller }); } } - + protected String getLocation() { return provisionTo.getLocation() + "!/" + ResourceHelper.getLocation(resource); } - + protected boolean isContent() { return Utils.isContent(subsystem, resource); } - + protected boolean isDependency() { return Utils.isDependency(subsystem, resource); } - + protected boolean isReferencedProvisionTo() { DeploymentManifest manifest = subsystem.getDeploymentManifest(); if (manifest != null) { @@ -130,7 +136,7 @@ public abstract class ResourceInstaller return isReferencedSubsystem(); return false; } - + protected boolean isReferencedSubsystem() { DeploymentManifest manifest = subsystem.getDeploymentManifest(); if (manifest != null) {
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java Tue Dec 2 15:38:38 2014 @@ -13,7 +13,9 @@ */ package org.apache.aries.subsystem.core.internal; +import org.apache.aries.subsystem.ContentHandler; import org.apache.aries.subsystem.core.archive.ProvisionResourceHeader; +import org.osgi.framework.ServiceReference; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.framework.wiring.BundleRevision; import org.osgi.resource.Resource; @@ -24,31 +26,37 @@ import org.slf4j.LoggerFactory; public abstract class ResourceUninstaller { private static final Logger logger = LoggerFactory.getLogger(ResourceUninstaller.class); - + public static ResourceUninstaller newInstance(Resource resource, BasicSubsystem subsystem) { String type = ResourceHelper.getTypeAttribute(resource); if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) - || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) + || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) { return new SubsystemResourceUninstaller(resource, subsystem); - else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) + } else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) { return new BundleResourceUninstaller(resource, subsystem); - else - throw new SubsystemException("No uninstaller exists for resource type: " + type); + } else { + ServiceReference<ContentHandler> handlerRef = CustomResources.getCustomContentHandler(subsystem, type); + if (handlerRef != null) { + return new CustomResourceUninstaller(resource, type, subsystem, handlerRef); + } else { + throw new SubsystemException("No uninstaller exists for resource type: " + type); + } + } } - + protected static void removeConstituent(BasicSubsystem subsystem, Resource resource) { Activator.getInstance().getSubsystems().removeConstituent(subsystem, resource); } - + protected static void removeReference(BasicSubsystem subsystem, Resource resource) { Activator.getInstance().getSubsystems().removeReference(subsystem, resource); } - + protected final BasicSubsystem provisionTo; protected final Resource resource; protected final BasicSubsystem subsystem; - + public ResourceUninstaller(Resource resource, BasicSubsystem subsystem) { if (resource == null) throw new NullPointerException("Missing required parameter: resource"); @@ -61,9 +69,9 @@ public abstract class ResourceUninstalle else provisionTo = subsystem; } - + public abstract void uninstall(); - + protected boolean isExplicit() { // The operation is explicit if it was requested by a user, in which // case the resource and subsystem are the same. @@ -80,14 +88,14 @@ public abstract class ResourceUninstalle } return false; } - + protected boolean isTransitive() { ProvisionResourceHeader header = subsystem.getDeploymentManifest().getProvisionResourceHeader(); if (header == null) return false; return header.contains(resource); } - + protected boolean isResourceUninstallable() { int referenceCount = Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource).size(); if (referenceCount == 0) @@ -98,11 +106,11 @@ public abstract class ResourceUninstalle } return false; } - + protected void removeConstituent() { removeConstituent(subsystem, resource); } - + protected void removeReference() { removeReference(subsystem, resource); } Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java Tue Dec 2 15:38:38 2014 @@ -22,6 +22,7 @@ import java.util.EnumSet; import java.util.List; import java.util.Map.Entry; +import org.apache.aries.subsystem.ContentHandler; import org.apache.aries.subsystem.core.archive.ExportPackageCapability; import org.apache.aries.subsystem.core.archive.ExportPackageHeader; import org.apache.aries.subsystem.core.archive.ProvideCapabilityCapability; @@ -35,6 +36,7 @@ import org.eclipse.equinox.region.Region import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.framework.startlevel.BundleStartLevel; import org.osgi.framework.startlevel.FrameworkStartLevel; @@ -54,20 +56,20 @@ import org.slf4j.LoggerFactory; public class StartAction extends AbstractAction { private static final Logger logger = LoggerFactory.getLogger(StartAction.class); - + private final Coordination coordination; private final BasicSubsystem instigator; - + public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target) { this(instigator, requestor, target, null); } - + public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Coordination coordination) { super(requestor, target, false); this.instigator = instigator; this.coordination = coordination; } - + @Override public Object run() { State state = target.getState(); @@ -119,7 +121,7 @@ public class StartAction extends Abstrac // region and transition to INSTALLED. } finally { try { - // Don't end the coordination if the subsystem being started + // Don't end the coordination if the subsystem being started // (i.e. the target) did not begin it. if (coordination.getName().equals(Utils.computeCoordinationName(target))) coordination.end(); @@ -133,7 +135,7 @@ public class StartAction extends Abstrac } return null; } - + private static Collection<Bundle> getBundles(BasicSubsystem subsystem) { Collection<Resource> constituents = Activator.getInstance().getSubsystems().getConstituents(subsystem); ArrayList<Bundle> result = new ArrayList<Bundle>(constituents.size()); @@ -144,7 +146,7 @@ public class StartAction extends Abstrac result.trimToSize(); return result; } - + private static void resolve(BasicSubsystem subsystem) { // Don't propagate a RESOLVING event if this is a persisted subsystem // that is already RESOLVED. @@ -158,7 +160,7 @@ public class StartAction extends Abstrac if (!subsystem.isRoot()) { for (Subsystem child : Activator.getInstance().getSubsystems().getChildren(subsystem)) resolve((BasicSubsystem)child); - + FrameworkWiring frameworkWiring = Activator.getInstance().getBundleContext().getBundle(0) .adapt(FrameworkWiring.class); @@ -193,7 +195,7 @@ public class StartAction extends Abstrac throw new SubsystemException(t); } } - + private static void setExportIsolationPolicy(BasicSubsystem subsystem) throws InvalidSyntaxException, IOException, BundleException, URISyntaxException, ResolutionException { if (!subsystem.isComposite()) return; @@ -211,7 +213,7 @@ public class StartAction extends Abstrac + ", to=" + to + ", filter=" + regionFilter); from.connectRegion(to, regionFilter); } - + private static void setExportIsolationPolicy(RegionFilterBuilder builder, ExportPackageHeader header, BasicSubsystem subsystem) throws InvalidSyntaxException { if (header == null) return; @@ -226,7 +228,7 @@ public class StartAction extends Abstrac builder.allow(policy, filter.toString()); } } - + private static void setExportIsolationPolicy(RegionFilterBuilder builder, ProvideCapabilityHeader header, BasicSubsystem subsystem) throws InvalidSyntaxException { if (header == null) return; @@ -255,7 +257,7 @@ public class StartAction extends Abstrac builder.allow(policy, filter.toString()); } } - + private void startBundleResource(Resource resource, Coordination coordination) throws BundleException { if (target.isRoot()) // Starting the root subsystem should not affect bundles within the @@ -265,11 +267,11 @@ public class StartAction extends Abstrac // The region context bundle was persistently started elsewhere. return; final Bundle bundle = ((BundleRevision)resource).getBundle(); - + if ((bundle.getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0) return; - - if (logger.isDebugEnabled()) { + + if (logger.isDebugEnabled()) { int bundleStartLevel = bundle.adapt(BundleStartLevel.class).getStartLevel(); Bundle systemBundle=Activator.getInstance().getBundleContext().getBundle(0); int fwStartLevel = systemBundle.adapt(FrameworkStartLevel.class).getStartLevel(); @@ -278,43 +280,60 @@ public class StartAction extends Abstrac + " bundleStartLevel=" + bundleStartLevel + " frameworkStartLevel=" + fwStartLevel); } - + bundle.start(Bundle.START_TRANSIENT | Bundle.START_ACTIVATION_POLICY); - - if (logger.isDebugEnabled()) { + + if (logger.isDebugEnabled()) { logger.debug("StartAction: bundle " + bundle.getSymbolicName() + " " + bundle.getVersion().toString() + " started correctly"); } - + if (coordination == null) return; coordination.addParticipant(new Participant() { public void ended(Coordination coordination) throws Exception { // noop } - + public void failed(Coordination coordination) throws Exception { bundle.stop(); } }); } - + private void startResource(Resource resource, Coordination coordination) throws BundleException, IOException { String type = ResourceHelper.getTypeAttribute(resource); if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) - || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) + || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) { startSubsystemResource(resource, coordination); - else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) + } else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) { startBundleResource(resource, coordination); - else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) { + } else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) { // Fragments are not started. + } else { + if (!startCustomHandler(resource, type, coordination)) + throw new SubsystemException("Unsupported resource type: " + type); } - else - throw new SubsystemException("Unsupported resource type: " + type); } + private boolean startCustomHandler(Resource resource, String type, Coordination coordination) { + ServiceReference<ContentHandler> customHandlerRef = CustomResources.getCustomContentHandler(target, type); + if (customHandlerRef != null) { + ContentHandler customHandler = target.getBundleContext().getService(customHandlerRef); + if (customHandler != null) { + try { + customHandler.start(ResourceHelper.getSymbolicNameAttribute(resource), type, target, coordination); + return true; + } finally { + target.getBundleContext().ungetService(customHandlerRef); + } + } + } + return false; + } + private void startSubsystemResource(Resource resource, Coordination coordination) throws IOException { final BasicSubsystem subsystem = (BasicSubsystem)resource; // Subsystems that are content resources of another subsystem must have @@ -328,7 +347,7 @@ public class StartAction extends Abstrac public void ended(Coordination coordination) throws Exception { // noop } - + public void failed(Coordination coordination) throws Exception { new StopAction(target, subsystem, !subsystem.isRoot()).run(); } Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java Tue Dec 2 15:38:38 2014 @@ -19,9 +19,11 @@ import java.util.Collections; import java.util.EnumSet; import java.util.List; +import org.apache.aries.subsystem.ContentHandler; import org.apache.aries.subsystem.core.archive.DeploymentManifest; import org.apache.aries.subsystem.core.archive.SubsystemContentHeader; import org.osgi.framework.BundleException; +import org.osgi.framework.ServiceReference; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.framework.wiring.BundleRevision; import org.osgi.resource.Resource; @@ -33,11 +35,11 @@ import org.slf4j.LoggerFactory; public class StopAction extends AbstractAction { private static final Logger logger = LoggerFactory.getLogger(StopAction.class); - + public StopAction(BasicSubsystem requestor, BasicSubsystem target, boolean disableRootCheck) { super(requestor, target, disableRootCheck); } - + @Override public Object run() { checkRoot(); @@ -63,7 +65,7 @@ public class StopAction extends Abstract continue; try { stopResource(resource); - } + } catch (Exception e) { logger.error("An error occurred while stopping resource " + resource + " of subsystem " + target, e); } @@ -88,29 +90,47 @@ public class StopAction extends Abstract } return null; } - + private void stopBundleResource(Resource resource) throws BundleException { if (target.isRoot()) return; ((BundleRevision)resource).getBundle().stop(); } - + private void stopResource(Resource resource) throws BundleException, IOException { if (Utils.getActiveUseCount(resource) > 0) return; String type = ResourceHelper.getTypeAttribute(resource); if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) - || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) + || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) { stopSubsystemResource(resource); - else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) + } else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) { stopBundleResource(resource); - else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) + } else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) { return; - else - throw new SubsystemException("Unsupported resource type: " + type); + } else { + if (!stopCustomHandler(resource, type)) + throw new SubsystemException("Unsupported resource type: " + type); + } } - + + private boolean stopCustomHandler(Resource resource, String type) { + ServiceReference<ContentHandler> customHandlerRef = CustomResources.getCustomContentHandler(target, type); + if (customHandlerRef != null) { + ContentHandler customHandler = target.getBundleContext().getService(customHandlerRef); + if (customHandler != null) { + try { + customHandler.stop(ResourceHelper.getSymbolicNameAttribute(resource), type, target); + return true; + } finally { + target.getBundleContext().ungetService(customHandlerRef); + } + } + } + return false; + } + private void stopSubsystemResource(Resource resource) throws IOException { new StopAction(target, (BasicSubsystem)resource, !((BasicSubsystem)resource).isRoot()).run(); } Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java Tue Dec 2 15:38:38 2014 @@ -74,7 +74,7 @@ import org.osgi.service.subsystem.Subsys public class SubsystemResource implements Resource { private Region region; - + private final List<Capability> capabilities; private final DeploymentManifest deploymentManifest; private final Collection<Resource> installableContent = new HashSet<Resource>(); @@ -87,11 +87,11 @@ public class SubsystemResource implement private final RawSubsystemResource resource; private final Collection<Resource> sharedContent = new HashSet<Resource>(); private final Collection<Resource> sharedDependencies = new HashSet<Resource>(); - + public SubsystemResource(String location, IDirectory content, BasicSubsystem parent) throws URISyntaxException, IOException, ResolutionException, BundleException, InvalidSyntaxException { - this(new RawSubsystemResource(location, content), parent); + this(new RawSubsystemResource(location, content, parent), parent); } - + public SubsystemResource(RawSubsystemResource resource, BasicSubsystem parent) throws IOException, BundleException, InvalidSyntaxException, URISyntaxException { this.parent = parent; this.resource = resource; @@ -101,21 +101,21 @@ public class SubsystemResource implement computeDependencies(resource.getDeploymentManifest()); deploymentManifest = computeDeploymentManifest(); } - + public SubsystemResource(File file) throws IOException, URISyntaxException, ResolutionException, BundleException, InvalidSyntaxException { this(FileSystem.getFSRoot(file)); } - + public SubsystemResource(IDirectory directory) throws IOException, URISyntaxException, ResolutionException, BundleException, InvalidSyntaxException { parent = null; - resource = new RawSubsystemResource(directory); + resource = new RawSubsystemResource(directory, parent); preferredProviderRepository = null; deploymentManifest = resource.getDeploymentManifest(); computeContentResources(deploymentManifest); capabilities = computeCapabilities(); computeDependencies(deploymentManifest); } - + @Override public boolean equals(Object o) { if (o == this) @@ -130,7 +130,7 @@ public class SubsystemResource implement public List<Capability> getCapabilities(String namespace) { return Collections.unmodifiableList(capabilities); } - + private List<Capability> computeCapabilities() throws InvalidSyntaxException { List<Capability> capabilities = new ArrayList<Capability>(); if (isScoped()) @@ -139,18 +139,18 @@ public class SubsystemResource implement computeUnscopedCapabilities(capabilities); return capabilities; } - + private void computeUnscopedCapabilities(List<Capability> capabilities) { capabilities.addAll(resource.getCapabilities(null)); for (Resource r : getContentResources()) capabilities.addAll(r.getCapabilities(null)); } - + private void computeScopedCapabilities(List<Capability> capabilities) throws InvalidSyntaxException { capabilities.addAll(resource.getCapabilities(null)); computeOsgiServiceCapabilities(capabilities); } - + private void computeOsgiServiceCapabilities(List<Capability> capabilities) throws InvalidSyntaxException { SubsystemExportServiceHeader header = getSubsystemManifest().getSubsystemExportServiceHeader(); if (header == null) @@ -158,35 +158,35 @@ public class SubsystemResource implement for (Resource resource : getContentResources()) capabilities.addAll(header.toCapabilities(resource)); } - + public DeploymentManifest getDeploymentManifest() { return deploymentManifest; } - + public long getId() { return resource.getId(); } - + public Collection<Resource> getInstallableContent() { return installableContent; } - + public Collection<Resource> getInstallableDependencies() { return installableDependencies; } - + public Repository getLocalRepository() { return resource.getLocalRepository(); } - + public String getLocation() { return resource.getLocation().getValue(); } - + public Collection<DeployedContentHeader.Clause> getMissingResources() { return missingResources; } - + public Collection<BasicSubsystem> getParents() { if (parent == null) { Header<?> header = getDeploymentManifest().getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_PARENTS); @@ -200,7 +200,7 @@ public class SubsystemResource implement } return Collections.singleton(parent); } - + public synchronized Region getRegion() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (region == null) { region = createRegion(getId()); @@ -235,30 +235,30 @@ public class SubsystemResource implement return result; } } - + public Collection<Resource> getResources() { return resource.getResources(); } - + public Collection<Resource> getSharedContent() { return sharedContent; } - + public Collection<Resource> getSharedDependencies() { return sharedDependencies; } - + public SubsystemManifest getSubsystemManifest() { return resource.getSubsystemManifest(); } - + @Override public int hashCode() { int result = 17; result = 31 * result + getLocation().hashCode(); return result; } - + private void addContentResource(Resource resource) { if (resource == null) return; @@ -271,7 +271,7 @@ public class SubsystemResource implement else sharedContent.add(resource); } - + private boolean addDependencies(Repository repository, Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (repository == null) return false; @@ -283,32 +283,32 @@ public class SubsystemResource implement } return !capabilities.isEmpty(); } - + private boolean addDependenciesFromContentRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { // TODO Why create this with each method call? What not cache it as an instance variable? Repository repository = new ContentRepository(installableContent, sharedContent); return addDependencies(repository, requirement, capabilities); } - + private boolean addDependenciesFromLocalRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { Repository repository = resource.getLocalRepository(); return addDependencies(repository, requirement, capabilities); } - + private boolean addDependenciesFromPreferredProviderRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { return addDependencies(preferredProviderRepository, requirement, capabilities); } - + private boolean addDependenciesFromRepositoryServiceRepositories(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { Repository repository = new RepositoryServiceRepository(); return addDependencies(repository, requirement, capabilities); } - + private boolean addDependenciesFromSystemRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { Repository repository = Activator.getInstance().getSystemRepository(); return addDependencies(repository, requirement, capabilities); } - + private void addDependency(Resource resource) { if (resource == null) return; @@ -317,17 +317,17 @@ public class SubsystemResource implement else sharedDependencies.add(resource); } - + private void addMissingResource(DeployedContentHeader.Clause resource) { missingResources.add(resource); } - + private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { for (Capability c : from) if (isValid(c, requirement)) to.add(c); } - + private void addSubsystemServiceImportToSharingPolicy( RegionFilterBuilder builder) throws InvalidSyntaxException, BundleException, IOException, URISyntaxException { builder.allow( @@ -340,7 +340,7 @@ public class SubsystemResource implement .append('=').append(getRegion().getName()) .append("))").toString()); } - + private void addSubsystemServiceImportToSharingPolicy(RegionFilterBuilder builder, Region to) throws InvalidSyntaxException, BundleException, IOException, URISyntaxException { Region root = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion(); @@ -354,7 +354,7 @@ public class SubsystemResource implement getRegion().connectRegion(to, regionFilter); } } - + private void computeContentResources(DeploymentManifest manifest) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (manifest == null) computeContentResources(getSubsystemManifest()); @@ -371,7 +371,7 @@ public class SubsystemResource implement } } } - + private void computeContentResources(SubsystemManifest manifest) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader(); if (contentHeader == null) @@ -387,7 +387,7 @@ public class SubsystemResource implement addContentResource(resource); } } - + private void computeDependencies(DeploymentManifest manifest) { if (manifest == null) computeDependencies(getSubsystemManifest()); @@ -401,9 +401,9 @@ public class SubsystemResource implement throw new SubsystemException("A required dependency could not be found. This means the resource was either missing or not recognized as a supported resource format due to, for example, an invalid bundle manifest or blueprint XML file. Turn on debug logging for more information. The resource was: " + resource); addDependency(resource); } - } + } } - + private void computeDependencies(SubsystemManifest manifest) { SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader(); try { @@ -425,14 +425,14 @@ public class SubsystemResource implement throw new SubsystemException(e); } } - + private DeployedContentHeader computeDeployedContentHeader() { Collection<Resource> content = getContentResources(); if (content.isEmpty()) return null; return DeployedContentHeader.newInstance(content); } - + private DeploymentManifest computeDeploymentManifest() throws IOException { DeploymentManifest result = computeExistingDeploymentManifest(); if (result != null) @@ -442,18 +442,18 @@ public class SubsystemResource implement .header(computeProvisionResourceHeader()).build(); return result; } - + private DeploymentManifest computeExistingDeploymentManifest() throws IOException { return resource.getDeploymentManifest(); } - + private ProvisionResourceHeader computeProvisionResourceHeader() { Collection<Resource> dependencies = getDepedencies(); if (dependencies.isEmpty()) return null; return ProvisionResourceHeader.newInstance(dependencies); } - + private Region createRegion(long id) throws BundleException { if (!isScoped()) return getParents().iterator().next().getRegion(); @@ -478,11 +478,11 @@ public class SubsystemResource implement return digraph.createRegion(name); return region; } - + private ResolveContext createResolveContext() { return new ResolveContext() { private final Map<Resource, Wiring> wirings = computeWirings(); - + private Map<Resource, Wiring> computeWirings() { Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>(); for (BasicSubsystem subsystem : Activator.getInstance().getSubsystems().getSubsystems()) @@ -490,7 +490,7 @@ public class SubsystemResource implement addWiring(constituent, wirings); return Collections.unmodifiableMap(wirings); } - + private void addWiring(Resource resource, Map<Resource, Wiring> wirings) { if (resource instanceof BundleConstituent) { BundleConstituent bc = (BundleConstituent)resource; @@ -501,13 +501,13 @@ public class SubsystemResource implement wirings.put(br, br.getWiring()); } } - + @Override public List<Capability> findProviders(Requirement requirement) { List<Capability> result = new ArrayList<Capability>(); try { // Only check the system repository for osgi.ee and osgi.native - if (ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(requirement.getNamespace()) + if (ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(requirement.getNamespace()) || DependencyCalculator.NATIVE_NAMESPACE.equals(requirement.getNamespace())) { addDependenciesFromSystemRepository(requirement, result); return result; @@ -532,12 +532,12 @@ public class SubsystemResource implement } return result; } - + @Override public Collection<Resource> getMandatoryResources() { return SubsystemResource.this.mandatoryResources; } - + @Override public Collection<Resource> getOptionalResources() { return SubsystemResource.this.optionalResources; @@ -561,7 +561,7 @@ public class SubsystemResource implement } }; } - + private Resource findContent(Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { Map<Requirement, Collection<Capability>> map; // TODO System repository for scoped subsystems should be searched in @@ -596,7 +596,7 @@ public class SubsystemResource implement return capabilities.iterator().next().getResource(); return null; } - + private Resource findContent(DeployedContentHeader.Clause clause) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { Attribute attribute = clause.getAttribute(DeployedContentHeader.Clause.ATTRIBUTE_RESOURCEID); long resourceId = attribute == null ? -1 : Long.parseLong(String.valueOf(attribute.getValue())); @@ -613,7 +613,7 @@ public class SubsystemResource implement } return findContent(clause.toRequirement(this)); } - + private Resource findDependency(ProvisionResourceHeader.Clause clause) { Attribute attribute = clause.getAttribute(DeployedContentHeader.Clause.ATTRIBUTE_RESOURCEID); long resourceId = attribute == null ? -1 : Long.parseLong(String.valueOf(attribute.getValue())); @@ -632,54 +632,54 @@ public class SubsystemResource implement return null; return capabilities.get(0).getResource(); } - + private Collection<Resource> getContentResources() { Collection<Resource> result = new ArrayList<Resource>(installableContent.size() + sharedContent.size()); result.addAll(installableContent); result.addAll(sharedContent); return result; } - + private Collection<Resource> getDepedencies() { Collection<Resource> result = new ArrayList<Resource>(installableDependencies.size() + sharedDependencies.size()); result.addAll(installableDependencies); result.addAll(sharedDependencies); return result; } - + private boolean isContent(Resource resource) { return getSubsystemManifest().getSubsystemContentHeader().contains(resource); } - + private boolean isInstallable(Resource resource) { return !isShared(resource); } - + private boolean isMandatory(Resource resource) { SubsystemContentHeader header = this.resource.getSubsystemManifest().getSubsystemContentHeader(); if (header == null) return false; return header.isMandatory(resource); } - + private boolean isRoot() { return BasicSubsystem.ROOT_LOCATION.equals(getLocation()); } - + private boolean isShared(Resource resource) { return Utils.isSharedResource(resource); } - + private boolean isScoped() { String type = resource.getSubsystemManifest().getSubsystemTypeHeader().getType(); return SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type); } - + private boolean isUnscoped() { return !isScoped(); } - + private boolean isValid(Capability capability, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getNamespace())) return true; @@ -687,7 +687,7 @@ public class SubsystemResource implement Region to = findRegionForCapabilityValidation(requirement.getResource()); return new SharingPolicyValidator(from, to).isValid(capability); } - + private Region findRegionForCapabilityValidation(Resource resource) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (isInstallable(resource)) { if (isContent(resource)) @@ -707,14 +707,14 @@ public class SubsystemResource implement return Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource).iterator().next().getRegion(); } } - + private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { if (isRoot() || !isScoped()) return; Region region = getRegion(); Region from = region; RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder(); - Region to = ((BasicSubsystem)getParents().iterator().next()).getRegion(); + Region to = getParents().iterator().next().getRegion(); addSubsystemServiceImportToSharingPolicy(builder, to); // TODO Is this check really necessary? Looks like it was done at the beginning of this method. if (isScoped()) { @@ -739,15 +739,15 @@ public class SubsystemResource implement RegionFilter regionFilter = builder.build(); from.connectRegion(to, regionFilter); } - + private void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException { String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE; - // work around https://www.osgi.org/bugzilla/show_bug.cgi?id=144 - // In the first instance, what if the various weaving services were to have a property, - // osgi.woven.packages, that was a comma separated list of packages that might be woven - // by that hook. + // work around https://www.osgi.org/bugzilla/show_bug.cgi?id=144 + // In the first instance, what if the various weaving services were to have a property, + // osgi.woven.packages, that was a comma separated list of packages that might be woven + // by that hook. Collection<String> wovenPackages = getWovenPackages(); - for (String pkg : wovenPackages) { + for (String pkg : wovenPackages) { builder.allow(policy, "(osgi.wiring.package=" + pkg + ")"); } if (header == null) @@ -758,23 +758,23 @@ public class SubsystemResource implement builder.allow(policy, filter); } } - - // First pass at this: really just a sketch. + + // First pass at this: really just a sketch. private Collection<String> getWovenPackages() throws InvalidSyntaxException { // Find all weaving services in our region BundleContext bc = Activator.getInstance().getBundleContext(); Collection<ServiceReference<WeavingHook>> weavers = bc.getServiceReferences(WeavingHook.class, null); Collection<String> wovenPackages = new ArrayList<String>(); - for (ServiceReference<WeavingHook> sr : weavers) { + for (ServiceReference<WeavingHook> sr : weavers) { String someWovenPackages = (String) sr.getProperty("osgi.woven.packages"); - if (someWovenPackages != null) { + if (someWovenPackages != null) { wovenPackages.addAll(ManifestHeaderProcessor.split(someWovenPackages, ",")); } } return wovenPackages; } - + private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException { if (header == null) return; @@ -785,7 +785,7 @@ public class SubsystemResource implement builder.allow(policy, filter); } } - + private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException { if (header == null) return; @@ -802,7 +802,7 @@ public class SubsystemResource implement builder.allow(policy, filter); } } - + private void setImplicitAccessToNativeAndEECapabilities(RegionFilterBuilder builder) { builder.allowAll(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE); Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java (original) +++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java Tue Dec 2 15:38:38 2014 @@ -29,7 +29,7 @@ public class SubsystemResourceInstaller public SubsystemResourceInstaller(Coordination coordination, Resource resource, BasicSubsystem subsystem) { super(coordination, resource, subsystem); } - + public Resource install() throws Exception { BasicSubsystem result; if (resource instanceof RepositoryContent) @@ -42,7 +42,7 @@ public class SubsystemResourceInstaller result = installSubsystemResource((SubsystemResource)resource); return result; } - + private void addChild(final BasicSubsystem child) { // provisionTo will be null if the resource is an already installed // dependency. @@ -64,7 +64,7 @@ public class SubsystemResourceInstaller } }); } - + private void addSubsystem(final BasicSubsystem subsystem) { Activator.getInstance().getSubsystems().addSubsystem(subsystem); coordination.addParticipant(new Participant() { @@ -72,14 +72,14 @@ public class SubsystemResourceInstaller public void ended(Coordination arg0) throws Exception { // Nothing } - + @Override public void failed(Coordination arg0) throws Exception { Activator.getInstance().getSubsystems().removeSubsystem(subsystem); } }); } - + private BasicSubsystem installAriesSubsystem(BasicSubsystem subsystem) throws Exception { addChild(subsystem); addReference(subsystem); @@ -124,12 +124,12 @@ public class SubsystemResourceInstaller Activator.getInstance().getSubsystemServiceRegistrar().register(subsystem, this.subsystem); return subsystem; } - + private BasicSubsystem installRawSubsystemResource(RawSubsystemResource resource) throws Exception { SubsystemResource subsystemResource = new SubsystemResource(resource, provisionTo); return installSubsystemResource(subsystemResource); } - + private void installRegionContextBundle(final BasicSubsystem subsystem) throws Exception { if (!subsystem.isScoped()) return; @@ -146,12 +146,12 @@ public class SubsystemResourceInstaller } }); } - + private BasicSubsystem installRepositoryContent(RepositoryContent resource) throws Exception { - RawSubsystemResource rawSubsystemResource = new RawSubsystemResource(getLocation(), FileSystem.getFSRoot(resource.getContent())); + RawSubsystemResource rawSubsystemResource = new RawSubsystemResource(getLocation(), FileSystem.getFSRoot(resource.getContent()), subsystem); return installRawSubsystemResource(rawSubsystemResource); } - + private BasicSubsystem installSubsystemResource(SubsystemResource resource) throws Exception { BasicSubsystem subsystem = new BasicSubsystem(resource); installAriesSubsystem(subsystem); Modified: aries/trunk/subsystem/subsystem-itests/pom.xml URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/pom.xml?rev=1642910&r1=1642909&r2=1642910&view=diff ============================================================================== --- aries/trunk/subsystem/subsystem-itests/pom.xml (original) +++ aries/trunk/subsystem/subsystem-itests/pom.xml Tue Dec 2 15:38:38 2014 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.subsystem</groupId> <artifactId>org.apache.aries.subsystem.itests</artifactId> - <version>1.0.0-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> <name>Apache Aries Subsystem iTests</name> <description> Integration tests using the subsystem api, core for the implementation @@ -129,7 +129,7 @@ <groupId>org.apache.aries.subsystem</groupId> <artifactId>org.apache.aries.subsystem.api</artifactId> <scope>test</scope> - <version>1.0.1-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.osgi</groupId> @@ -141,7 +141,7 @@ <groupId>org.apache.aries.subsystem</groupId> <artifactId>org.apache.aries.subsystem.core</artifactId> <scope>test</scope> - <version>1.1.1-SNAPSHOT</version> + <version>1.2.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.osgi</groupId> @@ -181,7 +181,7 @@ <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.configadmin</artifactId> <scope>test</scope> - <version>1.2.8</version> + <version>1.8.0</version> <exclusions> <exclusion> <groupId>org.osgi</groupId> @@ -489,6 +489,85 @@ </execution> <execution> + <id>cm-content-bundleZ</id> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF</manifestFile> + </archive> + <classesDirectory>${project.build.directory}/test-classes</classesDirectory> + <includes> + <include>org/apache/aries/subsystem/itests/cmcontent/impl/**</include> + </includes> + <outputDirectory>${project.build.directory}/test-classes/cmContent</outputDirectory> + <finalName>cmContentBundleZ</finalName> + </configuration> + <phase>process-test-classes</phase> + </execution> + + <execution> + <id>custom-content-bundleA</id> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF</manifestFile> + </archive> + <outputDirectory>${project.build.directory}/test-classes/customContent</outputDirectory> + <finalName>customContentBundleA</finalName> + </configuration> + <phase>process-test-classes</phase> + </execution> + + <execution> + <id>custom-content-bundleB</id> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF</manifestFile> + </archive> + <outputDirectory>${project.build.directory}/test-classes/customContent1</outputDirectory> + <finalName>customContentBundleB</finalName> + </configuration> + <phase>process-test-classes</phase> + </execution> + + <execution> + <id>custom-content-bundleC</id> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF</manifestFile> + </archive> + <outputDirectory>${project.build.directory}/test-classes/customContent2</outputDirectory> + <finalName>customContentBundleC</finalName> + </configuration> + <phase>process-test-classes</phase> + </execution> + + <execution> + <id>custom-content-bundleD</id> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF</manifestFile> + </archive> + <outputDirectory>${project.build.directory}/test-classes/customContent3</outputDirectory> + <finalName>customContentBundleD</finalName> + </configuration> + <phase>process-test-classes</phase> + </execution> + + <execution> <id>dynamic-import-impl</id> <goals> <goal>jar</goal> @@ -581,6 +660,19 @@ </execution> <execution> + <id>add-source-cmContentBundleZ</id> + <phase>generate-sources</phase> + <goals> + <goal>add-test-source</goal> + </goals> + <configuration> + <sources> + <source>src/test/bundles/cmContentBundleZ</source> + </sources> + </configuration> + </execution> + + <execution> <id>add-source-dynamicImport</id> <phase>generate-sources</phase> <goals> Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF Tue Dec 2 15:38:38 2014 @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: CM Content Test Bundle +Bundle-SymbolicName: org.apache.aries.subsystem.itests.cmcontent.impl +Bundle-Version: 1.0.0 +Import-Package: org.osgi.framework, org.osgi.service.cm +Bundle-Activator: org.apache.aries.subsystem.itests.cmcontent.impl.Activator + Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java Tue Dec 2 15:38:38 2014 @@ -0,0 +1,26 @@ +package org.apache.aries.subsystem.itests.cmcontent.impl; + +import java.util.Dictionary; +import java.util.Hashtable; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ManagedService; + +public class Activator implements BundleActivator { + @Override + public void start(BundleContext context) throws Exception { + Dictionary<String, Object> blahProps = new Hashtable<String, Object>(); + blahProps.put(Constants.SERVICE_PID, "com.blah.Blah"); + context.registerService(ManagedService.class, new BlahManagedService(context), blahProps); + + Dictionary<String, Object> barProps = new Hashtable<String, Object>(); + barProps.put(Constants.SERVICE_PID, "org.foo.Bar"); + context.registerService(ManagedService.class, new BarManagedService(context), barProps); + } + + @Override + public void stop(BundleContext context) throws Exception { + } +} Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java Tue Dec 2 15:38:38 2014 @@ -0,0 +1,26 @@ +package org.apache.aries.subsystem.itests.cmcontent.impl; + +import java.util.Dictionary; +import java.util.Hashtable; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; + +public class BarManagedService implements ManagedService { + private final BundleContext bundleContext; + + public BarManagedService(BundleContext context) { + bundleContext = context; + } + + @Override + public void updated(Dictionary<String, ?> p) throws ConfigurationException { + if ("test".equals(p.get("configVal"))) { + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put("test.pid", p.get(Constants.SERVICE_PID)); + bundleContext.registerService(String.class, "Bar!", props); + } + } +} Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java Tue Dec 2 15:38:38 2014 @@ -0,0 +1,27 @@ +package org.apache.aries.subsystem.itests.cmcontent.impl; + +import java.util.Dictionary; +import java.util.Hashtable; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; + +public class BlahManagedService implements ManagedService { + private final BundleContext bundleContext; + + public BlahManagedService(BundleContext context) { + bundleContext = context; + } + + @Override + public void updated(Dictionary<String, ?> p) throws ConfigurationException { + if ("test2".equals(p.get("configVal")) && + "test123".equals(p.get("configVal2"))) { + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put("test.pid", p.get(Constants.SERVICE_PID)); + bundleContext.registerService(String.class, "Blah!", props); + } + } +} Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF Tue Dec 2 15:38:38 2014 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleA +Bundle-Version: 1.0.0 + Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF Tue Dec 2 15:38:38 2014 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleB +Bundle-Version: 1.0.0 + Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF Tue Dec 2 15:38:38 2014 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleC +Bundle-Version: 1.0.0 + Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF Tue Dec 2 15:38:38 2014 @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleD +Bundle-Version: 1.0.0 + Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java Tue Dec 2 15:38:38 2014 @@ -0,0 +1,79 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.aries.subsystem.itests; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.osgi.framework.Filter; +import org.osgi.service.subsystem.Subsystem; +import org.osgi.util.tracker.ServiceTracker; + +public class ConfigAdminPropsFileContentHandlerTest extends SubsystemTest { + public ConfigAdminPropsFileContentHandlerTest() { + installConfigAdmin = true; + } + + @Override + protected void createApplications() throws Exception { + createApplication("cmContent", "org.foo.Bar.cfg", "com.blah.Blah.cfg", + "cmContentBundleZ.jar"); + } + + @Test + public void testConfigurationContentHandler() throws Exception { + // This test works as follows: it first installs a subsystem (cmContent.esa) + // that contains two configuration files (org.foo.Bar.cfg and com.blah.Blah.cfg) + // These configuration files are marked as 'osgi.config' content type. + // The ConfigAdminContentHandler handles the installation of this content + // and registers them as configuration with the Config Admin Service. + // The .esa file also contains an ordinary bundle that registers two + // Config Admin ManagedServices. Each registerd under one of the PIDs. + // Once they receive the expected configuration they each register a String + // service to mark that they have. + // After starting the subsystem this test waits for these 'String' services + // to appear so that it knows that the whole process worked. + + Subsystem subsystem = installSubsystemFromFile("cmContent.esa"); + subsystem.start(); + + // Now check that both Managed Services (Config Admin services) have been configured + // If they are configured correctly they will register a marker String service to + // indicate this. + + Filter f = bundleContext.createFilter( + "(&(objectClass=java.lang.String)(test.pid=org.foo.Bar))"); + ServiceTracker<String, String> barTracker = + new ServiceTracker<String, String>(bundleContext, f, null); + try { + barTracker.open(); + String blahSvc = barTracker.waitForService(2000); + assertEquals("Bar!", blahSvc); + } finally { + barTracker.close(); + } + + Filter f2 = bundleContext.createFilter( + "(&(objectClass=java.lang.String)(test.pid=com.blah.Blah))"); + ServiceTracker<String, String> blahTracker = + new ServiceTracker<String, String>(bundleContext, f2, null); + try { + blahTracker.open(); + String blahSvc = blahTracker.waitForService(2000); + assertEquals("Blah!", blahSvc); + } finally { + blahTracker.close(); + } + } +} Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java?rev=1642910&view=auto ============================================================================== --- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java (added) +++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java Tue Dec 2 15:38:38 2014 @@ -0,0 +1,347 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.aries.subsystem.itests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.Scanner; + +import org.apache.aries.subsystem.ContentHandler; +import org.junit.Ignore; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceRegistration; +import org.osgi.framework.namespace.IdentityNamespace; +import org.osgi.resource.Capability; +import org.osgi.resource.Resource; +import org.osgi.service.coordinator.Coordination; +import org.osgi.service.subsystem.Subsystem; + +public class CustomContentHandlerTest extends SubsystemTest { + + @Override + protected void createApplications() throws Exception { + createApplication("customContent", "custom1.sausages", "customContentBundleA.jar"); + createApplication("customContent1", "custom2.sausages", "customContentBundleB.jar"); + createApplication("customContent2", "custom3.sausages", "customContentBundleC.jar"); + createApplication("customContent3", "custom4.sausages", "customContentBundleD.jar"); + } + + @Test + public void testCustomContentHandler() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + try { + assertEquals("Precondition", 0, handler.calls.size()); + Subsystem subsystem = installSubsystemFromFile("customContent.esa"); + try { + assertEquals(Arrays.asList("install:customContent1 sausages = 1"), handler.calls); + + Collection<Resource> constituents = subsystem.getConstituents(); + assertEquals("The custom content should not show up as a subsystem constituent", + 1, constituents.size()); + + boolean foundBundle = false; + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) { + foundBundle = true; + } + } + assertTrue(foundBundle); + + boolean foundBundleInConstituents = false; + for (Resource c : constituents) { + for(Capability idCap : c.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE)) { + Object name = idCap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE); + if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(name)) + foundBundleInConstituents = true; + } + } + assertTrue(foundBundleInConstituents); + + handler.calls.clear(); + assertEquals(Subsystem.State.INSTALLED, subsystem.getState()); + + subsystem.start(); + assertEquals(Arrays.asList("start:customContent1"), handler.calls); + + handler.calls.clear(); + assertEquals(Subsystem.State.ACTIVE, subsystem.getState()); + + subsystem.stop(); + assertEquals(Arrays.asList("stop:customContent1"), handler.calls); + + assertEquals(Subsystem.State.RESOLVED, subsystem.getState()); + } finally { + handler.calls.clear(); + subsystem.uninstall(); + assertEquals(Arrays.asList("uninstall:customContent1"), handler.calls); + assertEquals(Subsystem.State.UNINSTALLED, subsystem.getState()); + } + } finally { + reg.unregister(); + } + } + + @Test + public void testCustomContentInstallationException() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(true, "install"); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + assertEquals("Precondition", 0, handler.calls.size()); + + try { + installSubsystemFromFile("customContent1.esa"); + } catch (Exception ex) { + // ignore + } + try { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { + fail("Should not have installed the bundle"); + } + } + } finally { + reg.unregister(); + } + } + + @Test @Ignore("This test exposes a problem that needs to be fixed, namely that the previous test leaves stuff behind and that " + + "customContent1.esa cannot be installed again. Currently ignored until someone finds the time to fix it.") + public void testCustomContentInstallationSecondTime() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + try { + Subsystem subsystem = installSubsystemFromFile("customContent1.esa"); + subsystem.uninstall(); + } finally { + reg.unregister(); + } + } + + @Test + public void testCustomContentInstallationCoordinationFails() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(false, "install"); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + assertEquals("Precondition", 0, handler.calls.size()); + + try { + installSubsystemFromFile("customContent2.esa"); + } catch (Exception ex) { + // ignore + } + try { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { + fail("Should not have installed the bundle"); + } + } + } finally { + reg.unregister(); + } + } + + + + @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't") + public void testCustomContentStartException() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(true, "start"); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + assertEquals("Precondition", 0, handler.calls.size()); + Subsystem subsystem = installSubsystemFromFile("customContent2.esa"); + + try { + assertEquals(Arrays.asList("install:customContent3 sausages = 3"), handler.calls); + + try { + Bundle theBundle = null; + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { + assertEquals(Bundle.INSTALLED, b.getState()); + theBundle = b; + } + } + assertNotNull(theBundle); + + try { + subsystem.start(); + } catch (Exception ex) { + // good + } + assertEquals("There was an exception during start, so the bundle should not be started", + Bundle.INSTALLED, theBundle.getState()); + } finally { + subsystem.uninstall(); + } + } finally { + reg.unregister(); + } + } + + @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't") + public void testCustomContentStartFailCoordination() throws Exception { + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) { + fail("Precondition"); + } + } + + SausagesContentHandler handler = new SausagesContentHandler(false, "start"); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); + ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); + + assertEquals("Precondition", 0, handler.calls.size()); + Subsystem subsystem = installSubsystemFromFile("customContent3.esa"); + + try { + assertEquals(Arrays.asList("install:customContent4 sausages = 4"), handler.calls); + + try { + Bundle theBundle = null; + for (Bundle b : bundleContext.getBundles()) { + if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) { + assertEquals(Bundle.INSTALLED, b.getState()); + theBundle = b; + } + } + assertNotNull(theBundle); + + try { + subsystem.start(); + } catch (Exception ex) { + // good + } + assertEquals("The coordination failued during start, so the bundle should not be started", + Bundle.INSTALLED, theBundle.getState()); + } finally { + subsystem.uninstall(); + } + } finally { + reg.unregister(); + } + } + + private static String convertStreamToString(InputStream is) { + Scanner s = new Scanner(is).useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } + + static class SausagesContentHandler implements ContentHandler { + List<String> calls = new ArrayList<String>(); + private final boolean exception; + private final String state; + + public SausagesContentHandler() { + this(false, null); + } + + public SausagesContentHandler(boolean exception, String state) { + this.exception = exception; + this.state = state; + } + + @Override + public void install(InputStream is, String symbolicName, String type, Subsystem subsystem, + Coordination coordination) { + if ("install".equals(state)) { + if (exception) { + throw new RuntimeException(state); + } else { + coordination.fail(new RuntimeException(state)); + } + } + + String content = convertStreamToString(is); + calls.add(("install:" + symbolicName + " " + content).trim()); + } + + @Override + public void start(String symbolicName, String type, Subsystem subsystem, Coordination coordination) { + if ("start".equals(state)) { + if (exception) { + throw new RuntimeException(state); + } else { + coordination.fail(new RuntimeException(state)); + } + } + + calls.add("start:" + symbolicName); + } + + @Override + public void stop(String symbolicName, String type, Subsystem subsystem) { + calls.add("stop:" + symbolicName); + } + + @Override + public void uninstall(String symbolicName, String type, Subsystem subsystem) { + calls.add("uninstall:" + symbolicName); + } + } +}
