[exo-jcr-commits] exo-jcr SVN: r4905 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/query and 2 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Sep 13 10:20:22 EDT 2011


Author: nzamosenchuk
Date: 2011-09-13 10:20:22 -0400 (Tue, 13 Sep 2011)
New Revision: 4905

Added:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractRecoveryFilter.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberRecoveryFilter.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DummyRecoveryFilter.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SystemPropertyRecoveryFilter.java
Modified:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerParams.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRecoveryImpl.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
Log:
EXOJCR-1505 : feature implemented and tested. When initializing a SearchIndex it checks if local index is really used and instantiates all the filters configured. Each filter in constructor performs required operations like RPC command's registration. And calling stop on SearchManager invoked close() on each filter. This method should free the resources obtained by filter. When filters are initialized index invokes accept() on each one. When any returns true, current indexes dropped and reindexed or retrieved from coordinator node.
There are couple implementations of filters:
- DummyRecoveryFilter: always returns true, for cases when index must be recovered each time;
- SystemPropertyRecoveryFilter : return value of system property;
- DocNumberRecoveryFilter : checks number of documents in index on coordinator side and self-side. Return true is differs.

EXOJCR-1529 : commit contains a fix for this issues also. Additional parameter is passed from SearchManager to MultiIndex.

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerParams.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerParams.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerParams.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -113,8 +113,10 @@
 
    public static final String PARAM_RDBMS_REINDEXING = "rdbms-reindexing";
    
-   public static final String PARAM_INDEX_RECOVERY_MODE = "index-recovery-mode";
-
    public static final String PARAM_ASYNC_REINDEXING = "async-reindexing";
    
+   public static final String PARAM_INDEX_RECOVERY_MODE = "index-recovery-mode";
+   
+   public static final String PARAM_INDEX_RECOVERY_FILTER = "index-recovery-filter";
+   
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -110,7 +110,6 @@
     */
    public void init() throws IOException, RepositoryException, RepositoryConfigurationException
    {
-      // TODO Auto-generated method stub
       doInit();
       initialized = true;
    }
@@ -264,12 +263,4 @@
    {
       this.indexUpdateMonitor = indexUpdateMonitor;
    }
-
-   /**
-    * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setOnline(boolean)
-    */
-   public void setOnline(boolean isOnline) throws IOException
-   {
-      setOnline(isOnline, false);
-   }
 }
\ No newline at end of file

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRecoveryImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRecoveryImpl.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRecoveryImpl.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -125,7 +125,7 @@
          public Serializable execute(Serializable[] args) throws Throwable
          {
             boolean isOnline = (Boolean)args[0];
-            searchManager.setOnline(isOnline);
+            searchManager.setOnline(isOnline, false, false);
             IndexRecoveryImpl.this.isOnline = isOnline;
             return null;
          }
@@ -300,7 +300,7 @@
          throw new RepositoryException(e);
       }
    }
-   
+
    /**
     * @see org.exoplatform.services.jcr.impl.core.query.IndexRecovery#checkIndexReady()
     */
@@ -452,7 +452,7 @@
                      // node which was responsible for resuming leave the cluster, so resume component
                      log
                         .error("Node responsible for setting index back online seems to leave the cluster. Setting back online.");
