[infinispan-commits] Infinispan SVN: r2601 - in trunk: query/src/main/java/org/infinispan/query/backend and 1 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Mon Oct 25 12:08:54 EDT 2010


Author: manik.surtani at jboss.com
Date: 2010-10-25 12:08:54 -0400 (Mon, 25 Oct 2010)
New Revision: 2601

Added:
   trunk/query/src/main/java/org/infinispan/query/backend/SearchFactoryStopper.java
   trunk/query/src/test/java/org/infinispan/query/blackbox/SearchFactoryShutdownTest.java
Modified:
   trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
   trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java
Log:
ISPN-700 - Query integration fails to stop integrated Hibernate Search (merged from branch 4.2.x, r2600)

Modified: trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java	2010-10-25 16:07:10 UTC (rev 2600)
+++ trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java	2010-10-25 16:08:54 UTC (rev 2601)
@@ -96,18 +96,16 @@
 
    // component and method containers
    final Map<String, Component> componentLookup = new HashMap<String, Component>();
-   
+
    protected static List<ModuleLifecycle> moduleLifecycles;
-   
+
    static {
       try {
          moduleLifecycles = ModuleProperties.resolveModuleLifecycles();
-      } catch (Exception e) {         
+      } catch (Exception e) {
          moduleLifecycles = Collections.emptyList();
       }
    }
-   
-   
 
 
    volatile ComponentStatus state = ComponentStatus.INSTANTIATED;
@@ -130,6 +128,7 @@
     * as Commands.
     *
     * @param target object to wire
+    *
     * @throws ConfigurationException if there is a problem wiring the instance
     */
    public void wireDependencies(Object target) throws ConfigurationException {
@@ -219,6 +218,7 @@
       c.injectDependencies();
 
       if (old == null) getLog().trace("Registering component {0} under name {1}", c, name);
+      if (state == ComponentStatus.RUNNING) populateLifeCycleMethods(c);
    }
 
    /**
@@ -250,8 +250,8 @@
    private String getComponentName(Class component, Annotation[][] annotations, int paramNumber) {
       String name;
       if (annotations == null ||
-            annotations.length <= paramNumber ||
-            (name = findComponentName(annotations[paramNumber])) == null) return component.getName();
+              annotations.length <= paramNumber ||
+              (name = findComponentName(annotations[paramNumber])) == null) return component.getName();
 
       return name;
    }
@@ -283,7 +283,9 @@
     * <p/>
     *
     * @param componentClass type of component to be retrieved.  Should not be null.
+    *
     * @return a fully wired component instance, or null if one cannot be found or constructed.
+    *
     * @throws ConfigurationException if there is a problem with constructing or wiring the instance.
     */
    protected <T> T getOrCreateComponent(Class<T> componentClass) {
@@ -304,8 +306,8 @@
             // create this component and add it to the registry
             AbstractComponentFactory factory = getFactory(componentClass);
             component = factory instanceof NamedComponentFactory ?
-                  ((NamedComponentFactory) factory).construct(componentClass, name)
-                  : factory.construct(componentClass);
+                    ((NamedComponentFactory) factory).construct(componentClass, name)
+                    : factory.construct(componentClass);
             attemptedFactoryConstruction = true;
 
          }
@@ -328,6 +330,7 @@
     * doesn't exist in the registry, one is created.
     *
     * @param componentClass type of component to construct
