Author: jwross
Date: Tue Apr 16 16:30:06 2013
New Revision: 1468495
URL: http://svn.apache.org/r1468495
Log:
Fix stale state written to deployment manifest.
There was a small window where a previous state could be written to a
deployment manifest due
to holding a stale copy of the deployment manifest. This included *ING states
so that subsequent
operations would end up waiting for a state change the would never occur.
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AbstractAction.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AbstractAction.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AbstractAction.java?rev=1468495&r1=1468494&r2=1468495&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AbstractAction.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AbstractAction.java
Tue Apr 16 16:30:06 2013
@@ -17,8 +17,12 @@ import java.security.PrivilegedAction;
import org.osgi.service.subsystem.Subsystem.State;
import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public abstract class AbstractAction implements PrivilegedAction<Object> {
+ private static final Logger logger =
LoggerFactory.getLogger(AbstractAction.class);
+
protected final boolean disableRootCheck;
protected final BasicSubsystem requestor;
protected final BasicSubsystem target;
@@ -43,13 +47,19 @@ public abstract class AbstractAction imp
protected void waitForStateChange(State fromState) {
long then = System.currentTimeMillis() + 60000;
synchronized (target) {
+ if (logger.isDebugEnabled())
+ logger.debug("Request to wait for state change
of subsystem {} from state {}", target.getSymbolicName(), target.getState());
while (target.getState().equals(fromState)) {
+ if (logger.isDebugEnabled())
+ logger.debug("{} equals {}",
target.getState(), fromState);
// State change has not occurred.
long now = System.currentTimeMillis();
if (then <= now)
// Wait time has expired.
throw new SubsystemException("Operation
timed out while waiting for the subsystem to change state from " + fromState);
try {
+ if (logger.isDebugEnabled())
+ logger.debug("Waiting for {}
ms", then - now);
// Wait will never be called with zero
or a negative
// argument due to previous check.
target.wait(then - now);
@@ -60,6 +70,8 @@ public abstract class AbstractAction imp
throw new SubsystemException(e);
}
}
+ if (logger.isDebugEnabled())
+ logger.debug("Done waiting for subsystem {} in
state {} to change from state {}", new Object[]{target.getSymbolicName(),
target.getState(), fromState});
}
}
}
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java?rev=1468495&r1=1468494&r2=1468495&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java
Tue Apr 16 16:30:06 2013
@@ -57,8 +57,12 @@ import org.osgi.service.resolver.Resolut
import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.SubsystemConstants;
import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class BasicSubsystem implements Resource, AriesSubsystem {
+ private static final Logger logger =
LoggerFactory.getLogger(BasicSubsystem.class);
+
public static final String ROOT_SYMBOLIC_NAME =
"org.osgi.service.subsystem.root";
public static final Version ROOT_VERSION =
Version.parseVersion("1.0.0");
public static final String ROOT_LOCATION = "subsystem://?"
@@ -310,8 +314,14 @@ public class BasicSubsystem implements R
void addedConstituent(Resource resource, boolean referenced) {
try {
- setDeploymentManifest(new DeploymentManifest.Builder()
-
.manifest(getDeploymentManifest()).content(resource, referenced).build());
+ if (logger.isDebugEnabled())
+ logger.debug("Adding constituent {} to
deployment manifest...", resource);
+ synchronized (this) {
+ setDeploymentManifest(new
DeploymentManifest.Builder()
+
.manifest(getDeploymentManifest()).content(resource, referenced).build());
+ }
+ if (logger.isDebugEnabled())
+ logger.debug("Added constituent {} to
deployment manifest", resource);
} catch (Exception e) {
throw new SubsystemException(e);
}
@@ -319,8 +329,14 @@ public class BasicSubsystem implements R
void addedParent(BasicSubsystem subsystem, boolean referenceCount) {
try {
- setDeploymentManifest(new DeploymentManifest.Builder()
-
.manifest(getDeploymentManifest()).parent(subsystem, referenceCount).build());
+ if (logger.isDebugEnabled())
+ logger.debug("Adding parent {} to deployment
manifest...", subsystem.getSymbolicName());
+ synchronized (this) {
+ setDeploymentManifest(new
DeploymentManifest.Builder()
+
.manifest(getDeploymentManifest()).parent(subsystem, referenceCount).build());
+ }
+ if (logger.isDebugEnabled())
+ logger.debug("Added parent {} to deployment
manifest", subsystem.getSymbolicName());
} catch (Exception e) {
throw new SubsystemException(e);
}
@@ -453,7 +469,7 @@ public class BasicSubsystem implements R
removedContent(Collections.singleton(clause));
}
- void removedContent(Collection<DeployedContentHeader.Clause> content) {
+ synchronized void
removedContent(Collection<DeployedContentHeader.Clause> content) {
DeploymentManifest manifest = getDeploymentManifest();
DeployedContentHeader header =
manifest.getDeployedContentHeader();
if (header == null)
@@ -481,8 +497,10 @@ public class BasicSubsystem implements R
void setAutostart(boolean value) {
try {
- setDeploymentManifest(new DeploymentManifest.Builder()
-
.manifest(getDeploymentManifest()).autostart(value).build());
+ synchronized (this) {
+ setDeploymentManifest(new
DeploymentManifest.Builder()
+
.manifest(getDeploymentManifest()).autostart(value).build());
+ }
} catch (Exception e) {
throw new SubsystemException(e);
}
@@ -491,6 +509,8 @@ public class BasicSubsystem implements R
synchronized void setDeploymentManifest(DeploymentManifest value)
throws IOException {
deploymentManifest = value;
Coordination coordination =
Activator.getInstance().getCoordinator().peek();
+ if (logger.isDebugEnabled())
+ logger.debug("Setting deployment manifest for subsystem
{} using coordination {}", getSymbolicName(), coordination == null ? null :
coordination.getName());
if (coordination == null) {
saveDeploymentManifest();
} else {
@@ -517,7 +537,11 @@ public class BasicSubsystem implements R
file.mkdirs();
BufferedOutputStream out = new BufferedOutputStream(new
FileOutputStream(new File(file, "DEPLOYMENT.MF")));
try {
+ if (logger.isDebugEnabled())
+ logger.debug("Writing deployment manifest for
subsystem {} in state {}", getSymbolicName(), getState());
deploymentManifest.write(out);
+ if (logger.isDebugEnabled())
+ logger.debug("Wrote deployment manifest for
subsystem {} in state {}", getSymbolicName(), getState());
}
finally {
IOUtils.close(out);
@@ -525,16 +549,28 @@ public class BasicSubsystem implements R
}
void setState(State value) {
- if (value.equals(getState()))
+ if (logger.isDebugEnabled())
+ logger.debug("Setting state of subsystem {} to {}",
getSymbolicName(), value);
+ State state = getState();
+ if (value.equals(state)) {
+ if (logger.isDebugEnabled())
+ logger.debug("Requested state {} equals current
state {}", value, state);
return;
+ }
try {
- setDeploymentManifest(new DeploymentManifest.Builder()
-
.manifest(getDeploymentManifest()).state(value).build());
+ if (logger.isDebugEnabled())
+ logger.debug("Setting the deployment
manifest...");
+ synchronized (this) {
+ setDeploymentManifest(new
DeploymentManifest.Builder()
+
.manifest(getDeploymentManifest()).state(value).build());
+ }
} catch (Exception e) {
throw new SubsystemException(e);
}
Activator.getInstance().getSubsystemServiceRegistrar().update(this);
synchronized (this) {
+ if (logger.isDebugEnabled())
+ logger.debug("Notifying all waiting for state
change of subsystem {}", getSymbolicName());
notifyAll();
}
}
@@ -590,6 +626,8 @@ public class BasicSubsystem implements R
@Override
public void ended(Coordination coordination) throws Exception {
+ if (logger.isDebugEnabled())
+ logger.debug("Saving deployment manifests
because coordination {} ended", coordination.getName());
Map<Class<?>, Object> variables =
coordination.getVariables();
Set<BasicSubsystem> dirtySubsystems;
synchronized (variables) {
@@ -598,6 +636,8 @@ public class BasicSubsystem implements R
dirtySubsystems = temp == null ? Collections.
<BasicSubsystem>emptySet() : temp;
}
for (BasicSubsystem dirtySubsystem : dirtySubsystems) {
+ if (logger.isDebugEnabled())
+ logger.debug("Saving deployment
manifest of subsystem {} for coordination {}",
dirtySubsystem.getSymbolicName(), coordination.getName());
dirtySubsystem.saveDeploymentManifest();
}
}
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=1468495&r1=1468494&r2=1468495&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 Apr 16 16:30:06 2013
@@ -71,15 +71,17 @@ public class StopAction extends Abstract
// TODO Can we automatically assume it actually is resolved?
target.setState(State.RESOLVED);
try {
- target.setDeploymentManifest(new DeploymentManifest(
- target.getDeploymentManifest(),
- null,
- target.isAutostart(),
- target.getSubsystemId(),
- SubsystemIdentifier.getLastId(),
- target.getLocation(),
- false,
- false));
+ synchronized (target) {
+ target.setDeploymentManifest(new
DeploymentManifest(
+ target.getDeploymentManifest(),
+ null,
+ target.isAutostart(),
+ target.getSubsystemId(),
+ SubsystemIdentifier.getLastId(),
+ target.getLocation(),
+ false,
+ false));
+ }
}
catch (Exception e) {
throw new SubsystemException(e);