-                     searchManager.setOnline(true);
+                     searchManager.setOnline(true, false, false);
                   }
                   catch (SecurityException e1)
                   {

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -200,26 +200,19 @@
 
    /**
     * Switches index into corresponding ONLINE or OFFLINE mode. Offline mode means that new indexing data is
-    * collected but index is guaranteed to be unmodified during offline state. Queries are denied in offline
-    * mode. Please refer to {{@link #setOnline(boolean, boolean)}} if queries must be allowed while index is
-    * offline. 
-    * 
-    * @param isOnline
-    * @throws IOException
-    */
-   void setOnline(boolean isOnline) throws IOException;
-
-   /**
-    * Switches index into corresponding ONLINE or OFFLINE mode. Offline mode means that new indexing data is
     * collected but index is guaranteed to be unmodified during offline state. Passing the allowQuery flag, can
     * allow or deny performing queries on index during offline mode. AllowQuery is not used when setting index
-    * back online.
+    * back online. When dropStaleIndexes is set, indexes present on the moment of switching index offline will be
+    * marked as stale and removed on switching it back online.
     * 
     * @param isOnline
     * @param allowQuery
+    *          doesn't matter, when switching index to online
+    * @param dropStaleIndexes
+    *          doesn't matter, when switching index to online
     * @throws IOException
     */
-   void setOnline(boolean isOnline, boolean allowQuery) throws IOException;
+   void setOnline(boolean isOnline, boolean allowQuery, boolean dropStaleIndexes) throws IOException;
 
    /**
     * Offline mode means that new indexing data is collected but index is guaranteed to be unmodified during

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -72,6 +72,8 @@
 
    private final boolean createInitialIndex;
 
+   private final boolean recoveryFilterUsed;
+
    private final LuceneVirtualTableResolver virtualTableResolver;
 
    /**
@@ -88,7 +90,7 @@
     * Field containing RPCService, if any configured in container  
     */
    private final RPCService rpcService;
-   
+
    private final String repositoryName;
 
    /**
@@ -121,7 +123,8 @@
    public QueryHandlerContext(WorkspaceContainerFacade container, ItemDataConsumer stateMgr, IndexingTree indexingTree,
       NodeTypeDataManager nodeTypeDataManager, NamespaceRegistryImpl nsRegistry, QueryHandler parentHandler,
       String indexDirectory, DocumentReaderService extractor, boolean createInitialIndex,
-      LuceneVirtualTableResolver virtualTableResolver, IndexRecovery indexRecovery, RPCService rpcService, String repositoryName)
+      boolean useIndexRecoveryFilters, LuceneVirtualTableResolver virtualTableResolver, IndexRecovery indexRecovery,
+      RPCService rpcService, String repositoryName)
    {
       this.indexRecovery = indexRecovery;
       this.container = container;
@@ -137,6 +140,7 @@
       this.rpcService = rpcService;
       this.parentHandler = parentHandler;
       this.repositoryName = repositoryName;
+      this.recoveryFilterUsed = useIndexRecoveryFilters;
       ((NodeTypeDataManagerImpl)this.nodeTypeDataManager).addListener(propRegistry);
    }
 
@@ -165,6 +169,14 @@
    }
 
    /**
+    * @return the recoveryFilterUsed
+    */
+   public boolean isRecoveryFilterUsed()
+   {
+      return recoveryFilterUsed;
+   }
+
+   /**
     * Returns the persistent {@link ItemStateManager} of the workspace this
     * <code>QueryHandler</code> is based on.
     * 
@@ -256,7 +268,7 @@
    {
       return rpcService;
    }
-   
+
    /**
     * @return
     *          The name of current repository

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -202,5 +202,9 @@
       {
          searchIndex.setAsyncReindexing(Boolean.parseBoolean(value));
       }
+      else if (QueryHandlerParams.PARAM_INDEX_RECOVERY_FILTER.equals(name))
+      {
+         searchIndex.addRecoveryFilterClass(value);
+      }
    }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -18,9 +18,9 @@
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.WildcardQuery;
+import org.apache.lucene.search.BooleanClause.Occur;
 import org.exoplatform.commons.utils.PrivilegedFileHelper;
 import org.exoplatform.container.ExoContainerContext;
 import org.exoplatform.container.configuration.ConfigurationManager;
@@ -237,7 +237,7 @@
     * Switches index between online and offline modes
     */
    private RemoteCommand changeIndexState;
-   
+
    private final ExoContainerContext ctx;
 
    private String hotReindexingState = "not stated";
@@ -754,10 +754,18 @@
          throw new RepositoryConfigurationException(e);
       }
 