+    *
     * @return component factory capable of constructing such components
     */
    protected AbstractComponentFactory getFactory(Class componentClass) {
@@ -398,6 +401,7 @@
     * public constructor.
     *
     * @param factory class of factory to be created
+    *
     * @return factory instance
     */
    AbstractComponentFactory instantiateFactory(Class<? extends AbstractComponentFactory> factory) {
@@ -427,6 +431,7 @@
     * Retrieves a component from the {@link Configuration}
     *
     * @param componentClass component type
+    *
     * @return component, or null if it cannot be found
     */
    @SuppressWarnings("unchecked")
@@ -460,6 +465,7 @@
     * Retrieves a component of a specified type from the registry, or null if it cannot be found.
     *
     * @param type type to find
+    *
     * @return component, or null
     */
    public <T> T getComponent(Class<T> type) {
@@ -507,30 +513,32 @@
     * by priority.
     */
    private void populateLifecycleMethods() {
-      for (Component c : componentLookup.values()) {
-         if (!c.methodsScanned) {
-            c.methodsScanned = true;
-            c.startMethods.clear();
-            c.stopMethods.clear();
+      for (Component c : componentLookup.values()) populateLifeCycleMethods(c);
+   }
 
-            List<Method> methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Start.class);
-            for (Method m : methods) {
-               PrioritizedMethod em = new PrioritizedMethod();
-               em.component = c;
-               em.method = m;
-               em.priority = m.getAnnotation(Start.class).priority();
-               c.startMethods.add(em);
-            }
+   private void populateLifeCycleMethods(Component c) {
+      if (!c.methodsScanned) {
+         c.methodsScanned = true;
+         c.startMethods.clear();
+         c.stopMethods.clear();
 
-            methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Stop.class);
-            for (Method m : methods) {
-               PrioritizedMethod em = new PrioritizedMethod();
-               em.component = c;
-               em.method = m;
-               em.priority = m.getAnnotation(Stop.class).priority();
-               c.stopMethods.add(em);
-            }
+         List<Method> methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Start.class);
+         for (Method m : methods) {
+            PrioritizedMethod em = new PrioritizedMethod();
+            em.component = c;
+            em.method = m;
+            em.priority = m.getAnnotation(Start.class).priority();
+            c.startMethods.add(em);
          }
+
+         methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Stop.class);
+         for (Method m : methods) {
+            PrioritizedMethod em = new PrioritizedMethod();
+            em.component = c;
+            em.method = m;
+            em.priority = m.getAnnotation(Stop.class).priority();
+            c.stopMethods.add(em);
+         }
       }
    }
 
@@ -713,6 +721,7 @@
     *
     * @param originLocal true if the call originates locally (i.e., from the {@link org.infinispan.CacheDelegate} or
     *                    false if it originates remotely, i.e., from the {@link org.infinispan.remoting.InboundInvocationHandler}.
+    *
     * @return true if invocations are allowed, false otherwise.
     */
    public boolean invocationsAllowed(boolean originLocal) {
@@ -790,10 +799,10 @@
       @Override
       public String toString() {
          return "Component{" +
-               "instance=" + instance +
-               ", name=" + name +
-               ", nonVolatile=" + nonVolatile +
-               '}';
+                 "instance=" + instance +
+                 ", name=" + name +
+                 ", nonVolatile=" + nonVolatile +
+                 '}';
       }
 
       /**
@@ -855,9 +864,9 @@
       @Override
       public String toString() {
          return "PrioritizedMethod{" +
-               "method=" + method +
-               ", priority=" + priority +
-               '}';
+                 "method=" + method +
+                 ", priority=" + priority +
+                 '}';
       }
    }
 

Modified: trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java	2010-10-25 16:07:10 UTC (rev 2600)
+++ trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java	2010-10-25 16:08:54 UTC (rev 2601)
@@ -182,6 +182,7 @@
       // get the component registry and then register the searchFactory.
       ComponentRegistry cr = cache.getAdvancedCache().getComponentRegistry();
       cr.registerComponent(searchFactory, SearchFactoryImplementor.class);
+      cr.registerComponent(new SearchFactoryStopper(searchFactory), SearchFactoryStopper.class);
 
       // Get the interceptor chain factory so I can create my interceptor.
       InterceptorChainFactory icf = cr.getComponent(InterceptorChainFactory.class);

Copied: trunk/query/src/main/java/org/infinispan/query/backend/SearchFactoryStopper.java (from rev 2600, branches/4.2.x/query/src/main/java/org/infinispan/query/backend/SearchFactoryStopper.java)
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/backend/SearchFactoryStopper.java	                        (rev 0)
+++ trunk/query/src/main/java/org/infinispan/query/backend/SearchFactoryStopper.java	2010-10-25 16:08:54 UTC (rev 2601)
@@ -0,0 +1,26 @@
+package org.infinispan.query.backend;
+
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.infinispan.factories.annotations.Stop;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+
+/**
+ * A helper component to clean up a search factory
+ *
+ * @author Manik Surtani
+ * @version 4.2
+ */
+ at Scope(Scopes.NAMED_CACHE)
+public class SearchFactoryStopper {
+   private final SearchFactoryImplementor searchFactory;
+
+   public SearchFactoryStopper(SearchFactoryImplementor searchFactory) {
+      this.searchFactory = searchFactory;
+   }
+
+   @Stop(priority = 1)
+   public void cleanup() {
+      searchFactory.close();
+   }
+}

Copied: trunk/query/src/test/java/org/infinispan/query/blackbox/SearchFactoryShutdownTest.java (from rev 2600, branches/4.2.x/query/src/test/java/org/infinispan/query/blackbox/SearchFactoryShutdownTest.java)
===================================================================
--- trunk/query/src/test/java/org/infinispan/query/blackbox/SearchFactoryShutdownTest.java	                        (rev 0)
+++ trunk/query/src/test/java/org/infinispan/query/blackbox/SearchFactoryShutdownTest.java	2010-10-25 16:08:54 UTC (rev 2601)
@@ -0,0 +1,68 @@
+package org.infinispan.query.blackbox;
+
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.impl.SearchFactoryImpl;
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.query.backend.QueryHelper;
+import org.infinispan.query.helper.TestQueryHelperFactory;
+import org.infinispan.query.test.AnotherGrassEater;
+import org.infinispan.query.test.Person;
+import org.infinispan.test.AbstractInfinispanTest;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.infinispan.config.Configuration.CacheMode.LOCAL;
+
+/**
+ * Ensures the search factory is properly shut down.
+ *
+ * @author Manik Surtani
+ * @version 4.2
+ */
+ at Test(testName = "query.blackbox.SearchFactoryShutdownTest", groups = "functional")
+public class SearchFactoryShutdownTest extends AbstractInfinispanTest {
+   public void testCorrectShutdown() throws NoSuchFieldException, IllegalAccessException {
+      CacheContainer cc = null;
+
+      try {
+         Configuration c = SingleCacheManagerTest.getDefaultClusteredConfig(LOCAL, true);
+         c.setIndexingEnabled(true);
+         c.setIndexLocalOnly(false);
+         cc = TestCacheManagerFactory.createCacheManager(c, true);
+         Cache<?, ?> cache = cc.getCache();
+         QueryHelper qh = TestQueryHelperFactory.createTestQueryHelperInstance(cache, Person.class, AnotherGrassEater.class);
+         SearchFactoryImpl sfi = (SearchFactoryImpl) TestingUtil.extractComponent(cache, SearchFactoryImplementor.class);
+
+         assert !isStopped(sfi);
+
+         TestingUtil.killCacheManagers(cc);
+
+         assert isStopped(sfi);
+      } finally {
+         // proper cleanup for exceptional execution
+         TestingUtil.killCacheManagers(cc);
+      }
+   }
+
+   private boolean isStopped(SearchFactoryImpl sfi) {
+      // this sucks - there is no public API to test the Search Factory's status!!!
+      // This method may fail if used with future versions of Hibernate Search.
+
+      try {
+         Field status = SearchFactoryImpl.class.getDeclaredField("stopped");
+         status.setAccessible(true); // to allow access to a private field
+         AtomicBoolean b = (AtomicBoolean) status.get(sfi);
+         return b.get();
+      } catch (Exception e) {
+         throw new RuntimeException("Cannot test running state of the search factory", e);
+      }
+
+   }
+}



More information about the infinispan-commits mailing list