You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cu...@apache.org on 2010/09/10 16:08:35 UTC
svn commit: r995797 - in /incubator/aries/trunk/blueprint: ./
blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/
blueprint-bundle/ blueprint-core/
blueprint-core/src/main/java/org/apache/aries/blueprint/container/
blueprint-ite...
Author: cumminsh
Date: Fri Sep 10 14:08:34 2010
New Revision: 995797
URL: http://svn.apache.org/viewvc?rev=995797&view=rev
Log:
ARIES-383: Committing patch from Hannah Ramlee and Simon Maple for blueprint quiesce participant.
Added:
incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java
incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/
incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml
Modified:
incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java
incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml
incubator/aries/trunk/blueprint/blueprint-core/pom.xml
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java
incubator/aries/trunk/blueprint/blueprint-itests/pom.xml
incubator/aries/trunk/blueprint/pom.xml
Modified: incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java Fri Sep 10 14:08:34 2010
@@ -77,7 +77,7 @@ public class BlueprintAnnotationTest ext
obj = getOsgiService(bundleContext, Foo.class, null, 5000);
assertNotNull(obj);
- assertSame(foo, obj);
+ assertEquals(foo.toString(), obj.toString());
}
@org.ops4j.pax.exam.junit.Configuration
Modified: incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml (original)
+++ incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml Fri Sep 10 14:08:34 2010
@@ -46,6 +46,8 @@
org.objectweb.asm*;version="[3.1,4)";resolution:=optional,
org.osgi.service.cm;version="[1.2.0,2.0.0)",
org.apache.aries.blueprint.annotation.service;resolution:=optional,
+ org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
+ org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
*
</aries.osgi.import>
<aries.osgi.export>
@@ -107,6 +109,11 @@
<artifactId>org.osgi.compendium</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.aries.quiesce</groupId>
+ <artifactId>org.apache.aries.quiesce.api</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
Added: incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml (added)
+++ incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml Fri Sep 10 14:08:34 2010
@@ -0,0 +1,8 @@
+<project default="copy-resources">
+ <target name="init"/>
+ <target name="copy-resources" depends="init">
+ <copy todir="target/classes/org/apache/aries/blueprint" filtering="false">
+ <fileset dir="/home/cumminsh/projects/aries/apache-workspace/aries/blueprint/blueprint-api/src/main/resources/org/osgi/service/blueprint" includes="blueprint.xsd" excludes="**/*.java"/>
+ </copy>
+ </target>
+</project>
\ No newline at end of file
Modified: incubator/aries/trunk/blueprint/blueprint-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/pom.xml (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/pom.xml Fri Sep 10 14:08:34 2010
@@ -46,6 +46,8 @@
org.osgi.service.event*;resolution:=optional,
org.osgi.service.framework;resolution:=optional,
org.apache.aries.blueprint.annotation.service;resolution:=optional,
+ org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
+ org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
*
</aries.osgi.import>
<aries.osgi.export.service>
@@ -101,6 +103,12 @@
<artifactId>asm-all</artifactId>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.apache.aries.quiesce</groupId>
+ <artifactId>org.apache.aries.quiesce.api</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java Fri Sep 10 14:08:34 2010
@@ -648,7 +648,7 @@ public class BlueprintContainerImpl impl
}
}
- private void unregisterServices() {
+ protected void unregisterServices() {
if (repository != null) {
List<ServiceRecipe> recipes = this.services;
this.services = null;
@@ -821,6 +821,23 @@ public class BlueprintContainerImpl impl
eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYED, getBundleContext().getBundle(), getExtenderBundle()));
LOGGER.debug("Blueprint container destroyed: {}", this.bundleContext);
}
+
+ protected void quiesce() {
+ destroyed = true;
+ eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYING, getBundleContext().getBundle(), getExtenderBundle()));
+
+ if (timeoutFuture != null) {
+ timeoutFuture.cancel(false);
+ }
+ if (registration != null) {
+ registration.unregister();
+ }
+ if (handlerSet != null) {
+ handlerSet.removeListener(this);
+ handlerSet.destroy();
+ }
+ LOGGER.debug("Blueprint container quiesced: {}", this.bundleContext);
+ }
public void namespaceHandlerRegistered(URI uri) {
if (namespaces != null && namespaces.contains(uri)) {
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java Fri Sep 10 14:08:34 2010
@@ -49,9 +49,7 @@ import org.osgi.framework.ServiceRegistr
import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.blueprint.container.BlueprintContainer;
import org.osgi.service.blueprint.container.BlueprintEvent;
-import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,6 +60,8 @@ import org.slf4j.LoggerFactory;
*/
public class BlueprintExtender implements BundleActivator, SynchronousBundleListener {
+ /** The QuiesceParticipant implementation class name */
+ private static final String QUIESCE_PARTICIPANT_CLASS = "org.apache.aries.quiesce.participant.QuiesceParticipant";
private static final Logger LOGGER = LoggerFactory.getLogger(BlueprintExtender.class);
private BundleContext context;
@@ -71,6 +71,7 @@ public class BlueprintExtender implement
private NamespaceHandlerRegistry handlers;
private RecursiveBundleTracker bt;
private ServiceRegistration parserServiceReg;
+ private ServiceRegistration quiesceParticipantReg;
public void start(BundleContext context) {
LOGGER.debug("Starting blueprint extender...");
@@ -90,6 +91,19 @@ public class BlueprintExtender implement
parserServiceReg = context.registerService(ParserService.class.getName(),
new ParserServiceImpl (handlers),
new Hashtable<Object, Object>());
+
+ try{
+ context.getBundle().loadClass(QUIESCE_PARTICIPANT_CLASS);
+ //Class was loaded, register
+
+ quiesceParticipantReg = context.registerService(QUIESCE_PARTICIPANT_CLASS,
+ new BlueprintQuiesceParticipant(context, this),
+ new Hashtable<Object, Object>());
+ }
+ catch (ClassNotFoundException e)
+ {
+ LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations", e);
+ }
LOGGER.debug("Blueprint extender started");
}
@@ -123,6 +137,9 @@ public class BlueprintExtender implement
}
parserServiceReg.unregister();
+
+ if (quiesceParticipantReg != null)
+ quiesceParticipantReg.unregister();
// Orderly shutdown of containers
while (!containers.isEmpty()) {
@@ -392,4 +409,9 @@ public class BlueprintExtender implement
}
}
+ protected BlueprintContainerImpl getBlueprintContainerImpl(Bundle bundle)
+ {
+ return (BlueprintContainerImpl) containers.get(bundle);
+ }
+
}
Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.blueprint.container;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.aries.blueprint.di.Recipe;
+import org.apache.aries.quiesce.manager.QuiesceCallback;
+import org.apache.aries.quiesce.participant.QuiesceParticipant;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class BlueprintQuiesceParticipant implements QuiesceParticipant
+{
+ private BundleContext ctx;
+ private BlueprintExtender extender;
+
+ public BlueprintQuiesceParticipant(BundleContext context, BlueprintExtender extender)
+ {
+ this.ctx = context;
+ this.extender = extender;
+ }
+
+ /**
+ * A Threadpool for running quiesce operations
+ */
+ private final ExecutorService executor = new ThreadPoolExecutor(0, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory()
+ {
+ public Thread newThread(Runnable r)
+ {
+ Thread t = new Thread(r, "Blueprint-Container-ThreadPool");
+ t.setDaemon(true);
+ return t;
+ }
+ });
+
+ public void quiesce(QuiesceCallback callback, List<Bundle> bundlesToQuiesce)
+ {
+ for(Bundle b : bundlesToQuiesce)
+ {
+ try
+ {
+ executor.execute(new QuiesceBundle(callback, b, extender));
+ }
+ catch (RejectedExecutionException re) {
+ }
+
+ //If we are quiescing, then we need to quiesce this threadpool!
+ if(b.equals(ctx.getBundle()))
+ executor.shutdown();
+ }
+ }
+
+ /**
+ * A runnable Quiesce operation for a single bundle
+ */
+ private static final class QuiesceBundle implements Runnable
+ {
+ /** The bundle being quiesced */
+ private final Bundle bundleToQuiesce;
+ private QuiesceCallback callback;
+ private BlueprintExtender extender;
+
+ public QuiesceBundle(QuiesceCallback callback, Bundle bundleToQuiesce,
+ BlueprintExtender extender)
+ {
+ super();
+ this.callback = callback;
+ this.bundleToQuiesce = bundleToQuiesce;
+ this.extender = extender;
+ }
+
+ public void run()
+ {
+ BlueprintContainerImpl container = extender.getBlueprintContainerImpl(bundleToQuiesce);
+
+ BlueprintRepository repository = container.getRepository();
+ Set<String> names = repository.getNames();
+ container.quiesce();
+ boolean hasServices = false;
+
+ for (String name: names)
+ {
+ Recipe recipe = repository.getRecipe(name);
+ if (recipe instanceof ServiceRecipe)
+ {
+ hasServices = true;
+ ((ServiceRecipe)recipe).quiesce(new QuiesceDelegatingCallback(callback, bundleToQuiesce));
+ }
+ }
+ //If the bundle has no services we can quiesce immediately
+ if (!hasServices)
+ {
+ callback.bundleQuiesced(bundleToQuiesce);
+ }
+ }
+ }
+
+ /**
+ * A wrapper to protect our internals from the Quiesce API so that we can make it
+ * an optional dependency
+ */
+ private static final class QuiesceDelegatingCallback implements DestroyCallback
+ {
+
+ /** The callback to delegate to */
+ private final QuiesceCallback callback;
+
+ /** The single bundle being quiesced by this DestroyCallback */
+ private final Bundle toQuiesce;
+
+ private Set<String> services = new HashSet<String>();
+
+ public QuiesceDelegatingCallback(QuiesceCallback cbk, Bundle b)
+ {
+ callback = cbk;
+ toQuiesce = b;
+
+ ServiceReference[] serviceRefs = b.getRegisteredServices();
+
+ for (ServiceReference ref : serviceRefs)
+ {
+ services.add(b.getBundleContext().getService(ref).toString());
+ }
+ }
+
+ public void callback(Object key)
+ {
+ if (key != null && services.remove(key.toString()) && services.isEmpty())
+ {
+ callback.bundleQuiesced(toQuiesce);
+ }
+ }
+ }
+}
Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.blueprint.container;
+
+/**
+ * A callback to indicate that a destroy operation has completed
+ */
+public interface DestroyCallback {
+ public void callback(Object key);
+}
Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.blueprint.container;
+
+import java.lang.reflect.Method;
+
+import org.apache.aries.blueprint.Interceptor;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+
+public class QuiesceInterceptor implements Interceptor{
+
+ private ServiceRecipe serviceRecipe;
+
+ public QuiesceInterceptor(ServiceRecipe serviceRecipe)
+ {
+ this.serviceRecipe = serviceRecipe;
+ }
+
+ public Object preCall(ComponentMetadata cm, Method m, Object... parameters) throws Throwable
+ {
+ serviceRecipe.incrementActiveCalls();
+
+ return null;
+ }
+
+ public void postCallWithReturn(ComponentMetadata cm, Method m, Object returnType, Object preCallToken) throws Throwable
+ {
+ serviceRecipe.decrementActiveCalls();
+ }
+
+ public void postCallWithException(ComponentMetadata cm, Method m, Throwable ex, Object preCallToken) throws Throwable
+ {
+ serviceRecipe.decrementActiveCalls();
+ }
+
+ public int getRank()
+ {
+ return 0;
+ }
+}
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java Fri Sep 10 14:08:34 2010
@@ -16,6 +16,7 @@
*/
package org.apache.aries.blueprint.container;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
@@ -29,12 +30,15 @@ import java.util.concurrent.atomic.Atomi
import org.apache.aries.blueprint.BlueprintConstants;
import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.Interceptor;
import org.apache.aries.blueprint.ServiceProcessor;
import org.apache.aries.blueprint.di.AbstractRecipe;
import org.apache.aries.blueprint.di.CollectionRecipe;
import org.apache.aries.blueprint.di.MapRecipe;
import org.apache.aries.blueprint.di.Recipe;
import org.apache.aries.blueprint.di.Repository;
+import org.apache.aries.blueprint.proxy.AsmInterceptorWrapper;
+import org.apache.aries.blueprint.proxy.CgLibInterceptorWrapper;
import org.apache.aries.blueprint.utils.JavaUtils;
import org.apache.aries.blueprint.utils.ReflectionUtils;
import org.osgi.framework.Bundle;
@@ -43,6 +47,7 @@ import org.osgi.framework.ServiceFactory
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.RefMetadata;
import org.osgi.service.blueprint.reflect.ServiceMetadata;
import org.slf4j.Logger;
@@ -70,6 +75,9 @@ public class ServiceRecipe extends Abstr
private Map registrationProperties;
private List<ServiceListener> listeners;
private volatile Object service;
+ private int activeCalls;
+ private boolean quiesce;
+ private DestroyCallback destroyCallback;
public ServiceRecipe(String name,
ExtendedBlueprintContainer blueprintContainer,
@@ -163,7 +171,7 @@ public class ServiceRecipe extends Abstr
LOGGER.debug("Registering service {} with interfaces {} and properties {}",
new Object[] { name, classes, props });
- registration.set(blueprintContainer.registerService(classArray, new TriggerServiceFactory(), props));
+ registration.set(blueprintContainer.registerService(classArray, new TriggerServiceFactory(this, metadata), props));
}
}
@@ -361,10 +369,124 @@ public class ServiceRecipe extends Abstr
}
}
- private class TriggerServiceFactory implements ServiceFactory {
+ protected void incrementActiveCalls()
+ {
+ synchronized(this)
+ {
+ activeCalls++;
+ }
+ }
+
+ protected void decrementActiveCalls()
+ {
+
+ synchronized(this)
+ {
+ activeCalls--;
+
+ if (quiesce && activeCalls == 0)
+ {
+ destroyCallback.callback(service);
+ }
+ }
+ }
+
+ public void quiesce(DestroyCallback destroyCallback)
+ {
+ this.destroyCallback = destroyCallback;
+ quiesce = true;
+ unregister();
+ if(activeCalls == 0)
+ {
+ destroyCallback.callback(service);
+ }
+ }
+
+ private class TriggerServiceFactory implements ServiceFactory
+ {
+ private QuiesceInterceptor interceptor;
+ private ServiceRecipe serviceRecipe;
+ private ComponentMetadata cm;
+ public TriggerServiceFactory(ServiceRecipe serviceRecipe, ComponentMetadata cm)
+ {
+ this.serviceRecipe = serviceRecipe;
+ this.cm = cm;
+ }
+
+ public Object getService(Bundle bundle, ServiceRegistration registration)
+ {
+ Object original = ServiceRecipe.this.getService(bundle, registration);
+ Object intercepted = null;
+ boolean asmAvailable = false;
+ boolean cglibAvailable = false;
+
+ if (interceptor == null)
+ {
+ interceptor = new QuiesceInterceptor(serviceRecipe);
+ }
+
+ List<Interceptor> interceptors = new ArrayList<Interceptor>();
+ interceptors.add(interceptor);
+
+ try
+ {
+ // Try load load an asm class (to make sure it's actually
+ // available)
+ getClass().getClassLoader().loadClass(
+ "org.objectweb.asm.ClassVisitor");
+ LOGGER.debug("asm available for interceptors");
+ asmAvailable = true;
+ }
+ catch (Throwable t)
+ {
+ try
+ {
+ // Try load load a cglib class (to make sure it's actually
+ // available)
+ getClass().getClassLoader().loadClass(
+ "net.sf.cglib.proxy.Enhancer");
+ cglibAvailable = true;
+ }
+ catch (Throwable u)
+ {
+ LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations");
+ return original;
+ }
+ }
+
+ try
+ {
+ if (asmAvailable)
+ {
+ // if asm is available we can proxy the original object with the
+ // AsmInterceptorWrapper
+ intercepted = AsmInterceptorWrapper.createProxyObject(original
+ .getClass().getClassLoader(), cm, interceptors,
+ original, original.getClass());
+ }
+ else if (cglibAvailable)
+ {
+ LOGGER.debug("cglib available for interceptors");
+ // otherwise we're using cglib and need to use the interfaces
+ // with the CgLibInterceptorWrapper
+ intercepted = CgLibInterceptorWrapper.createProxyObject(
+ original.getClass().getClassLoader(), cm,
+ interceptors, original, original.getClass()
+ .getInterfaces());
+ }
+ else
+ {
+ return original;
+ }
+ }
+ catch (Throwable u)
+ {
+ LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations");
+ return original;
+ }
+
+ return intercepted;
- public Object getService(Bundle bundle, ServiceRegistration registration) {
- return ServiceRecipe.this.getService(bundle, registration);
}
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
Modified: incubator/aries/trunk/blueprint/blueprint-itests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-itests/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-itests/pom.xml (original)
+++ incubator/aries/trunk/blueprint/blueprint-itests/pom.xml Fri Sep 10 14:08:34 2010
@@ -131,6 +131,34 @@
<artifactId>asm-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.aries.quiesce</groupId>
+ <artifactId>org.apache.aries.quiesce.api</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <type>bundle</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <type>bundle</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.core</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <type>bundle</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.cm</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <type>bundle</type>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
Added: incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,469 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.blueprint.itests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackages;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.OptionUtils.combine;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.aries.blueprint.testquiescebundle.TestBean;
+import org.apache.aries.quiesce.manager.QuiesceCallback;
+import org.apache.aries.quiesce.participant.QuiesceParticipant;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.CoreOptions;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.container.def.options.VMOption;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.options.BootDelegationOption;
+import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.util.tracker.ServiceTracker;
+
+@RunWith(JUnit4TestRunner.class)
+public class QuiesceBlueprintTest extends AbstractIntegrationTest{
+
+ private static class TestQuiesceCallback implements QuiesceCallback
+ {
+ private int calls = 0;
+
+ public void bundleQuiesced(Bundle... bundlesQuiesced) {
+ System.out.println("bundleQuiesced "+ bundlesQuiesced);
+ calls++;
+ }
+
+ public int getCalls() {
+ return calls;
+ }
+ }
+
+ private static final int DEFAULT_TIMEOUT = 30000;
+
+ @Inject
+ protected BundleContext bundleContext;
+
+
+ private QuiesceParticipant getParticipant(String bundleName) throws InvalidSyntaxException {
+ ServiceReference[] refs = bundleContext.getServiceReferences(QuiesceParticipant.class.getName(), null);
+
+ if(refs != null) {
+ for(ServiceReference ref : refs) {
+ if(ref.getBundle().getSymbolicName().equals(bundleName))
+ return (QuiesceParticipant) bundleContext.getService(ref);
+ else System.out.println(ref.getBundle().getSymbolicName());
+ }
+ }
+
+
+ return null;
+ }
+
+ @org.ops4j.pax.exam.junit.Configuration
+ public static Option[] configuration() {
+ Option[] options = options(
+ bootDelegationPackages("javax.transaction", "javax.transaction.*"),
+ vmOption("-Dorg.osgi.framework.system.packages=javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,
javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.name
space,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.
PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers,javax.transaction;partial=true;mandatory:=partial,javax.transaction.xa;partial=true;mandatory:=partial"),
+
+ // Log
+ mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
+ mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
+ // Felix Config Admin
+ mavenBundle("org.apache.felix", "org.apache.felix.configadmin"),
+ // Felix mvn url handler
+ mavenBundle("org.ops4j.pax.url", "pax-url-mvn"),
+
+ // this is how you set the default log level when using pax
+ // logging (logProfile)
+ systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("DEBUG"),
+
+ // Bundles
+ mavenBundle("asm","asm-all"),
+ mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.cglib"),
+
+ mavenBundle("org.apache.aries.quiesce", "org.apache.aries.quiesce.api"),
+ mavenBundle("org.apache.aries", "org.apache.aries.util"),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundlea").noStart(),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundleb").noStart(),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testquiescebundle"),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.cm"),
+ mavenBundle("org.osgi", "org.osgi.compendium"),
+
+ //new VMOption( "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000" ),
+
+ equinox().version("3.5.0"));
+ options = updateOptions(options);
+ return options;
+ }
+
+
+ protected Bundle getBundle(String symbolicName) {
+ return getBundle(symbolicName, null);
+ }
+
+ protected Bundle getBundle(String bundleSymbolicName, String version) {
+ Bundle result = null;
+ for (Bundle b : bundleContext.getBundles()) {
+ if (b.getSymbolicName().equals(bundleSymbolicName)) {
+ if (version == null
+ || b.getVersion().equals(Version.parseVersion(version))) {
+ result = b;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ public static BootDelegationOption bootDelegation() {
+ return new BootDelegationOption("org.apache.aries.unittest.fixture");
+ }
+
+ public static MavenArtifactProvisionOption mavenBundle(String groupId,
+ String artifactId) {
+ return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId)
+ .versionAsInProject();
+ }
+
+ protected static Option[] updateOptions(Option[] options) {
+ // We need to add pax-exam-junit here when running with the ibm
+ // jdk to avoid the following exception during the test run:
+ // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
+ if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
+ Option[] ibmOptions = options(wrappedBundle(mavenBundle(
+ "org.ops4j.pax.exam", "pax-exam-junit")));
+ options = combine(ibmOptions, options);
+ }
+
+ return options;
+ }
+
+ protected <T> T getOsgiService(Class<T> type, long timeout) {
+ return getOsgiService(type, null, timeout);
+ }
+
+ protected <T> T getOsgiService(Class<T> type) {
+ return getOsgiService(type, null, DEFAULT_TIMEOUT);
+ }
+
+ protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
+ return getOsgiService(null, type, filter, timeout);
+ }
+
+ protected <T> T getOsgiService(BundleContext bc, Class<T> type,
+ String filter, long timeout) {
+ ServiceTracker tracker = null;
+ try {
+ String flt;
+ if (filter != null) {
+ if (filter.startsWith("(")) {
+ flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")"
+ + filter + ")";
+ } else {
+ flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")("
+ + filter + "))";
+ }
+ } else {
+ flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
+ }
+ Filter osgiFilter = FrameworkUtil.createFilter(flt);
+ tracker = new ServiceTracker(bc == null ? bundleContext : bc, osgiFilter,
+ null);
+ tracker.open();
+ // Note that the tracker is not closed to keep the reference
+ // This is buggy, has the service reference may change i think
+ Object svc = type.cast(tracker.waitForService(timeout));
+ if (svc == null) {
+ throw new RuntimeException("Gave up waiting for service " + flt);
+ }
+ return type.cast(svc);
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Invalid filter", e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ public void testBasicQuieseEmptyCounter() throws Exception
+ {
+ //This test checks that a single bundle when called will not quiesce while
+ //there is an active request (method sleeps), but will quiesce after the
+ //request is completed.
+
+ System.out.println("In testBasicQuieseEmptyCounter");
+ Object obj = getOsgiService(TestBean.class);
+
+ if (obj != null)
+ {
+ QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
+
+ if (participant != null)
+ {
+ System.out.println(obj.getClass().getName());
+
+ TestQuiesceCallback callback = new TestQuiesceCallback();
+
+ Bundle bundle = getBundle("org.apache.aries.blueprint.testquiescebundle");
+
+ System.out.println("Got the bundle");
+
+ List<Bundle> bundles = new ArrayList<Bundle>();
+ bundles.add(bundle);
+
+ Thread t = new Thread(new TestBeanClient((TestBean)obj, 1500));
+ t.start();
+
+ System.out.println("Thread Started");
+
+ participant.quiesce(callback, bundles);
+
+ System.out.println("Called Quiesce");
+
+ Thread.sleep(1000);
+
+ Assert.assertTrue("Quiesce callback should not have occurred yet; calls should be 0, but it is "+callback.getCalls(), callback.getCalls()==0);
+
+ Thread.sleep(1500);
+
+ System.out.println("After second sleep");
+
+ Assert.assertTrue("Quiesce callback should have occurred once; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
+
+ }
+ else
+ {
+ throw new Exception("No Quiesce Participant found for the blueprint service");
+ }
+
+ System.out.println("done");
+ }
+ else
+ {
+ throw new Exception("No Service returned for " + TestBean.class);
+ }
+ }
+
+ @Test
+ public void testNoServicesQuiesce() throws Exception {
+
+ //This test covers the case where one of the bundles being asked to quiesce has no
+ //services. It should be quiesced immediately.
+
+ System.out.println("In testNoServicesQuiesce");
+ Object obj = getOsgiService(TestBean.class);
+
+ if (obj != null)
+ {
+ QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
+
+ if (participant != null)
+ {
+ TestQuiesceCallback callbackA = new TestQuiesceCallback();
+ TestQuiesceCallback callbackB = new TestQuiesceCallback();
+
+ //bundlea provides the ns handlers, bean processors, interceptors etc for this test.
+ Bundle bundlea = getBundle("org.apache.aries.blueprint.testbundlea");
+ assertNotNull(bundlea);
+ bundlea.start();
+
+ //bundleb has no services and makes use of the extensions provided by bundlea
+ Bundle bundleb = getBundle("org.apache.aries.blueprint.testbundleb");
+ assertNotNull(bundleb);
+ bundleb.start();
+
+ participant.quiesce(callbackB, Collections.singletonList(getBundle(
+ "org.apache.aries.blueprint.testbundleb")));
+
+ System.out.println("Called Quiesce");
+
+ Thread.sleep(200);
+
+ Assert.assertTrue("Quiesce callback B should have occurred; calls should be 1, but it is "+callbackB.getCalls(), callbackB.getCalls()==1);
+ Assert.assertTrue("Quiesce callback A should not have occurred yet; calls should be 0, but it is "+callbackA.getCalls(), callbackA.getCalls()==0);
+
+ participant.quiesce(callbackA, Collections.singletonList(getBundle(
+ "org.apache.aries.blueprint.testbundlea")));
+
+ Thread.sleep(1000);
+
+ System.out.println("After second sleep");
+
+ Assert.assertTrue("Quiesce callback A should have occurred once; calls should be 1, but it is "+callbackA.getCalls(), callbackA.getCalls()==1);
+ Assert.assertTrue("Quiesce callback B should have occurred once; calls should be 1, but it is "+callbackB.getCalls(), callbackB.getCalls()==1);
+
+ }else{
+ throw new Exception("No Quiesce Participant found for the blueprint service");
+ }
+ }else{
+ throw new Exception("No Service returned for " + TestBean.class);
+ }
+ }
+
+ @Test
+ public void testMultiBundleQuiesce() throws Exception {
+
+ //This test covers the case where two bundles are quiesced at the same time.
+ //Bundle A should quiesce immediately, quiesce bundle should quiesce after the
+ //request has completed.
+
+ System.out.println("In testMultiBundleQuiesce");
+ Object obj = getOsgiService(TestBean.class);
+
+ if (obj != null)
+ {
+ QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
+
+ if (participant != null)
+ {
+ TestQuiesceCallback callback = new TestQuiesceCallback();
+
+ //bundlea provides the ns handlers, bean processors, interceptors etc for this test.
+ Bundle bundlea = getBundle("org.apache.aries.blueprint.testbundlea");
+ assertNotNull(bundlea);
+ bundlea.start();
+
+ //quiesce bundle will sleep for a second so will quiesce after that
+ Bundle bundleq = getBundle("org.apache.aries.blueprint.testquiescebundle");
+
+ System.out.println("Got the bundle");
+
+ List<Bundle> bundles = new ArrayList<Bundle>();
+ bundles.add(bundlea);
+ bundles.add(bundleq);
+
+ Thread t = new Thread(new TestBeanClient((TestBean)obj, 1500));
+ t.start();
+
+ participant.quiesce(callback, bundles);
+
+ System.out.println("Called Quiesce");
+
+ Thread.sleep(500);
+
+ Assert.assertTrue("Quiesce callback should have occurred once for bundle a but not for bundle q; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
+
+ Thread.sleep(1500);
+
+ System.out.println("After second sleep");
+
+ Assert.assertTrue("Quiesce callback should have occurred twice, once for bundle a and q respectively; calls should be 2, but it is "+callback.getCalls(), callback.getCalls()==2);
+
+ }else{
+ throw new Exception("No Quiesce Participant found for the blueprint service");
+ }
+ }else{
+ throw new Exception("No Service returned for " + TestBean.class);
+ }
+ }
+
+ @Test
+ public void testMultiRequestQuiesce() throws Exception {
+
+ //This test covers the case where we have two active requests when
+ //the bundle is being quiesced.
+
+ System.out.println("In testMultiRequestQuiesce");
+ Object obj = getOsgiService(TestBean.class);
+
+ if (obj != null)
+ {
+ QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
+
+ if (participant != null)
+ {
+ TestQuiesceCallback callback = new TestQuiesceCallback();
+ TestBeanClient client = new TestBeanClient((TestBean)obj, 1500);
+
+
+ //quiesce bundle will sleep for a second so will quiesce after that
+ Bundle bundle = getBundle("org.apache.aries.blueprint.testquiescebundle");
+
+ System.out.println("Got the bundle");
+
+ List<Bundle> bundles = new ArrayList<Bundle>();
+ bundles.add(bundle);
+
+ Thread t = new Thread(client);
+ t.start();
+
+ participant.quiesce(callback, bundles);
+
+ System.out.println("Called Quiesce, putting in a new request");
+
+ Thread t2 = new Thread(client);
+ t2.start();
+
+ Thread.sleep(5000);
+
+ Assert.assertTrue("Quiesce callback should have occurred once; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
+
+
+ }else{
+ throw new Exception("No Quiesce Participant found for the blueprint service");
+ }
+ }else{
+ throw new Exception("No Service returned for " + TestBean.class);
+ }
+ }
+
+
+ private class TestBeanClient implements Runnable
+ {
+ private TestBean myService;
+ private int time;
+
+ public TestBeanClient(TestBean myService, int time)
+ {
+ this.myService = myService;
+ this.time = time;
+ }
+
+ public void run()
+ {
+ try
+ {
+ System.out.println("In Test Bean Client - Sleeping zzzzzzz");
+ myService.sleep(time);
+ System.out.println("Woken up");
+ }
+ catch (InterruptedException ie)
+ {
+ ie.printStackTrace();
+ }
+ }
+
+ }
+}
Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml (added)
+++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml Fri Sep 10 14:08:34 2010
@@ -0,0 +1,52 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <description>Blueprint Test Quiesce Bundle, tests the blueprint participant for the quiesce functionality.</description>
+ <parent>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>blueprint</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
+ <name>Apache Aries Blueprint Test Quiesce Bundle</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <aries.osgi.activator>
+ org.apache.aries.blueprint.testquiescebundle.Activator
+ </aries.osgi.activator>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse</groupId>
+ <artifactId>osgi</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.core</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.blueprint.testquiescebundle;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ public void start(BundleContext context) {
+ }
+
+ public void stop(BundleContext context) {
+ }
+
+}
Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java Fri Sep 10 14:08:34 2010
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.blueprint.testquiescebundle;
+
+public class TestBean
+{
+ public void sleep(int time) throws InterruptedException
+ {
+ Thread.sleep(time);
+ }
+}
Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml?rev=995797&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml (added)
+++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml Fri Sep 10 14:08:34 2010
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
+ xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+
+ default-availability="optional">
+
+ <bean id="TestBean" class="org.apache.aries.blueprint.testquiescebundle.TestBean" scope="singleton">
+ </bean>
+
+ <service interface="org.apache.aries.blueprint.testquiescebundle.TestBean" ref="TestBean">
+ </service>
+
+</blueprint>
+
Modified: incubator/aries/trunk/blueprint/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/pom.xml (original)
+++ incubator/aries/trunk/blueprint/pom.xml Fri Sep 10 14:08:34 2010
@@ -91,6 +91,11 @@
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
+ <version>${version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.itests</artifactId>
<version>${version}</version>
</dependency>
@@ -140,6 +145,18 @@
<artifactId>xbean-finder</artifactId>
<version>3.7</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <type>bundle</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.quiesce</groupId>
+ <artifactId>org.apache.aries.quiesce.api</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -180,6 +197,7 @@
<module>blueprint-annotation-itest</module>
<module>blueprint-testbundlea</module>
<module>blueprint-testbundleb</module>
+ <module>blueprint-testquiescebundle</module>
<module>blueprint-itests</module>
</modules>
Re: svn commit: r995797 - in /incubator/aries/trunk/blueprint: ./
blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/
blueprint-bundle/ blueprint-core/ blueprint-core/src/main/java/org/apache/aries/blueprint/container/
blueprint-ite...
Posted by Joe Bohn <jo...@gmail.com>.
Hi Holly,
Can you delete the maven-eclipse.xml file added below which I presume
was added by mistake?
Thanks,
Joe
On 9/10/10 10:08 AM, cumminsh@apache.org wrote:
> Author: cumminsh
> Date: Fri Sep 10 14:08:34 2010
> New Revision: 995797
>
> URL: http://svn.apache.org/viewvc?rev=995797&view=rev
> Log:
> ARIES-383: Committing patch from Hannah Ramlee and Simon Maple for blueprint quiesce participant.
>
> Added:
> incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java
> incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/
> incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml
> Modified:
> incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java
> incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml
> incubator/aries/trunk/blueprint/blueprint-core/pom.xml
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
> incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java
> incubator/aries/trunk/blueprint/blueprint-itests/pom.xml
> incubator/aries/trunk/blueprint/pom.xml
>
> Modified: incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java (original)
> +++ incubator/aries/trunk/blueprint/blueprint-annotation-itest/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java Fri Sep 10 14:08:34 2010
> @@ -77,7 +77,7 @@ public class BlueprintAnnotationTest ext
>
> obj = getOsgiService(bundleContext, Foo.class, null, 5000);
> assertNotNull(obj);
> - assertSame(foo, obj);
> + assertEquals(foo.toString(), obj.toString());
> }
>
> @org.ops4j.pax.exam.junit.Configuration
>
> Modified: incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml (original)
> +++ incubator/aries/trunk/blueprint/blueprint-bundle/pom.xml Fri Sep 10 14:08:34 2010
> @@ -46,6 +46,8 @@
> org.objectweb.asm*;version="[3.1,4)";resolution:=optional,
> org.osgi.service.cm;version="[1.2.0,2.0.0)",
> org.apache.aries.blueprint.annotation.service;resolution:=optional,
> + org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
> + org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
> *
> </aries.osgi.import>
> <aries.osgi.export>
> @@ -107,6 +109,11 @@
> <artifactId>org.osgi.compendium</artifactId>
> <scope>provided</scope>
> </dependency>
> +<dependency>
> +<groupId>org.apache.aries.quiesce</groupId>
> +<artifactId>org.apache.aries.quiesce.api</artifactId>
> +<scope>provided</scope>
> +</dependency>
>
> </dependencies>
>
>
> Added: incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml (added)
> +++ incubator/aries/trunk/blueprint/blueprint-core/maven-eclipse.xml Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,8 @@
> +<project default="copy-resources">
> +<target name="init"/>
> +<target name="copy-resources" depends="init">
> +<copy todir="target/classes/org/apache/aries/blueprint" filtering="false">
> +<fileset dir="/home/cumminsh/projects/aries/apache-workspace/aries/blueprint/blueprint-api/src/main/resources/org/osgi/service/blueprint" includes="blueprint.xsd" excludes="**/*.java"/>
> +</copy>
> +</target>
> +</project>
> \ No newline at end of file
>
> Modified: incubator/aries/trunk/blueprint/blueprint-core/pom.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/pom.xml (original)
> +++ incubator/aries/trunk/blueprint/blueprint-core/pom.xml Fri Sep 10 14:08:34 2010
> @@ -46,6 +46,8 @@
> org.osgi.service.event*;resolution:=optional,
> org.osgi.service.framework;resolution:=optional,
> org.apache.aries.blueprint.annotation.service;resolution:=optional,
> + org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
> + org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
> *
> </aries.osgi.import>
> <aries.osgi.export.service>
> @@ -101,6 +103,12 @@
> <artifactId>asm-all</artifactId>
> <optional>true</optional>
> </dependency>
> +<dependency>
> + <groupId>org.apache.aries.quiesce</groupId>
> + <artifactId>org.apache.aries.quiesce.api</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <scope>provided</scope>
> +</dependency>
> </dependencies>
>
> <build>
>
> Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java (original)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java Fri Sep 10 14:08:34 2010
> @@ -648,7 +648,7 @@ public class BlueprintContainerImpl impl
> }
> }
>
> - private void unregisterServices() {
> + protected void unregisterServices() {
> if (repository != null) {
> List<ServiceRecipe> recipes = this.services;
> this.services = null;
> @@ -821,6 +821,23 @@ public class BlueprintContainerImpl impl
> eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYED, getBundleContext().getBundle(), getExtenderBundle()));
> LOGGER.debug("Blueprint container destroyed: {}", this.bundleContext);
> }
> +
> + protected void quiesce() {
> + destroyed = true;
> + eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYING, getBundleContext().getBundle(), getExtenderBundle()));
> +
> + if (timeoutFuture != null) {
> + timeoutFuture.cancel(false);
> + }
> + if (registration != null) {
> + registration.unregister();
> + }
> + if (handlerSet != null) {
> + handlerSet.removeListener(this);
> + handlerSet.destroy();
> + }
> + LOGGER.debug("Blueprint container quiesced: {}", this.bundleContext);
> + }
>
> public void namespaceHandlerRegistered(URI uri) {
> if (namespaces != null&& namespaces.contains(uri)) {
>
> Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java (original)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java Fri Sep 10 14:08:34 2010
> @@ -49,9 +49,7 @@ import org.osgi.framework.ServiceRegistr
> import org.osgi.framework.SynchronousBundleListener;
> import org.osgi.service.blueprint.container.BlueprintContainer;
> import org.osgi.service.blueprint.container.BlueprintEvent;
> -import org.osgi.util.tracker.BundleTracker;
> import org.osgi.util.tracker.BundleTrackerCustomizer;
> -import org.osgi.util.tracker.ServiceTracker;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
>
> @@ -62,6 +60,8 @@ import org.slf4j.LoggerFactory;
> */
> public class BlueprintExtender implements BundleActivator, SynchronousBundleListener {
>
> + /** The QuiesceParticipant implementation class name */
> + private static final String QUIESCE_PARTICIPANT_CLASS = "org.apache.aries.quiesce.participant.QuiesceParticipant";
> private static final Logger LOGGER = LoggerFactory.getLogger(BlueprintExtender.class);
>
> private BundleContext context;
> @@ -71,6 +71,7 @@ public class BlueprintExtender implement
> private NamespaceHandlerRegistry handlers;
> private RecursiveBundleTracker bt;
> private ServiceRegistration parserServiceReg;
> + private ServiceRegistration quiesceParticipantReg;
>
> public void start(BundleContext context) {
> LOGGER.debug("Starting blueprint extender...");
> @@ -90,6 +91,19 @@ public class BlueprintExtender implement
> parserServiceReg = context.registerService(ParserService.class.getName(),
> new ParserServiceImpl (handlers),
> new Hashtable<Object, Object>());
> +
> + try{
> + context.getBundle().loadClass(QUIESCE_PARTICIPANT_CLASS);
> + //Class was loaded, register
> +
> + quiesceParticipantReg = context.registerService(QUIESCE_PARTICIPANT_CLASS,
> + new BlueprintQuiesceParticipant(context, this),
> + new Hashtable<Object, Object>());
> + }
> + catch (ClassNotFoundException e)
> + {
> + LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations", e);
> + }
>
> LOGGER.debug("Blueprint extender started");
> }
> @@ -123,6 +137,9 @@ public class BlueprintExtender implement
> }
>
> parserServiceReg.unregister();
> +
> + if (quiesceParticipantReg != null)
> + quiesceParticipantReg.unregister();
>
> // Orderly shutdown of containers
> while (!containers.isEmpty()) {
> @@ -392,4 +409,9 @@ public class BlueprintExtender implement
> }
> }
>
> + protected BlueprintContainerImpl getBlueprintContainerImpl(Bundle bundle)
> + {
> + return (BlueprintContainerImpl) containers.get(bundle);
> + }
> +
> }
>
> Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintQuiesceParticipant.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,160 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.blueprint.container;
> +
> +import java.util.HashSet;
> +import java.util.List;
> +import java.util.Set;
> +import java.util.concurrent.ExecutorService;
> +import java.util.concurrent.LinkedBlockingQueue;
> +import java.util.concurrent.RejectedExecutionException;
> +import java.util.concurrent.ThreadFactory;
> +import java.util.concurrent.ThreadPoolExecutor;
> +import java.util.concurrent.TimeUnit;
> +
> +import org.apache.aries.blueprint.di.Recipe;
> +import org.apache.aries.quiesce.manager.QuiesceCallback;
> +import org.apache.aries.quiesce.participant.QuiesceParticipant;
> +import org.osgi.framework.Bundle;
> +import org.osgi.framework.BundleContext;
> +import org.osgi.framework.ServiceReference;
> +
> +public class BlueprintQuiesceParticipant implements QuiesceParticipant
> +{
> + private BundleContext ctx;
> + private BlueprintExtender extender;
> +
> + public BlueprintQuiesceParticipant(BundleContext context, BlueprintExtender extender)
> + {
> + this.ctx = context;
> + this.extender = extender;
> + }
> +
> + /**
> + * A Threadpool for running quiesce operations
> + */
> + private final ExecutorService executor = new ThreadPoolExecutor(0, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory()
> + {
> + public Thread newThread(Runnable r)
> + {
> + Thread t = new Thread(r, "Blueprint-Container-ThreadPool");
> + t.setDaemon(true);
> + return t;
> + }
> + });
> +
> + public void quiesce(QuiesceCallback callback, List<Bundle> bundlesToQuiesce)
> + {
> + for(Bundle b : bundlesToQuiesce)
> + {
> + try
> + {
> + executor.execute(new QuiesceBundle(callback, b, extender));
> + }
> + catch (RejectedExecutionException re) {
> + }
> +
> + //If we are quiescing, then we need to quiesce this threadpool!
> + if(b.equals(ctx.getBundle()))
> + executor.shutdown();
> + }
> + }
> +
> + /**
> + * A runnable Quiesce operation for a single bundle
> + */
> + private static final class QuiesceBundle implements Runnable
> + {
> + /** The bundle being quiesced */
> + private final Bundle bundleToQuiesce;
> + private QuiesceCallback callback;
> + private BlueprintExtender extender;
> +
> + public QuiesceBundle(QuiesceCallback callback, Bundle bundleToQuiesce,
> + BlueprintExtender extender)
> + {
> + super();
> + this.callback = callback;
> + this.bundleToQuiesce = bundleToQuiesce;
> + this.extender = extender;
> + }
> +
> + public void run()
> + {
> + BlueprintContainerImpl container = extender.getBlueprintContainerImpl(bundleToQuiesce);
> +
> + BlueprintRepository repository = container.getRepository();
> + Set<String> names = repository.getNames();
> + container.quiesce();
> + boolean hasServices = false;
> +
> + for (String name: names)
> + {
> + Recipe recipe = repository.getRecipe(name);
> + if (recipe instanceof ServiceRecipe)
> + {
> + hasServices = true;
> + ((ServiceRecipe)recipe).quiesce(new QuiesceDelegatingCallback(callback, bundleToQuiesce));
> + }
> + }
> + //If the bundle has no services we can quiesce immediately
> + if (!hasServices)
> + {
> + callback.bundleQuiesced(bundleToQuiesce);
> + }
> + }
> + }
> +
> + /**
> + * A wrapper to protect our internals from the Quiesce API so that we can make it
> + * an optional dependency
> + */
> + private static final class QuiesceDelegatingCallback implements DestroyCallback
> + {
> +
> + /** The callback to delegate to */
> + private final QuiesceCallback callback;
> +
> + /** The single bundle being quiesced by this DestroyCallback */
> + private final Bundle toQuiesce;
> +
> + private Set<String> services = new HashSet<String>();
> +
> + public QuiesceDelegatingCallback(QuiesceCallback cbk, Bundle b)
> + {
> + callback = cbk;
> + toQuiesce = b;
> +
> + ServiceReference[] serviceRefs = b.getRegisteredServices();
> +
> + for (ServiceReference ref : serviceRefs)
> + {
> + services.add(b.getBundleContext().getService(ref).toString());
> + }
> + }
> +
> + public void callback(Object key)
> + {
> + if (key != null&& services.remove(key.toString())&& services.isEmpty())
> + {
> + callback.bundleQuiesced(toQuiesce);
> + }
> + }
> + }
> +}
>
> Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/DestroyCallback.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,26 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.blueprint.container;
> +
> +/**
> + * A callback to indicate that a destroy operation has completed
> + */
> +public interface DestroyCallback {
> + public void callback(Object key);
> +}
>
> Added: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/QuiesceInterceptor.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,56 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.blueprint.container;
> +
> +import java.lang.reflect.Method;
> +
> +import org.apache.aries.blueprint.Interceptor;
> +import org.osgi.service.blueprint.reflect.ComponentMetadata;
> +
> +public class QuiesceInterceptor implements Interceptor{
> +
> + private ServiceRecipe serviceRecipe;
> +
> + public QuiesceInterceptor(ServiceRecipe serviceRecipe)
> + {
> + this.serviceRecipe = serviceRecipe;
> + }
> +
> + public Object preCall(ComponentMetadata cm, Method m, Object... parameters) throws Throwable
> + {
> + serviceRecipe.incrementActiveCalls();
> +
> + return null;
> + }
> +
> + public void postCallWithReturn(ComponentMetadata cm, Method m, Object returnType, Object preCallToken) throws Throwable
> + {
> + serviceRecipe.decrementActiveCalls();
> + }
> +
> + public void postCallWithException(ComponentMetadata cm, Method m, Throwable ex, Object preCallToken) throws Throwable
> + {
> + serviceRecipe.decrementActiveCalls();
> + }
> +
> + public int getRank()
> + {
> + return 0;
> + }
> +}
>
> Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java (original)
> +++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ServiceRecipe.java Fri Sep 10 14:08:34 2010
> @@ -16,6 +16,7 @@
> */
> package org.apache.aries.blueprint.container;
>
> +
> import java.util.ArrayList;
> import java.util.Collections;
> import java.util.Dictionary;
> @@ -29,12 +30,15 @@ import java.util.concurrent.atomic.Atomi
>
> import org.apache.aries.blueprint.BlueprintConstants;
> import org.apache.aries.blueprint.ExtendedBlueprintContainer;
> +import org.apache.aries.blueprint.Interceptor;
> import org.apache.aries.blueprint.ServiceProcessor;
> import org.apache.aries.blueprint.di.AbstractRecipe;
> import org.apache.aries.blueprint.di.CollectionRecipe;
> import org.apache.aries.blueprint.di.MapRecipe;
> import org.apache.aries.blueprint.di.Recipe;
> import org.apache.aries.blueprint.di.Repository;
> +import org.apache.aries.blueprint.proxy.AsmInterceptorWrapper;
> +import org.apache.aries.blueprint.proxy.CgLibInterceptorWrapper;
> import org.apache.aries.blueprint.utils.JavaUtils;
> import org.apache.aries.blueprint.utils.ReflectionUtils;
> import org.osgi.framework.Bundle;
> @@ -43,6 +47,7 @@ import org.osgi.framework.ServiceFactory
> import org.osgi.framework.ServiceReference;
> import org.osgi.framework.ServiceRegistration;
> import org.osgi.service.blueprint.container.ComponentDefinitionException;
> +import org.osgi.service.blueprint.reflect.ComponentMetadata;
> import org.osgi.service.blueprint.reflect.RefMetadata;
> import org.osgi.service.blueprint.reflect.ServiceMetadata;
> import org.slf4j.Logger;
> @@ -70,6 +75,9 @@ public class ServiceRecipe extends Abstr
> private Map registrationProperties;
> private List<ServiceListener> listeners;
> private volatile Object service;
> + private int activeCalls;
> + private boolean quiesce;
> + private DestroyCallback destroyCallback;
>
> public ServiceRecipe(String name,
> ExtendedBlueprintContainer blueprintContainer,
> @@ -163,7 +171,7 @@ public class ServiceRecipe extends Abstr
> LOGGER.debug("Registering service {} with interfaces {} and properties {}",
> new Object[] { name, classes, props });
>
> - registration.set(blueprintContainer.registerService(classArray, new TriggerServiceFactory(), props));
> + registration.set(blueprintContainer.registerService(classArray, new TriggerServiceFactory(this, metadata), props));
> }
> }
>
> @@ -361,10 +369,124 @@ public class ServiceRecipe extends Abstr
> }
> }
>
> - private class TriggerServiceFactory implements ServiceFactory {
> + protected void incrementActiveCalls()
> + {
> + synchronized(this)
> + {
> + activeCalls++;
> + }
> + }
> +
> + protected void decrementActiveCalls()
> + {
> +
> + synchronized(this)
> + {
> + activeCalls--;
> +
> + if (quiesce&& activeCalls == 0)
> + {
> + destroyCallback.callback(service);
> + }
> + }
> + }
> +
> + public void quiesce(DestroyCallback destroyCallback)
> + {
> + this.destroyCallback = destroyCallback;
> + quiesce = true;
> + unregister();
> + if(activeCalls == 0)
> + {
> + destroyCallback.callback(service);
> + }
> + }
> +
> + private class TriggerServiceFactory implements ServiceFactory
> + {
> + private QuiesceInterceptor interceptor;
> + private ServiceRecipe serviceRecipe;
> + private ComponentMetadata cm;
> + public TriggerServiceFactory(ServiceRecipe serviceRecipe, ComponentMetadata cm)
> + {
> + this.serviceRecipe = serviceRecipe;
> + this.cm = cm;
> + }
> +
> + public Object getService(Bundle bundle, ServiceRegistration registration)
> + {
> + Object original = ServiceRecipe.this.getService(bundle, registration);
> + Object intercepted = null;
> + boolean asmAvailable = false;
> + boolean cglibAvailable = false;
> +
> + if (interceptor == null)
> + {
> + interceptor = new QuiesceInterceptor(serviceRecipe);
> + }
> +
> + List<Interceptor> interceptors = new ArrayList<Interceptor>();
> + interceptors.add(interceptor);
> +
> + try
> + {
> + // Try load load an asm class (to make sure it's actually
> + // available)
> + getClass().getClassLoader().loadClass(
> + "org.objectweb.asm.ClassVisitor");
> + LOGGER.debug("asm available for interceptors");
> + asmAvailable = true;
> + }
> + catch (Throwable t)
> + {
> + try
> + {
> + // Try load load a cglib class (to make sure it's actually
> + // available)
> + getClass().getClassLoader().loadClass(
> + "net.sf.cglib.proxy.Enhancer");
> + cglibAvailable = true;
> + }
> + catch (Throwable u)
> + {
> + LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations");
> + return original;
> + }
> + }
> +
> + try
> + {
> + if (asmAvailable)
> + {
> + // if asm is available we can proxy the original object with the
> + // AsmInterceptorWrapper
> + intercepted = AsmInterceptorWrapper.createProxyObject(original
> + .getClass().getClassLoader(), cm, interceptors,
> + original, original.getClass());
> + }
> + else if (cglibAvailable)
> + {
> + LOGGER.debug("cglib available for interceptors");
> + // otherwise we're using cglib and need to use the interfaces
> + // with the CgLibInterceptorWrapper
> + intercepted = CgLibInterceptorWrapper.createProxyObject(
> + original.getClass().getClassLoader(), cm,
> + interceptors, original, original.getClass()
> + .getInterfaces());
> + }
> + else
> + {
> + return original;
> + }
> + }
> + catch (Throwable u)
> + {
> + LOGGER.info("No quiesce support is available, so blueprint components will not participate in quiesce operations");
> + return original;
> + }
> +
> + return intercepted;
>
> - public Object getService(Bundle bundle, ServiceRegistration registration) {
> - return ServiceRecipe.this.getService(bundle, registration);
> }
>
> public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
>
> Modified: incubator/aries/trunk/blueprint/blueprint-itests/pom.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-itests/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-itests/pom.xml (original)
> +++ incubator/aries/trunk/blueprint/blueprint-itests/pom.xml Fri Sep 10 14:08:34 2010
> @@ -131,6 +131,34 @@
> <artifactId>asm-all</artifactId>
> <scope>test</scope>
> </dependency>
> +<dependency>
> + <groupId>org.apache.aries.quiesce</groupId>
> + <artifactId>org.apache.aries.quiesce.api</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <type>bundle</type>
> + <scope>provided</scope>
> +</dependency>
> +<dependency>
> + <groupId>org.apache.aries.blueprint</groupId>
> + <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <type>bundle</type>
> + <scope>compile</scope>
> +</dependency>
> +<dependency>
> + <groupId>org.apache.aries.blueprint</groupId>
> + <artifactId>org.apache.aries.blueprint.core</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <type>bundle</type>
> + <scope>compile</scope>
> +</dependency>
> +<dependency>
> + <groupId>org.apache.aries.blueprint</groupId>
> + <artifactId>org.apache.aries.blueprint.cm</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <type>bundle</type>
> + <scope>compile</scope>
> +</dependency>
>
> </dependencies>
>
>
> Added: incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/QuiesceBlueprintTest.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,469 @@
> +/* Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You 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.blueprint.itests;
> +
> +import static org.junit.Assert.assertNotNull;
> +import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackages;
> +import static org.ops4j.pax.exam.CoreOptions.equinox;
> +import static org.ops4j.pax.exam.CoreOptions.options;
> +import static org.ops4j.pax.exam.CoreOptions.systemProperty;
> +import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
> +import static org.ops4j.pax.exam.OptionUtils.combine;
> +import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
> +
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.List;
> +
> +import junit.framework.Assert;
> +
> +import org.apache.aries.blueprint.testquiescebundle.TestBean;
> +import org.apache.aries.quiesce.manager.QuiesceCallback;
> +import org.apache.aries.quiesce.participant.QuiesceParticipant;
> +import org.junit.Test;
> +import org.junit.runner.RunWith;
> +import org.ops4j.pax.exam.CoreOptions;
> +import org.ops4j.pax.exam.Inject;
> +import org.ops4j.pax.exam.Option;
> +import org.ops4j.pax.exam.container.def.options.VMOption;
> +import org.ops4j.pax.exam.junit.JUnit4TestRunner;
> +import org.ops4j.pax.exam.options.BootDelegationOption;
> +import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
> +import org.osgi.framework.Bundle;
> +import org.osgi.framework.BundleContext;
> +import org.osgi.framework.Constants;
> +import org.osgi.framework.Filter;
> +import org.osgi.framework.FrameworkUtil;
> +import org.osgi.framework.InvalidSyntaxException;
> +import org.osgi.framework.ServiceReference;
> +import org.osgi.framework.Version;
> +import org.osgi.util.tracker.ServiceTracker;
> +
> +@RunWith(JUnit4TestRunner.class)
> +public class QuiesceBlueprintTest extends AbstractIntegrationTest{
> +
> + private static class TestQuiesceCallback implements QuiesceCallback
> + {
> + private int calls = 0;
> +
> + public void bundleQuiesced(Bundle... bundlesQuiesced) {
> + System.out.println("bundleQuiesced "+ bundlesQuiesced);
> + calls++;
> + }
> +
> + public int getCalls() {
> + return calls;
> + }
> + }
> +
> + private static final int DEFAULT_TIMEOUT = 30000;
> +
> + @Inject
> + protected BundleContext bundleContext;
> +
> +
> + private QuiesceParticipant getParticipant(String bundleName) throws InvalidSyntaxException {
> + ServiceReference[] refs = bundleContext.getServiceReferences(QuiesceParticipant.class.getName(), null);
> +
> + if(refs != null) {
> + for(ServiceReference ref : refs) {
> + if(ref.getBundle().getSymbolicName().equals(bundleName))
> + return (QuiesceParticipant) bundleContext.getService(ref);
> + else System.out.println(ref.getBundle().getSymbolicName());
> + }
> + }
> +
> +
> + return null;
> + }
> +
> + @org.ops4j.pax.exam.junit.Configuration
> + public static Option[] configuration() {
> + Option[] options = options(
> + bootDelegationPackages("javax.transaction", "javax.transaction.*"),
> + vmOption("-Dorg.osgi.framework.system.packages=javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callbac
k,
> javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.n
ame
> space,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.o
mg.
> PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers,javax.transaction;partial=true;mandatory:=partial,javax.transaction.xa;partial=true;mandatory:=partial"),
> +
> + // Log
> + mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
> + mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
> + // Felix Config Admin
> + mavenBundle("org.apache.felix", "org.apache.felix.configadmin"),
> + // Felix mvn url handler
> + mavenBundle("org.ops4j.pax.url", "pax-url-mvn"),
> +
> + // this is how you set the default log level when using pax
> + // logging (logProfile)
> + systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("DEBUG"),
> +
> + // Bundles
> + mavenBundle("asm","asm-all"),
> + mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.cglib"),
> +
> + mavenBundle("org.apache.aries.quiesce", "org.apache.aries.quiesce.api"),
> + mavenBundle("org.apache.aries", "org.apache.aries.util"),
> + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
> + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundlea").noStart(),
> + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testbundleb").noStart(),
> + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.testquiescebundle"),
> + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.cm"),
> + mavenBundle("org.osgi", "org.osgi.compendium"),
> +
> + //new VMOption( "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000" ),
> +
> + equinox().version("3.5.0"));
> + options = updateOptions(options);
> + return options;
> + }
> +
> +
> + protected Bundle getBundle(String symbolicName) {
> + return getBundle(symbolicName, null);
> + }
> +
> + protected Bundle getBundle(String bundleSymbolicName, String version) {
> + Bundle result = null;
> + for (Bundle b : bundleContext.getBundles()) {
> + if (b.getSymbolicName().equals(bundleSymbolicName)) {
> + if (version == null
> + || b.getVersion().equals(Version.parseVersion(version))) {
> + result = b;
> + break;
> + }
> + }
> + }
> + return result;
> + }
> +
> + public static BootDelegationOption bootDelegation() {
> + return new BootDelegationOption("org.apache.aries.unittest.fixture");
> + }
> +
> + public static MavenArtifactProvisionOption mavenBundle(String groupId,
> + String artifactId) {
> + return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId)
> + .versionAsInProject();
> + }
> +
> + protected static Option[] updateOptions(Option[] options) {
> + // We need to add pax-exam-junit here when running with the ibm
> + // jdk to avoid the following exception during the test run:
> + // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
> + if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
> + Option[] ibmOptions = options(wrappedBundle(mavenBundle(
> + "org.ops4j.pax.exam", "pax-exam-junit")));
> + options = combine(ibmOptions, options);
> + }
> +
> + return options;
> + }
> +
> + protected<T> T getOsgiService(Class<T> type, long timeout) {
> + return getOsgiService(type, null, timeout);
> + }
> +
> + protected<T> T getOsgiService(Class<T> type) {
> + return getOsgiService(type, null, DEFAULT_TIMEOUT);
> + }
> +
> + protected<T> T getOsgiService(Class<T> type, String filter, long timeout) {
> + return getOsgiService(null, type, filter, timeout);
> + }
> +
> + protected<T> T getOsgiService(BundleContext bc, Class<T> type,
> + String filter, long timeout) {
> + ServiceTracker tracker = null;
> + try {
> + String flt;
> + if (filter != null) {
> + if (filter.startsWith("(")) {
> + flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")"
> + + filter + ")";
> + } else {
> + flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")("
> + + filter + "))";
> + }
> + } else {
> + flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
> + }
> + Filter osgiFilter = FrameworkUtil.createFilter(flt);
> + tracker = new ServiceTracker(bc == null ? bundleContext : bc, osgiFilter,
> + null);
> + tracker.open();
> + // Note that the tracker is not closed to keep the reference
> + // This is buggy, has the service reference may change i think
> + Object svc = type.cast(tracker.waitForService(timeout));
> + if (svc == null) {
> + throw new RuntimeException("Gave up waiting for service " + flt);
> + }
> + return type.cast(svc);
> + } catch (InvalidSyntaxException e) {
> + throw new IllegalArgumentException("Invalid filter", e);
> + } catch (InterruptedException e) {
> + throw new RuntimeException(e);
> + }
> + }
> +
> + @Test
> + public void testBasicQuieseEmptyCounter() throws Exception
> + {
> + //This test checks that a single bundle when called will not quiesce while
> + //there is an active request (method sleeps), but will quiesce after the
> + //request is completed.
> +
> + System.out.println("In testBasicQuieseEmptyCounter");
> + Object obj = getOsgiService(TestBean.class);
> +
> + if (obj != null)
> + {
> + QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
> +
> + if (participant != null)
> + {
> + System.out.println(obj.getClass().getName());
> +
> + TestQuiesceCallback callback = new TestQuiesceCallback();
> +
> + Bundle bundle = getBundle("org.apache.aries.blueprint.testquiescebundle");
> +
> + System.out.println("Got the bundle");
> +
> + List<Bundle> bundles = new ArrayList<Bundle>();
> + bundles.add(bundle);
> +
> + Thread t = new Thread(new TestBeanClient((TestBean)obj, 1500));
> + t.start();
> +
> + System.out.println("Thread Started");
> +
> + participant.quiesce(callback, bundles);
> +
> + System.out.println("Called Quiesce");
> +
> + Thread.sleep(1000);
> +
> + Assert.assertTrue("Quiesce callback should not have occurred yet; calls should be 0, but it is "+callback.getCalls(), callback.getCalls()==0);
> +
> + Thread.sleep(1500);
> +
> + System.out.println("After second sleep");
> +
> + Assert.assertTrue("Quiesce callback should have occurred once; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
> +
> + }
> + else
> + {
> + throw new Exception("No Quiesce Participant found for the blueprint service");
> + }
> +
> + System.out.println("done");
> + }
> + else
> + {
> + throw new Exception("No Service returned for " + TestBean.class);
> + }
> + }
> +
> + @Test
> + public void testNoServicesQuiesce() throws Exception {
> +
> + //This test covers the case where one of the bundles being asked to quiesce has no
> + //services. It should be quiesced immediately.
> +
> + System.out.println("In testNoServicesQuiesce");
> + Object obj = getOsgiService(TestBean.class);
> +
> + if (obj != null)
> + {
> + QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
> +
> + if (participant != null)
> + {
> + TestQuiesceCallback callbackA = new TestQuiesceCallback();
> + TestQuiesceCallback callbackB = new TestQuiesceCallback();
> +
> + //bundlea provides the ns handlers, bean processors, interceptors etc for this test.
> + Bundle bundlea = getBundle("org.apache.aries.blueprint.testbundlea");
> + assertNotNull(bundlea);
> + bundlea.start();
> +
> + //bundleb has no services and makes use of the extensions provided by bundlea
> + Bundle bundleb = getBundle("org.apache.aries.blueprint.testbundleb");
> + assertNotNull(bundleb);
> + bundleb.start();
> +
> + participant.quiesce(callbackB, Collections.singletonList(getBundle(
> + "org.apache.aries.blueprint.testbundleb")));
> +
> + System.out.println("Called Quiesce");
> +
> + Thread.sleep(200);
> +
> + Assert.assertTrue("Quiesce callback B should have occurred; calls should be 1, but it is "+callbackB.getCalls(), callbackB.getCalls()==1);
> + Assert.assertTrue("Quiesce callback A should not have occurred yet; calls should be 0, but it is "+callbackA.getCalls(), callbackA.getCalls()==0);
> +
> + participant.quiesce(callbackA, Collections.singletonList(getBundle(
> + "org.apache.aries.blueprint.testbundlea")));
> +
> + Thread.sleep(1000);
> +
> + System.out.println("After second sleep");
> +
> + Assert.assertTrue("Quiesce callback A should have occurred once; calls should be 1, but it is "+callbackA.getCalls(), callbackA.getCalls()==1);
> + Assert.assertTrue("Quiesce callback B should have occurred once; calls should be 1, but it is "+callbackB.getCalls(), callbackB.getCalls()==1);
> +
> + }else{
> + throw new Exception("No Quiesce Participant found for the blueprint service");
> + }
> + }else{
> + throw new Exception("No Service returned for " + TestBean.class);
> + }
> + }
> +
> + @Test
> + public void testMultiBundleQuiesce() throws Exception {
> +
> + //This test covers the case where two bundles are quiesced at the same time.
> + //Bundle A should quiesce immediately, quiesce bundle should quiesce after the
> + //request has completed.
> +
> + System.out.println("In testMultiBundleQuiesce");
> + Object obj = getOsgiService(TestBean.class);
> +
> + if (obj != null)
> + {
> + QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
> +
> + if (participant != null)
> + {
> + TestQuiesceCallback callback = new TestQuiesceCallback();
> +
> + //bundlea provides the ns handlers, bean processors, interceptors etc for this test.
> + Bundle bundlea = getBundle("org.apache.aries.blueprint.testbundlea");
> + assertNotNull(bundlea);
> + bundlea.start();
> +
> + //quiesce bundle will sleep for a second so will quiesce after that
> + Bundle bundleq = getBundle("org.apache.aries.blueprint.testquiescebundle");
> +
> + System.out.println("Got the bundle");
> +
> + List<Bundle> bundles = new ArrayList<Bundle>();
> + bundles.add(bundlea);
> + bundles.add(bundleq);
> +
> + Thread t = new Thread(new TestBeanClient((TestBean)obj, 1500));
> + t.start();
> +
> + participant.quiesce(callback, bundles);
> +
> + System.out.println("Called Quiesce");
> +
> + Thread.sleep(500);
> +
> + Assert.assertTrue("Quiesce callback should have occurred once for bundle a but not for bundle q; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
> +
> + Thread.sleep(1500);
> +
> + System.out.println("After second sleep");
> +
> + Assert.assertTrue("Quiesce callback should have occurred twice, once for bundle a and q respectively; calls should be 2, but it is "+callback.getCalls(), callback.getCalls()==2);
> +
> + }else{
> + throw new Exception("No Quiesce Participant found for the blueprint service");
> + }
> + }else{
> + throw new Exception("No Service returned for " + TestBean.class);
> + }
> + }
> +
> + @Test
> + public void testMultiRequestQuiesce() throws Exception {
> +
> + //This test covers the case where we have two active requests when
> + //the bundle is being quiesced.
> +
> + System.out.println("In testMultiRequestQuiesce");
> + Object obj = getOsgiService(TestBean.class);
> +
> + if (obj != null)
> + {
> + QuiesceParticipant participant = getParticipant("org.apache.aries.blueprint");
> +
> + if (participant != null)
> + {
> + TestQuiesceCallback callback = new TestQuiesceCallback();
> + TestBeanClient client = new TestBeanClient((TestBean)obj, 1500);
> +
> +
> + //quiesce bundle will sleep for a second so will quiesce after that
> + Bundle bundle = getBundle("org.apache.aries.blueprint.testquiescebundle");
> +
> + System.out.println("Got the bundle");
> +
> + List<Bundle> bundles = new ArrayList<Bundle>();
> + bundles.add(bundle);
> +
> + Thread t = new Thread(client);
> + t.start();
> +
> + participant.quiesce(callback, bundles);
> +
> + System.out.println("Called Quiesce, putting in a new request");
> +
> + Thread t2 = new Thread(client);
> + t2.start();
> +
> + Thread.sleep(5000);
> +
> + Assert.assertTrue("Quiesce callback should have occurred once; calls should be 1, but it is "+callback.getCalls(), callback.getCalls()==1);
> +
> +
> + }else{
> + throw new Exception("No Quiesce Participant found for the blueprint service");
> + }
> + }else{
> + throw new Exception("No Service returned for " + TestBean.class);
> + }
> + }
> +
> +
> + private class TestBeanClient implements Runnable
> + {
> + private TestBean myService;
> + private int time;
> +
> + public TestBeanClient(TestBean myService, int time)
> + {
> + this.myService = myService;
> + this.time = time;
> + }
> +
> + public void run()
> + {
> + try
> + {
> + System.out.println("In Test Bean Client - Sleeping zzzzzzz");
> + myService.sleep(time);
> + System.out.println("Woken up");
> + }
> + catch (InterruptedException ie)
> + {
> + ie.printStackTrace();
> + }
> + }
> +
> + }
> +}
>
> Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml (added)
> +++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/pom.xml Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,52 @@
> +<!--
> + Licensed to the Apache Software Foundation (ASF) under one or more
> + contributor license agreements. See the NOTICE file distributed with
> + this work for additional information regarding copyright ownership.
> + The ASF licenses this file to You 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.
> +-->
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
> +<modelVersion>4.0.0</modelVersion>
> +<description>Blueprint Test Quiesce Bundle, tests the blueprint participant for the quiesce functionality.</description>
> +<parent>
> +<groupId>org.apache.aries.blueprint</groupId>
> +<artifactId>blueprint</artifactId>
> +<version>0.3-incubating-SNAPSHOT</version>
> +</parent>
> +
> +<artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
> +<name>Apache Aries Blueprint Test Quiesce Bundle</name>
> +<packaging>bundle</packaging>
> +
> +<properties>
> +<aries.osgi.activator>
> + org.apache.aries.blueprint.testquiescebundle.Activator
> +</aries.osgi.activator>
> +</properties>
> +
> +<dependencies>
> +<dependency>
> +<groupId>org.eclipse</groupId>
> +<artifactId>osgi</artifactId>
> +<scope>provided</scope>
> +</dependency>
> +<dependency>
> +<groupId>org.apache.aries.blueprint</groupId>
> +<artifactId>org.apache.aries.blueprint.api</artifactId>
> +</dependency>
> +<dependency>
> +<groupId>org.apache.aries.blueprint</groupId>
> +<artifactId>org.apache.aries.blueprint.core</artifactId>
> +</dependency>
> +</dependencies>
> +
> +</project>
>
> Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/Activator.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,30 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You 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.blueprint.testquiescebundle;
> +
> +import org.osgi.framework.BundleActivator;
> +import org.osgi.framework.BundleContext;
> +
> +public class Activator implements BundleActivator {
> +
> + public void start(BundleContext context) {
> + }
> +
> + public void stop(BundleContext context) {
> + }
> +
> +}
>
> Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java (added)
> +++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/java/org/apache/aries/blueprint/testquiescebundle/TestBean.java Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,25 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You 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.blueprint.testquiescebundle;
> +
> +public class TestBean
> +{
> + public void sleep(int time) throws InterruptedException
> + {
> + Thread.sleep(time);
> + }
> +}
>
> Added: incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml?rev=995797&view=auto
> ==============================================================================
> --- incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml (added)
> +++ incubator/aries/trunk/blueprint/blueprint-testquiescebundle/src/main/resources/OSGI-INF/blueprint/config.xml Fri Sep 10 14:08:34 2010
> @@ -0,0 +1,31 @@
> +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
> +<!--
> + Licensed to the Apache Software Foundation (ASF) under one or more
> + contributor license agreements. See the NOTICE file distributed with
> + this work for additional information regarding copyright ownership.
> + The ASF licenses this file to You 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.
> +-->
> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
> + xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
> + xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
> +
> + default-availability="optional">
> +
> +<bean id="TestBean" class="org.apache.aries.blueprint.testquiescebundle.TestBean" scope="singleton">
> +</bean>
> +
> +<service interface="org.apache.aries.blueprint.testquiescebundle.TestBean" ref="TestBean">
> +</service>
> +
> +</blueprint>
> +
>
> Modified: incubator/aries/trunk/blueprint/pom.xml
> URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/pom.xml?rev=995797&r1=995796&r2=995797&view=diff
> ==============================================================================
> --- incubator/aries/trunk/blueprint/pom.xml (original)
> +++ incubator/aries/trunk/blueprint/pom.xml Fri Sep 10 14:08:34 2010
> @@ -91,6 +91,11 @@
> </dependency>
> <dependency>
> <groupId>org.apache.aries.blueprint</groupId>
> +<artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
> +<version>${version}</version>
> +</dependency>
> +<dependency>
> +<groupId>org.apache.aries.blueprint</groupId>
> <artifactId>org.apache.aries.blueprint.itests</artifactId>
> <version>${version}</version>
> </dependency>
> @@ -140,6 +145,18 @@
> <artifactId>xbean-finder</artifactId>
> <version>3.7</version>
> </dependency>
> +<dependency>
> + <groupId>org.apache.aries.blueprint</groupId>
> + <artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
> + <version>0.3-incubating-SNAPSHOT</version>
> + <type>bundle</type>
> + <scope>compile</scope>
> +</dependency>
> +<dependency>
> +<groupId>org.apache.aries.quiesce</groupId>
> +<artifactId>org.apache.aries.quiesce.api</artifactId>
> +<version>0.3-incubating-SNAPSHOT</version>
> +</dependency>
> </dependencies>
> </dependencyManagement>
>
> @@ -180,6 +197,7 @@
> <module>blueprint-annotation-itest</module>
> <module>blueprint-testbundlea</module>
> <module>blueprint-testbundleb</module>
> +<module>blueprint-testquiescebundle</module>
> <module>blueprint-itests</module>
> </modules>
>
>
>
>
--
Joe