+      // Recovery Filters are 
+      String changesFilterClassName = config.getParameterValue(QueryHandlerParams.PARAM_CHANGES_FILTER_CLASS, null);
+
+      boolean recoveryFilterUsed =
+         (org.exoplatform.services.jcr.impl.core.query.ispn.LocalIndexChangesFilter.class.getName().equals(
+            changesFilterClassName) || org.exoplatform.services.jcr.impl.core.query.jbosscache.LocalIndexChangesFilter.class
+            .getName().equals(changesFilterClassName)) ? true : false;
+
       QueryHandlerContext context =
          new QueryHandlerContext(container, itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler,
-            PrivilegedFileHelper.getAbsolutePath(getIndexDirectory()), extractor, true, virtualTableResolver,
-            indexRecovery, rpcService, repositoryName);
+            PrivilegedFileHelper.getAbsolutePath(getIndexDirectory()), extractor, true, recoveryFilterUsed,
+            virtualTableResolver, indexRecovery, rpcService, repositoryName);
 
       return context;
    }
@@ -918,7 +926,8 @@
          catch (NoSuchMethodException e)
          {
             // No constructor with the workspace id can be found so we use the default constructor
-            Constructor<?> constuctor = qHandlerClass.getConstructor(QueryHandlerEntry.class, ConfigurationManager.class);
+            Constructor<?> constuctor =
+               qHandlerClass.getConstructor(QueryHandlerEntry.class, ConfigurationManager.class);
             handler = (QueryHandler)constuctor.newInstance(config, cfm);
          }
          QueryHandler parentHandler = (this.parentSearchManager != null) ? parentSearchManager.getHandler() : null;
@@ -1114,28 +1123,22 @@
    }
 
    /**
-    * Switches index into online or offline modes.
+    * Switches index into corresponding ONLINE or OFFLINE mode. Offline mode means that new indexing data is
+    * collected but index is guaranteed to be unmodified during offline state. Passing the allowQuery flag, can
+    * allow or deny performing queries on index during offline mode. AllowQuery is not used when setting index
+    * back online. When dropStaleIndexes is set, indexes present on the moment of switching index offline will be
+    * marked as stale and removed on switching it back online.
     * 
     * @param isOnline
-    * @throws IOException
-    */
-   public void setOnline(boolean isOnline) throws IOException
-   {
-      // deny queries
-      handler.setOnline(isOnline, false);
-   }
-
-   /**
-    * Switches index into online or offline modes. Passing the allowQuery flag, can
-    * allow or deny performing queries on index during offline mode
-    * 
-    * @param isOnline
     * @param allowQuery
+    *          doesn't matter, when switching index to online
+    * @param dropStaleIndexes
+    *          doesn't matter, when switching index to online
     * @throws IOException
     */
-   public void setOnline(boolean isOnline, boolean allowQuery) throws IOException
+   public void setOnline(boolean isOnline, boolean allowQuery, boolean dropStaleIndexes) throws IOException
    {
-      handler.setOnline(isOnline, allowQuery);
+      handler.setOnline(isOnline, allowQuery, dropStaleIndexes);
    }
 
    public boolean isOnline()
@@ -1217,7 +1220,7 @@
                }
                else
                {
-                  handler.setOnline(false, !dropExisting);
+                  handler.setOnline(false, !dropExisting, true);
                }
                // launch reindexing thread safely, resume nodes if any exception occurs
                if (handler instanceof SearchIndex)
