You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by li...@apache.org on 2010/04/09 22:42:33 UTC
svn commit: r932594 - in
/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal:
SubsystemAdminImpl.java SubsystemImpl.java SubsystemResourceProcessor.java
Author: linsun
Date: Fri Apr 9 20:42:33 2010
New Revision: 932594
URL: http://svn.apache.org/viewvc?rev=932594&view=rev
Log:
emit subsystem events for install/update/uninstall, add a bit more checking in subsystem manifest header and calculate composite manifest header
Modified:
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java
incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java
Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java?rev=932594&r1=932593&r2=932594&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java Fri Apr 9 20:42:33 2010
@@ -15,6 +15,7 @@ package org.apache.aries.subsystem.core.
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -24,6 +25,7 @@ import java.util.Map;
import org.apache.aries.subsystem.Subsystem;
import org.apache.aries.subsystem.SubsystemAdmin;
import org.apache.aries.subsystem.SubsystemConstants;
+import org.apache.aries.subsystem.SubsystemEvent;
import org.apache.aries.subsystem.SubsystemException;
import org.apache.aries.subsystem.SubsystemListener;
import org.apache.aries.subsystem.spi.Resource;
@@ -76,6 +78,7 @@ public class SubsystemAdminImpl implemen
public void dispose() {
compositeAdminTracker.close();
resourceResolverTracker.close();
+ listenersTracker.close();
}
public void bundleChanged(BundleEvent event) {
@@ -120,7 +123,7 @@ public class SubsystemAdminImpl implemen
String bsn = (String) bundle.getHeaders().get(Constants.BUNDLE_SYMBOLICNAME);
Clause[] bsnClauses = Parser.parseHeader(bsn);
if ("true".equals(bsnClauses[0].getDirective(SubsystemConstants.SUBSYSTEM_DIRECTIVE))) {
- return new SubsystemImpl(this, (CompositeBundle) bundle);
+ return new SubsystemImpl(this, (CompositeBundle) bundle, eventDispatcher);
}
}
return null;
@@ -198,29 +201,50 @@ public class SubsystemAdminImpl implemen
}
// let's get the one we just installed
- toReturn = getInstalledSubsytem(url);
- if (toReturn != null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Installing subsystem url {} is successful", url);
+ if (success) {
+ toReturn = getInstalledSubsytem(url);
+ if (toReturn != null) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Installing subsystem url {} is successful", url);
+ }
+
+ // emit the subsystem event
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.INSTALLED, System.currentTimeMillis(), toReturn));
+
+ return toReturn;
}
- return toReturn;
}
throw new IllegalStateException();
}
- public void update(Subsystem subsystem) {
+ public void update(Subsystem subsystem) throws SubsystemException {
update(subsystem, null);
}
- public void update(final Subsystem subsystem, final InputStream is) {
+ public void update(final Subsystem subsystem, final InputStream is) throws SubsystemException {
+ if (subsystem.getState().equals(Subsystem.State.UNINSTALLED)) {
+ throw new IllegalStateException("Unable to update subsystem as subsystem is already uninstalled");
+ }
+
+ if (subsystem.getState().equals(Subsystem.State.ACTIVE)
+ || subsystem.getState().equals(Subsystem.State.STARTING)
+ || subsystem.getState().equals(Subsystem.State.STOPPING)) {
+ subsystem.stop();
+ }
+
Resource subsystemResource = new ResourceImpl(subsystem.getSymbolicName(), subsystem.getVersion(), SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, subsystem.getLocation(), Collections.<String, String>emptyMap()) {
@Override
public InputStream open() throws IOException {
if (is != null) {
return is;
}
- // TODO: check update location first
+ // subsystem-updatelocation specified the manifest has higher priority than subsystem original location
+ String subsystemLoc = subsystem.getHeaders().get(SubsystemConstants.SUBSYSTEM_UPDATELOCATION);
+ if (subsystemLoc != null && subsystemLoc.length() > 0) {
+ // we have a subsystem location let us use it
+ return new URL(subsystemLoc).openStream();
+ }
return super.open();
}
};
@@ -232,6 +256,13 @@ public class SubsystemAdminImpl implemen
session.prepare();
session.commit();
success = true;
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Updating subsystem {} is successful", subsystem.getSymbolicName());
+ }
+
+ // emit the subsystem event
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.UPDATED, System.currentTimeMillis(), subsystem));
+
} finally {
if (!success) {
session.rollback();
@@ -240,6 +271,10 @@ public class SubsystemAdminImpl implemen
}
public void uninstall(Subsystem subsystem) {
+ if (subsystem.getState().equals(Subsystem.State.UNINSTALLED)) {
+ throw new IllegalStateException("Unable to uninstall subsystem as subsystem is already uninstalled");
+ }
+
Resource subsystemResource = new ResourceImpl(subsystem.getSymbolicName(), subsystem.getVersion(), SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, subsystem.getLocation(), Collections.<String, String>emptyMap());
SubsystemResourceProcessor processor = new SubsystemResourceProcessor();
SubsystemResourceProcessor.SubsystemSession session = processor.createSession(context);
@@ -249,6 +284,13 @@ public class SubsystemAdminImpl implemen
session.prepare();
session.commit();
success = true;
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Uninstalling subsystem {} is successful", subsystem.getSymbolicName());
+ }
+
+ // emit the subsystem event
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.UNINSTALLED, System.currentTimeMillis(), subsystem));
+
} finally {
if (!success) {
session.rollback();
Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java?rev=932594&r1=932593&r2=932594&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java Fri Apr 9 20:42:33 2010
@@ -16,6 +16,7 @@ package org.apache.aries.subsystem.core.
import java.util.*;
import org.apache.aries.subsystem.Subsystem;
+import org.apache.aries.subsystem.SubsystemEvent;
import org.apache.aries.subsystem.SubsystemException;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
@@ -27,11 +28,13 @@ public class SubsystemImpl implements Su
final long id;
final SubsystemAdminImpl admin;
final CompositeBundle composite;
+ final SubsystemEventDispatcher eventDispatcher;
- public SubsystemImpl(SubsystemAdminImpl admin, CompositeBundle composite) {
+ public SubsystemImpl(SubsystemAdminImpl admin, CompositeBundle composite, SubsystemEventDispatcher eventDispatcher) {
this.admin = admin;
this.composite = composite;
this.id = composite.getBundleId();
+ this.eventDispatcher = eventDispatcher;
}
public State getState() {
@@ -55,7 +58,9 @@ public class SubsystemImpl implements Su
public void start() throws SubsystemException {
try {
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.STARTING, System.currentTimeMillis(), this));
composite.start();
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.STARTED, System.currentTimeMillis(), this));
} catch (BundleException e) {
throw new SubsystemException("Unable to start subsystem", e);
}
@@ -63,7 +68,9 @@ public class SubsystemImpl implements Su
public void stop() throws SubsystemException {
try {
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.STOPPING, System.currentTimeMillis(), this));
composite.stop();
+ eventDispatcher.subsystemEvent(new SubsystemEvent(SubsystemEvent.Type.STOPPED, System.currentTimeMillis(), this));
} catch (BundleException e) {
throw new SubsystemException("Unable to stop subsystem", e);
}
Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java?rev=932594&r1=932593&r2=932594&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java Fri Apr 9 20:42:33 2010
@@ -25,7 +25,6 @@ import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
-import org.apache.aries.subsystem.Subsystem;
import org.apache.aries.subsystem.SubsystemAdmin;
import org.apache.aries.subsystem.SubsystemConstants;
import org.apache.aries.subsystem.SubsystemException;
@@ -43,6 +42,7 @@ import org.osgi.framework.InvalidSyntaxE
import org.osgi.framework.Version;
import org.osgi.service.composite.CompositeAdmin;
import org.osgi.service.composite.CompositeBundle;
+import org.osgi.service.composite.CompositeConstants;
import org.osgi.util.tracker.ServiceTracker;
import static org.apache.aries.subsystem.core.internal.FileUtils.closeQuietly;
@@ -119,57 +119,24 @@ public class SubsystemResourceProcessor
List<Resource> additional = resolver.resolve(content, resource);
- // Check subsystem manifest required headers
- String mfv = manifest.getMainAttributes().getValue(SUBSYSTEM_MANIFESTVERSION);
- if (mfv == null || mfv.length() == 0) {
- throw new SubsystemException("Invalid subsystem manifest version: " + mfv);
- }
- try {
- Version v = Version.parseVersion(mfv);
- if (!SUBSYSTEM_MANIFEST_VERSION.equals(v)) {
- throw new SubsystemException("Unsupported subsystem manifest version: " + mfv);
- }
- } catch (IllegalArgumentException e) {
- throw new SubsystemException("Invalid subsystem manifest version: " + mfv, e);
- }
+ // check manifest header to see if they are valid
String ssn = manifest.getMainAttributes().getValue(SUBSYSTEM_SYMBOLICNAME);
- if (ssn == null || ssn.length() == 0) {
- throw new SubsystemException("Invalid subsystem symbolic name: " + ssn);
- }
- // TODO: check attributes / directives on the subsystem symbolic name ?
String sv = manifest.getMainAttributes().getValue(SUBSYSTEM_VERSION);
- if (sv == null || sv.length() == 0) {
- throw new SubsystemException("Invalid subsystem version: " + sv);
- }
- try {
- new Version(sv);
- } catch (IllegalArgumentException e) {
- throw new SubsystemException("Invalid subsystem version: " + sv, e);
- }
- // Grab all headers
- Map<String, String> headers = new HashMap<String, String>();
- Iterator it = manifest.getMainAttributes().entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry e = (Map.Entry) it.next();
- String name = e.getKey().toString();
- String value = e.getValue().toString();
- headers.put(name, value);
- }
- // Create the required composite headers
- headers.put(BUNDLE_SYMBOLICNAME, ssn + ";" + COMPOSITE_DIRECTIVE + ":=true;" + SUBSYSTEM_DIRECTIVE + ":=true");
- headers.put(BUNDLE_VERSION, sv);
- // TODO: compute other composite manifest entries
- // TODO: compute list of bundles
+ checkManifestHeaders(manifest, ssn, sv);
+
+ Map<String, String> headers = computeCompositeHeaders(manifest, ssn, sv);
// Check existing bundles
CompositeBundle composite = findSubsystemComposite(res);
if (composite == null) {
+ // brand new install
composite = admin.installCompositeBundle(
res.getLocation(),
headers,
Collections.<String, String>emptyMap());
installed.put(res, composite);
} else {
+ // update
String previousContentHeader = (String) composite.getHeaders().get(SUBSYSTEM_CONTENT);
Clause[] previousContentClauses = Parser.parseHeader(previousContentHeader);
for (Clause c : previousContentClauses) {
@@ -341,5 +308,103 @@ public class SubsystemResourceProcessor
trackers.clear();
}
}
+
+ private static void checkManifestHeaders(Manifest manifest, String ssn, String sv) {
+ // Check subsystem manifest required headers
+ String mfv = manifest.getMainAttributes().getValue(SUBSYSTEM_MANIFESTVERSION);
+ if (mfv == null || mfv.length() == 0) {
+ throw new SubsystemException("Invalid subsystem manifest version: " + mfv);
+ }
+ try {
+ Version v = Version.parseVersion(mfv);
+ if (!SUBSYSTEM_MANIFEST_VERSION.equals(v)) {
+ throw new SubsystemException("Unsupported subsystem manifest version: " + mfv + ". Supported "
+ + SubsystemConstants.SUBSYSTEM_MANIFESTVERSION + " is " + SUBSYSTEM_MANIFEST_VERSION);
+ }
+ } catch (IllegalArgumentException e) {
+ throw new SubsystemException("Invalid subsystem manifest version: " + mfv, e);
+ }
+
+ if (ssn == null || ssn.length() == 0) {
+ throw new SubsystemException("Invalid subsystem symbolic name: " + ssn);
+ }
+ // check attributes / directives on the subsystem symbolic name
+ // TODO add any other symbolic name to check
+ Clause[] ssnClauses = Parser.parseHeader(ssn);
+ String ssDirective = ssnClauses[0].getDirective(SUBSYSTEM_DIRECTIVE);
+ String comDirective = ssnClauses[0].getDirective(COMPOSITE_DIRECTIVE);
+ if (ssDirective != null && ssDirective.equalsIgnoreCase("false")) {
+ throw new SubsystemException("Invalid " + SUBSYSTEM_DIRECTIVE + " directive in " + SUBSYSTEM_SYMBOLICNAME + ": " + ssDirective);
+ }
+
+ if (ssDirective != null && comDirective.equalsIgnoreCase("false")) {
+ throw new SubsystemException("Invalid " + COMPOSITE_DIRECTIVE + " directive in " + SUBSYSTEM_SYMBOLICNAME + ": " + comDirective);
+ }
+
+ if (sv == null || sv.length() == 0) {
+ throw new SubsystemException("Invalid subsystem version: " + sv);
+ }
+ try {
+ new Version(sv);
+ } catch (IllegalArgumentException e) {
+ throw new SubsystemException("Invalid subsystem version: " + sv, e);
+ }
+
+ // TODO: do we want to check other headers such as subsystem-importpackage, subsystem-exportpackage, etc.
+
+ }
+
+ // if the ssn already contains COMPOSITE_DIRECTIVE or SUBSYSTEM_DIRECTIVE directive
+ // let's not add them again
+ private static String getCompositeSymbolicName(String ssn) {
+ Clause[] ssnClauses = Parser.parseHeader(ssn);
+ String ssDirective = ssnClauses[0].getDirective(SUBSYSTEM_DIRECTIVE);
+ String comDirective = ssnClauses[0].getDirective(COMPOSITE_DIRECTIVE);
+
+ if (ssDirective == null && comDirective == null) {
+ ssn = ssn + ";" + COMPOSITE_DIRECTIVE + ":=true;" + SUBSYSTEM_DIRECTIVE + ":=true";
+ } else if (ssDirective == null) {
+ ssn = ssn + ";" + COMPOSITE_DIRECTIVE + ":=true;";
+ } else if (comDirective == null){
+ ssn = ssn + ";" + SUBSYSTEM_DIRECTIVE + ":=true;";
+ }
+
+ return ssn;
+ }
+
+ private static Map<String, String> computeCompositeHeaders(Manifest manifest, String ssn, String sv) {
+ // Grab all headers
+ Map<String, String> headers = new HashMap<String, String>();
+ Iterator it = manifest.getMainAttributes().entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ String name = e.getKey().toString();
+ String value = e.getValue().toString();
+ headers.put(name, value);
+ }
+
+ // Create the required composite headers
+ headers.put(BUNDLE_SYMBOLICNAME, getCompositeSymbolicName(ssn));
+ headers.put(BUNDLE_VERSION, sv);
+
+ String subImportPkg = headers.get(SUBSYSTEM_IMPORTPACKAGE);
+ String subExportPkg = headers.get(SUBSYSTEM_EXPORTPACKAGE);
+ if (subImportPkg != null && subImportPkg.length() > 0) {
+ // use subsystem-importpackage for composite-importpackage
+ headers.put(CompositeConstants.COMPOSITE_PACKAGE_IMPORT_POLICY, subImportPkg);
+ } else {
+ // TODO: let's compute the import package for the subsystem
+ }
+ if (subExportPkg != null && subExportPkg.length() > 0) {
+ // use subsystem-importpackage for composite-importpackage
+ headers.put(CompositeConstants.COMPOSITE_PACKAGE_EXPORT_POLICY, subExportPkg);
+ }
+
+ // TODO: compute other composite manifest entries
+ // TODO: compute list of bundles
+
+ return headers;
+ }
+
}
\ No newline at end of file