incubator-aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cummi...@apache.org
Subject 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...
Date Fri, 10 Sep 2010 14:08:35 GMT
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>
 



Mime
View raw message