@@ -1270,7 +1273,7 @@
                {
                   try
                   {
-                     handler.setOnline(true, true);
+                     handler.setOnline(true, true, true);
                   }
                   catch (IOException e)
                   {
@@ -1416,7 +1419,7 @@
          {
             boolean isOnline = (Boolean)args[0];
             boolean allowQuery = (args.length == 2) ? (Boolean)args[1] : false;
-            SearchManager.this.setOnline(isOnline, allowQuery);
+            SearchManager.this.setOnline(isOnline, allowQuery, true);
             return null;
          }
       });

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractRecoveryFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractRecoveryFilter.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractRecoveryFilter.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.exoplatform.services.jcr.impl.core.query.QueryHandlerContext;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:nzamosenchuk at exoplatform.com">Nikolay Zamosenchuk</a>
+ * @version $Id: AbstractRecoveryFilter.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+public abstract class AbstractRecoveryFilter
+{
+
+   protected SearchIndex searchIndex;
+   
+   protected QueryHandlerContext context;
+
+   /**
+    * Default constructor accepting searchIndex instance
+    * @param searchIndex
+    */
+   public AbstractRecoveryFilter(SearchIndex searchIndex)
+   {
+      this.searchIndex = searchIndex;
+      this.context = searchIndex.getContext();
+   }
+
+   /**
+    * Frees resources associated with current filter
+    */
+   public void close()
+   {
+
+   }
+
+   /**
+    * @return true if index should be re-retrieved on JCR start
+    */
+   public abstract boolean accept() throws RepositoryException;
+
+}


Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/AbstractRecoveryFilter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberRecoveryFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberRecoveryFilter.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberRecoveryFilter.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.exoplatform.services.rpc.RPCException;
+import org.exoplatform.services.rpc.RPCService;
+import org.exoplatform.services.rpc.RemoteCommand;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Filter asks coordinator for the number of documents in it's index. Returns true
+ * is it differs with local index.
+ * 
+ * @author <a href="mailto:nzamosenchuk at exoplatform.com">Nikolay Zamosenchul</a>
+ * @version $Id: DocNumberRecoveryFilter.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ */
+public class DocNumberRecoveryFilter extends AbstractRecoveryFilter
+{
+
+   private static final Logger log = LoggerFactory.getLogger("exo.jcr.component.core.index.DocNumberRecoveryFilter");
+
+   protected RemoteCommand getDocsNumCommand;
+
+   protected RPCService rpcService;
+
+   /**
+    * @param searchIndex
+    */
+   public DocNumberRecoveryFilter(SearchIndex searchIndex)
+   {
+      super(searchIndex);
+
+      rpcService = context.getRPCService();
+
+      getDocsNumCommand = rpcService.registerCommand(new RemoteCommand()
+      {
+         public String getId()
+         {
+            return "org.exoplatform.services.jcr.impl.core.query.lucene.DocNumberRecoveryFilter-getDocNum-"
+               + DocNumberRecoveryFilter.this.searchIndex.getWsId() + "-"
+               + (DocNumberRecoveryFilter.this.searchIndex.getContext().getParentHandler() == null);
+         }
+
+         public Serializable execute(Serializable[] args) throws Throwable
+         {
+            log.info("Remote command invoked");
+            return Integer.valueOf(DocNumberRecoveryFilter.this.searchIndex.getIndex().numDocs());
+         }
+      });
+
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   @Override
+   public boolean accept() throws RepositoryException
+   {
+      try
+      {
+         if (!rpcService.isCoordinator())
+         {
+            Integer docsNumber = (Integer)rpcService.executeCommandOnCoordinator(getDocsNumCommand, true);
+            log.info("Remote result received: " + docsNumber + " and local is: " + searchIndex.getIndex().numDocs());
+            return docsNumber.intValue() != searchIndex.getIndex().numDocs();
+         }
+         // if current node is coordinator
+         return false;
+      }
+      catch (SecurityException e)
+      {
+         throw new RepositoryException(e.getMessage(), e);
+      }
+      catch (RPCException e)
+      {
+         throw new RepositoryException(e.getMessage(), e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e.getMessage(), e);
+      }
+   }
+
+   @Override
+   public void close()
+   {
+      rpcService.unregisterCommand(getDocsNumCommand);
+      super.close();
+   }
+
+}


Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberRecoveryFilter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DummyRecoveryFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DummyRecoveryFilter.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DummyRecoveryFilter.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Always returns true, which means that index will be always re-retrieved on node startup
+ * 
+ * @author <a href="mailto:nzamosenchuk at exoplatform.com">Nikolay Zamosenchul</a>
+ * @version $Id: DummyRecoveryFilter.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ */
+public class DummyRecoveryFilter extends AbstractRecoveryFilter
+{
+
+   /**
+    * @param searchIndex
+    */
+   public DummyRecoveryFilter(SearchIndex searchIndex)
+   {
+      super(searchIndex);
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   @Override
+   public boolean accept() throws RepositoryException
+   {
+      return true;
+   }
+
+}


Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DummyRecoveryFilter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -430,13 +430,26 @@
     * @throws IllegalStateException
     *             if this index is not empty.
     */
-   void createInitialIndex(ItemDataConsumer stateMgr) throws IOException
+   void createInitialIndex(ItemDataConsumer stateMgr, boolean doForceReindexing) throws IOException
    {
       // only do an initial index if there are no indexes at all
       boolean indexCreated = false;
+
+      if (doForceReindexing && !indexes.isEmpty())
+      {
+         log.info("Removing stale indexes.");
+
+         List<PersistentIndex> oldIndexes = new ArrayList<PersistentIndex>(indexes);
+         for (PersistentIndex persistentIndex : oldIndexes)
+         {
+            deleteIndex(persistentIndex);
+         }
+         attemptDelete();
+      }
+
       if (indexNames.size() == 0)
       {
-         setOnline(false);
+         setOnline(false, false);
 
          try
          {
@@ -513,7 +526,7 @@
          }
          finally
          {
-            setOnline(true);
+            setOnline(true, false);
          }
       }
       else
@@ -809,25 +822,28 @@
    private void invokeOfflineIndex() throws IOException
    {
       List<String> processedIDs = offlineIndex.getProcessedIDs();
-      // remove all nodes placed in offline index
-      update(processedIDs, Collections.<Document> emptyList());
+      if (!processedIDs.isEmpty())
+      {
+         // remove all nodes placed in offline index
+         update(processedIDs, Collections.<Document> emptyList());
 
-      executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
+         executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
 
-      // create index
-      CreateIndex create = new CreateIndex(getTransactionId(), null);
-      executeAndLog(create);
+         // create index
+         CreateIndex create = new CreateIndex(getTransactionId(), null);
+         executeAndLog(create);
 
-      // invoke offline (copy offline into working index)
-      executeAndLog(new OfflineInvoke(getTransactionId(), create.getIndexName()));
+         // invoke offline (copy offline into working index)
+         executeAndLog(new OfflineInvoke(getTransactionId(), create.getIndexName()));
 
-      // add new index
-      AddIndex add = new AddIndex(getTransactionId(), create.getIndexName());
-      executeAndLog(add);
+         // add new index
+         AddIndex add = new AddIndex(getTransactionId(), create.getIndexName());
+         executeAndLog(add);
 
-      executeAndLog(new Commit(getTransactionId()));
+         executeAndLog(new Commit(getTransactionId()));
 
-      indexNames.write();
+         indexNames.write();
+      }
       offlineIndex.close();
       deleteIndex(offlineIndex);
       offlineIndex = null;
@@ -3361,7 +3377,7 @@
     * @param isOnline
     * @throws IOException
     */
-   public synchronized void setOnline(boolean isOnline) throws IOException
+   public synchronized void setOnline(boolean isOnline, boolean dropStaleIndexes) throws IOException
    {
       // if mode really changed
       if (online != isOnline)
@@ -3404,7 +3420,11 @@
                flush();
             }
             releaseMultiReader();
-            staleIndexes.addAll(indexes);
+            if (dropStaleIndexes)
+            {
+               staleIndexes.addAll(indexes);
+            }
+
             online = false;
          }
       }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -75,6 +75,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -521,6 +523,10 @@
     */
    protected boolean isSuspended = false;
 
+   protected Set<String> recoveryFilterClasses = new HashSet<String>();
+
+   protected List<AbstractRecoveryFilter> recoveryFilters = null;
+
    /**
     * Working constructor.
     * 
@@ -583,13 +589,13 @@
       {
          indexDirectory = new File(path);
 
-            if (!indexDirectory.exists())
+         if (!indexDirectory.exists())
+         {
+            if (!indexDirectory.mkdirs())
             {
-               if (!indexDirectory.mkdirs())
-               {
-                  throw new RepositoryException("fail to create index dir " + path);
-               }
+               throw new RepositoryException("fail to create index dir " + path);
             }
+         }
       }
       else
       {
@@ -641,7 +647,11 @@
       // if RW mode, create initial index and start check
       if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
       {
+         // set true if indexRecoveryFilters are required and some filter gives positive flag
          final boolean doReindexing = (index.numDocs() == 0 && context.isCreateInitialIndex());
+         // if existing index should be removed
+         final boolean doForceReindexing = (context.isRecoveryFilterUsed() && isIndexRecoveryRequired());
+
          final boolean doCheck = (consistencyCheckEnabled && (index.getRedoLogApplied() || forceConsistencyCheck));
          final ItemDataConsumer itemStateManager = context.getItemStateManager();
 
@@ -654,7 +664,7 @@
                {
                   try
                   {
-                     reindex(doReindexing, doCheck, itemStateManager);
+                     reindex(doReindexing, doForceReindexing, doCheck, itemStateManager);
                   }
                   catch (IOException e)
                   {
@@ -668,7 +678,7 @@
          }
          else
          {
-            reindex(doReindexing, doCheck, itemStateManager);
+            reindex(doReindexing, doForceReindexing, doCheck, itemStateManager);
          }
       }
       // initialize spell checker
@@ -700,12 +710,100 @@
       return wsId;
    }
 
-   private void reindex(boolean doReindexing, boolean doCheck, ItemDataConsumer itemStateManager) throws IOException
+   /**
+    * Adds new recovery filter to existing list.
+    * 
+    * @param recoveryFilterClassName
+    */
+   public void addRecoveryFilterClass(String recoveryFilterClassName)
    {
-      if (doReindexing)
+      recoveryFilterClasses.add(recoveryFilterClassName);
+   }
+
+   /**
+    * Invokes all recovery filters from the set
+    * @return true if any filter requires reindexing 
+    */
+   @SuppressWarnings("unchecked")
+   private boolean isIndexRecoveryRequired() throws RepositoryException
+   {
+      // instantiate filters first, if not initialized
+      if (recoveryFilters == null)
       {
-         index.createInitialIndex(itemStateManager);
+         recoveryFilters = new ArrayList<AbstractRecoveryFilter>();
+         log.info("Initializing RecoveryFilters.");
+         for (String recoveryFilterClassName : recoveryFilterClasses)
+         {
+            AbstractRecoveryFilter filter = null;
+            Class<? extends AbstractRecoveryFilter> filterClass;
+            try
+            {
+               filterClass =
+                  (Class<? extends AbstractRecoveryFilter>)Class.forName(recoveryFilterClassName, true, this.getClass()
+                     .getClassLoader());
+               Constructor<? extends AbstractRecoveryFilter> constuctor = filterClass.getConstructor(SearchIndex.class);
+               filter = constuctor.newInstance(this);
+               recoveryFilters.add(filter);
+            }
+            catch (ClassNotFoundException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (IllegalArgumentException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (InstantiationException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (IllegalAccessException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (InvocationTargetException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (SecurityException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+            catch (NoSuchMethodException e)
+            {
+               throw new RepositoryException(e.getMessage(), e);
+            }
+         }
       }
+
+      // invoke filters
+      for (AbstractRecoveryFilter filter : recoveryFilters)
+      {
+         if (filter.accept())
+         {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * @param doReindexing
+    *          performs indexing if set to true 
+    * @param doForceReindexing
+    *          skips index existence check
+    * @param doCheck
+    *          checks index
+    * @param itemStateManager
+    * @throws IOException
+    */
+   private void reindex(boolean doReindexing, boolean doForceReindexing, boolean doCheck,
+      ItemDataConsumer itemStateManager) throws IOException
+   {
+      if (doReindexing || doForceReindexing)
+      {
+         index.createInitialIndex(itemStateManager, doForceReindexing);
+      }
       if (doCheck)
       {
          log.info("Running consistency check...");
@@ -974,6 +1072,17 @@
     */
    public void close()
    {
+      // cleanup resources obtained by filters
+      if (recoveryFilters != null)
+      {
+         for (AbstractRecoveryFilter filter : recoveryFilters)
+         {
+            filter.close();
+         }
+         recoveryFilters.clear();
+         recoveryFilters = null;
+      }
+
       if (synonymProviderConfigFs != null)
       {
          try
@@ -1902,7 +2011,7 @@
          if (log.isDebugEnabled())
          {
             time = System.currentTimeMillis() - time;
-            log.debug("Retrieved {} aggregate roots in {} ms.", new Integer(found), new Long(time));            
+            log.debug("Retrieved {} aggregate roots in {} ms.", new Integer(found), new Long(time));
          }
       }
    }
@@ -3042,7 +3151,7 @@
    /**
     * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setOnline(boolean, boolean)
     */
-   public void setOnline(boolean isOnline, boolean allowQuery) throws IOException
+   public void setOnline(boolean isOnline, boolean allowQuery, boolean dropStaleIndexes) throws IOException
    {
       checkOpen();
       if (isOnline)
@@ -3053,7 +3162,7 @@
       {
          this.allowQuery = allowQuery;
       }
-      index.setOnline(isOnline);
+      index.setOnline(isOnline, dropStaleIndexes);
    }
 
    /**

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SystemPropertyRecoveryFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SystemPropertyRecoveryFilter.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SystemPropertyRecoveryFilter.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.exoplatform.commons.utils.PropertyManager;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Filter returns the value of system property "org.exoplatform.jcr.recoveryfilter.forcereindexing"
+ * 
+ * @author <a href="mailto:nzamosenchuk at exoplatform.com">Nikolay Zamosenchul</a>
+ * @version $Id: SystemPropertyRecoveryFilter.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ */
+public class SystemPropertyRecoveryFilter extends AbstractRecoveryFilter
+{
+
+   public static final String FORCE_REINDEXING_RECOVERY_FILTER_PROPERTY =
+      "org.exoplatform.jcr.recoveryfilter.forcereindexing";
+
+   /**
+    * @param searchIndex
+    */
+   public SystemPropertyRecoveryFilter(SearchIndex searchIndex)
+   {
+      super(searchIndex);
+   }
+
+   /**
+   * {@inheritDoc}
+   */
+   @Override
+   public boolean accept() throws RepositoryException
+   {
+      return Boolean.valueOf(PropertyManager.getProperty(FORCE_REINDEXING_RECOVERY_FILTER_PROPERTY));
+   }
+}


Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SystemPropertyRecoveryFilter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java	2011-09-13 13:55:32 UTC (rev 4904)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java	2011-09-13 14:20:22 UTC (rev 4905)
@@ -116,9 +116,9 @@
    }
 
    /**
-    * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setOnline(boolean, boolean)
+    * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setOnline(boolean, boolean, boolean)
     */
-   public void setOnline(boolean isOnline, boolean allowQuery) throws IOException
+   public void setOnline(boolean isOnline, boolean allowQuery, boolean dropStaleIndexes) throws IOException
    {
       // TODO Auto-generated method stub
       



More information about the exo-jcr-commits mailing list