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

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Feb 17 08:57:37 EST 2011


Author: tolusha
Date: 2011-02-17 08:57:37 -0500 (Thu, 17 Feb 2011)
New Revision: 3981

Added:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieve.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieveImpl.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/backup/Suspendable.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/SystemSearchManager.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/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java
Log:
EXOJCR-1193: Index retrieval from coordinator node

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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerParams.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -112,4 +112,6 @@
    public static final String PARAM_REINDEXING_PAGE_SIZE = "reindexing-page-size";
 
    public static final String PARAM_RDBMS_REINDEXING = "rdbms-reindexing";
+   
+   public static final String PARAM_INDEX_RECOVERY_MODE = "index-recovery-mode";
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java	2011-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/Suspendable.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -24,13 +24,16 @@
  */
 public interface Suspendable
 {
+   public static int SUSPEND_COMPONENT_ON_ALL_NODES = 1;
 
+   public static int SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY = 2;
+
    /**
     *  Suspend component.
     *  
     *  @throws SuspendException of error occurred 
     */
-   void suspend() throws SuspendException;
+   void suspend(int flag) throws SuspendException;
 
    /**
     *  Resume component.

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieve.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieve.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieve.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.query;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 16.02.2011
+ * 
+ * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: IndexRetrieve.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public interface IndexRetrieve
+{
+   /**
+    * Get list of relative paths of all files from index directory.
+    * 
+    * @return List
+    * @throws RepositoryException
+    *          if any exception occurred
+    */
+   public List<String> getIndexList() throws RepositoryException;
+
+   /**
+    * Get input stream of index file.
+    * @param filePath
+    *         String, relative file path
+    * @return InputStream
+    * @throws RepositoryException
+    *          if any exception occurred
+    */
+   public InputStream getIndexFile(String filePath) throws RepositoryException;
+}

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieveImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieveImpl.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexRetrieveImpl.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.query;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.services.jcr.impl.util.io.DirectoryHelper;
+import org.exoplatform.services.rpc.RPCException;
+import org.exoplatform.services.rpc.RPCService;
+import org.exoplatform.services.rpc.RemoteCommand;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 16.02.2011
+ * 
+ * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: IndexRetrieveImpl.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class IndexRetrieveImpl implements IndexRetrieve
+{
+
+   /**
+    * Buffer size.
+    */
+   public static final int BUFFER_SIZE = 1024 * 1024;
+
+   /**
+    * The service for executing commands on all nodes of cluster.
+    */
+   protected final RPCService rpcService;
+
+   /**
+    * Remote command responsible for getting the list of relative paths of all files from index directory.
+    */
+   private RemoteCommand getIndexList;
+
+   /**
+    * Remote command responsible for getting data of target file.
+    */
+   private RemoteCommand getIndexFile;
+
+   /**
+    * Constructor IndexRetrieveImpl.
+    */
+   public IndexRetrieveImpl(RPCService rpcService, final String wsId, final boolean isSystem, final File indexDirectory)
+   {
+      this.rpcService = rpcService;
+
+      getIndexList = rpcService.registerCommand(new RemoteCommand()
+      {
+         public String getId()
+         {
+            return "org.exoplatform.services.jcr.impl.core.query.IndexRetrieveImpl-getIndexList-" + wsId + "-"
+               + isSystem;
+         }
+
+         public Serializable execute(Serializable[] args) throws Throwable
+         {
+            int indexDirLen = PrivilegedFileHelper.getAbsolutePath(indexDirectory).length();
+
+            StringBuilder result = new StringBuilder();
+            for (File file : DirectoryHelper.listFiles(indexDirectory))
+            {
+               if (!file.isDirectory())
+               {
+                  result.append(PrivilegedFileHelper.getAbsolutePath(file).substring(indexDirLen)).append('\n');
+               }
+            }
+
+            return result.toString();
+         }
+      });
+
+      getIndexFile = rpcService.registerCommand(new RemoteCommand()
+      {
+         public String getId()
+         {
+            return "org.exoplatform.services.jcr.impl.core.query.IndexRetrieveImpl-getIndexFile-" + wsId + "-"
+               + isSystem;
+         }
+
+         public Serializable execute(Serializable[] args) throws Throwable
+         {
+            String filePath = (String)args[0];
+            int offset = (Integer)args[1];
+
+            RandomAccessFile file = new RandomAccessFile(new File(indexDirectory, filePath), "r");
+            file.seek(offset);
+            
+            byte[] buffer = new byte[BUFFER_SIZE];
+            int len = file.read(buffer);
+            
+            if (len == -1)
+            {
+               return null;
+            }
+            else
+            {
+               byte[] data = new byte[len];
+               System.arraycopy(buffer, 0, data, 0, len);
+
+               return data;
+            }
+         }
+      });
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public List<String> getIndexList() throws RepositoryException
+   {
+      try
+      {
+         List<String> result = new ArrayList<String>();
+
+         String data = (String)rpcService.executeCommandOnCoordinator(getIndexList, true);
+         String[] files = data.split("\n");
+
+         for (String file : files)
+         {
+            result.add(file);
+         }
+
+         return result;
+      }
+      catch (SecurityException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (RPCException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public InputStream getIndexFile(String filePath) throws RepositoryException
+   {
+      try
+      {
+         return new RemoteInputStream(filePath);
+      }
+      catch (SecurityException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (RPCException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * Allows to read data from remote machine.
+    */
+   class RemoteInputStream extends InputStream
+   {
+      private final String filePath;
+
+      private int fileOffset = 0;
+
+      private int bufferOffset = 0;
+
+      private byte[] buffer;
+
+      RemoteInputStream(String filePath) throws SecurityException, RPCException
+      {
+         this.filePath = filePath;
+         readNext();
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int read() throws IOException
+      {
+         throw new UnsupportedOperationException(
+            "RemoteStream.read(byte b[], int off, int len) method is not supported");
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int available() throws IOException
+      {
+         return buffer == null ? 0 : buffer.length - bufferOffset;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int read(byte b[]) throws IOException
+      {
+         if (buffer == null)
+         {
+            return -1;
+         }
+         else if (available() == 0)
+         {
+            try
+            {
+               readNext();
+
+               if (buffer == null)
+               {
+                  return -1;
+               }
+            }
+            catch (SecurityException e)
+            {
+               throw new IOException(e);
+            }
+            catch (RPCException e)
+            {
+               throw new IOException(e);
+            }
+         }
+
+         int len = Math.min(b.length, available());
+         System.arraycopy(buffer, bufferOffset, b, 0, len);
+         bufferOffset += len;
+
+         return len;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int read(byte b[], int off, int len) throws IOException
+      {
+         throw new UnsupportedOperationException(
+            "RemoteStream.read(byte b[], int off, int len) method is not supported");
+      }
+
+      private void readNext() throws SecurityException, RPCException
+      {
+         this.buffer = (byte[])rpcService.executeCommandOnCoordinator(getIndexFile, true, filePath, fileOffset);
+         if (buffer != null)
+         {
+            this.fileOffset += this.buffer.length;
+            this.bufferOffset = 0;
+         }
+      }
+   }
+}

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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -78,6 +78,11 @@
     */
    private final WorkspaceContainerFacade container;
 
+   /** 
+    * The class responsible for index retrieving from other place. 
+    */
+   private final IndexRetrieve indexRetrieve;
+   
    /**
     * Creates a new context instance.
     * 
@@ -100,12 +105,15 @@
     * @param excludedNodeId
     *            id of the node that should be excluded from indexing. Any
     *            descendant of that node is also excluded from indexing.
+    * @param indexRetrieve
+    *            the index retriever from other place     
     */
    public QueryHandlerContext(WorkspaceContainerFacade container, ItemDataConsumer stateMgr, IndexingTree indexingTree,
       NodeTypeDataManager nodeTypeDataManager, NamespaceRegistryImpl nsRegistry, QueryHandler parentHandler,
       String indexDirectory, DocumentReaderService extractor, boolean createInitialIndex,
-      LuceneVirtualTableResolver virtualTableResolver)
+      LuceneVirtualTableResolver virtualTableResolver, IndexRetrieve indexRetrieve)
    {
+      this.indexRetrieve = indexRetrieve;
       this.container = container;
       this.stateMgr = stateMgr;
       this.indexingTree = indexingTree;
@@ -223,4 +231,10 @@
    {
       return indexDirectory;
    }
+
+   public IndexRetrieve getIndexRetrieve()
+   {
+      return indexRetrieve;
+   }
+
 }

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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -194,5 +194,9 @@
       {
          searchIndex.setRDBMSReindexing(Boolean.parseBoolean(value));
       }
+      else if (QueryHandlerParams.PARAM_INDEX_RECOVERY_MODE.equals(name))
+      {
+         searchIndex.setIndexRecoveryMode(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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -167,6 +167,9 @@
     */
    protected final String workspaceName;
 
+   /**
+    * The repository service.
+    */
    protected final RepositoryService rService;
 
    /**
@@ -175,7 +178,7 @@
    protected final String wsId;
 
    /**
-    * The service for executing commands on all nodes of cluster.
+    * Component responsible for executing commands in cluster nodes.
     */
    protected final RPCService rpcService;
 
@@ -190,6 +193,11 @@
    protected Boolean isResponsibleForResuming = false;
 
    /**
+    * Suspend flag.
+    */
+   protected Integer suspendFlag;
+
+   /**
     * Suspend remote command.
     */
    private RemoteCommand suspend;
@@ -204,41 +212,13 @@
     */
    private RemoteCommand requestForResponsibleForResuming;
 
-   /**
-    * Creates a new <code>SearchManager</code>.
-    * 
-    * @param rEntry
-    *            repository configuration
-    * @param rService
-    *            repository service            
-    * @param config
-    *            the search configuration.
-    * @param nsReg
-    *            the namespace registry.
-    * @param ntReg
-    *            the node type registry.
-    * @param itemMgr
-    *            the shared item state manager.
-    * @param rootNodeId
-    *            the id of the root node.
-    * @param parentMgr
-    *            the parent search manager or <code>null</code> if there is no
-    *            parent search manager.
-    * @param excludedNodeId
-    *            id of the node that should be excluded from indexing. Any
-    *            descendant of that node will also be excluded from indexing.
-    * @throws RepositoryException
-    *             if the search manager cannot be initialized
-    * @throws RepositoryConfigurationException
-    */
-
-   public SearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+   public SearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
       QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
       WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
       DocumentReaderService extractor, ConfigurationManager cfm, final RepositoryIndexSearcherHolder indexSearcherHolder)
       throws RepositoryException, RepositoryConfigurationException
    {
-      this(wsConfig, rEntry, rService, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
+      this(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
          indexSearcherHolder, null);
    }
 
@@ -271,19 +251,18 @@
     *             if the search manager cannot be initialized
     * @throws RepositoryConfigurationException
     */
-
-   public SearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+   public SearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
       QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
       WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
       DocumentReaderService extractor, ConfigurationManager cfm,
       final RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
       RepositoryConfigurationException
    {
+      this.rpcService = rpcService;
       this.repositoryName = rEntry.getName();
-      this.workspaceName = wsConfig.getName();
+      this.workspaceName = wEntry.getName();
       this.rService = rService;
-      this.rpcService = rpcService;
-      this.wsId = wsConfig.getUniqueName();
+      this.wsId = wEntry.getUniqueName();
       this.extractor = extractor;
       indexSearcherHolder.addIndexSearcher(this);
       this.config = config;
@@ -561,9 +540,6 @@
                try
                {
                   indexingRootData = (NodeData)itemMgr.getItemData(Constants.ROOT_UUID);
-                  //               indexingRootData =
-                  //                  new TransientNodeData(Constants.ROOT_PATH, Constants.ROOT_UUID, 1, Constants.NT_UNSTRUCTURED,
-                  //                     new InternalQName[0], 0, null, new AccessControlList());
                }
                catch (RepositoryException e)
                {
@@ -604,7 +580,7 @@
       final ChangesHolder changes = getChanges(removedNodes, addedNodes);
       apply(changes);
    }
-   
+
    public void apply(ChangesHolder changes) throws RepositoryException, IOException
    {
       if (handler != null && changes != null && (!changes.getAdd().isEmpty() || !changes.getRemove().isEmpty()))
@@ -703,7 +679,7 @@
       }
       return null;
    }
-   
+
    protected QueryHandlerContext createQueryHandlerContext(QueryHandler parentHandler)
       throws RepositoryConfigurationException
    {
@@ -717,9 +693,15 @@
          throw new RepositoryConfigurationException(e);
       }
 
+      IndexRetrieve indexRetrieve =
+         rpcService == null ? null : new IndexRetrieveImpl(rpcService, getWsId(), parentHandler == null,
+            getIndexDirectory());
+
       QueryHandlerContext context =
          new QueryHandlerContext(container, itemMgr, indexingTree, nodeTypeDataManager, nsReg, parentHandler,
-            getIndexDirectory(), extractor, true, virtualTableResolver);
+            PrivilegedFileHelper.getAbsolutePath(getIndexDirectory()), extractor, true, virtualTableResolver,
+            indexRetrieve);
+
       return context;
    }
 
@@ -753,7 +735,10 @@
       }
    }
 
-   protected String getIndexDir() throws RepositoryConfigurationException
+   /**^
+    * Returns "index-dir" parameter from configuration. 
+    */
+   protected String getIndexDirParam() throws RepositoryConfigurationException
    {
       String dir = config.getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR, null);
       if (dir == null)
@@ -803,8 +788,8 @@
          if (parentSearchManager != null)
          {
             newChangesFilter =
-               constuctor.newInstance(this, parentSearchManager, config, indexingTree, parentSearchManager
-                  .getIndexingTree(), handler, parentSearchManager.getHandler(), cfm);
+               constuctor.newInstance(this, parentSearchManager, config, indexingTree,
+                  parentSearchManager.getIndexingTree(), handler, parentSearchManager.getHandler(), cfm);
          }
       }
       catch (SecurityException e)
@@ -1000,9 +985,10 @@
    /**
     * {@inheritDoc}
     */
-   public void suspend() throws SuspendException
+   public void suspend(int flag) throws SuspendException
    {
       isResponsibleForResuming = true;
+      suspendFlag = flag;
 
       if (rpcService != null)
       {
@@ -1051,8 +1037,9 @@
       }
 
       isResponsibleForResuming = false;
+      suspendFlag = null;
    }
-   
+
    /**
     * Register remote commands.
     */
@@ -1064,7 +1051,8 @@
 
          public String getId()
          {
-            return "org.exoplatform.services.jcr.impl.core.query.SearchManager-suspend-" + wsId;
+            return "org.exoplatform.services.jcr.impl.core.query.SearchManager-suspend-" + wsId + "-"
+               + (parentSearchManager == null);
          }
 
          public Serializable execute(Serializable[] args) throws Throwable
@@ -1079,7 +1067,8 @@
 
          public String getId()
          {
-            return "org.exoplatform.services.jcr.impl.core.query.SearchManager-resume-" + wsId;
+            return "org.exoplatform.services.jcr.impl.core.query.SearchManager-resume-" + wsId + "-"
+               + (parentSearchManager == null);
          }
 
          public Serializable execute(Serializable[] args) throws Throwable
@@ -1095,7 +1084,7 @@
          public String getId()
          {
             return "org.exoplatform.services.jcr.impl.core.query.SearchManager-requestForResponsibilityForResuming-"
-               + wsId;
+               + wsId + "-" + (parentSearchManager == null);
          }
 
          public Serializable execute(Serializable[] args) throws Throwable
@@ -1109,35 +1098,33 @@
 
    protected void suspendLocally() throws SuspendException
    {
+      if (isResponsibleForResuming && suspendFlag == Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY)
+      {
+         return;
+      }
+
       if (isSuspended)
       {
          throw new SuspendException("Component already suspended.");
       }
 
       isSuspended = true;
-
       stop();
-
-      if (handler instanceof Suspendable)
-      {
-         ((Suspendable)handler).suspend();
-      }
    }
 
    protected void resumeLocally() throws ResumeException
    {
-      if (!isSuspended)
+      if (isResponsibleForResuming && suspendFlag == Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY)
       {
-         throw new ResumeException("Component is not suspended.");
+         return;
       }
 
-      start();
-      
-      if (handler instanceof Suspendable)
+      if (!isSuspended)
       {
-         ((Suspendable)handler).resume();
+         throw new ResumeException("Component is not suspended.");
       }
 
+      start();
       isSuspended = false;
    }
 
@@ -1195,7 +1182,7 @@
    {
       try
       {
-         DirectoryHelper.removeDirectory(new File(getIndexDirectory()));
+         DirectoryHelper.removeDirectory(getIndexDirectory());
       }
       catch (IOException e)
       {
@@ -1214,7 +1201,7 @@
    {
       try
       {
-         File indexDir = new File(getIndexDirectory());
+         File indexDir = getIndexDirectory();
 
          if (!PrivilegedFileHelper.exists(indexDir))
          {
@@ -1238,14 +1225,14 @@
    }
 
    /**
-    * Return index directory.
+    * Returns the index directory.
     * 
-    * @return String
+    * @return File
     * @throws RepositoryConfigurationException
     */
-   protected String getIndexDirectory() throws RepositoryConfigurationException
+   protected File getIndexDirectory() throws RepositoryConfigurationException
    {
-      return getIndexDir();
+      return new File(getIndexDirParam());
    }
 
    /**
@@ -1265,7 +1252,6 @@
    {
       try
       {
-         File indexDir = new File(getIndexDirectory());
          File backupDir = new File(storageDir, getStorageName());
 
          if (!PrivilegedFileHelper.exists(backupDir))
@@ -1275,7 +1261,7 @@
          }
          else
          {
-            return new DirectoryRestor(indexDir, backupDir);
+            return new DirectoryRestor(getIndexDirectory(), backupDir);
          }
       }
       catch (RepositoryConfigurationException e)

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java	2011-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -28,12 +28,14 @@
 import org.exoplatform.services.jcr.datamodel.QPath;
 import org.exoplatform.services.jcr.impl.Constants;
 import org.exoplatform.services.jcr.impl.backup.SuspendException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
 import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
 import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 import org.exoplatform.services.rpc.RPCService;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -61,23 +63,22 @@
 
    public static final String INDEX_DIR_SUFFIX = "system";
 
-   public SystemSearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+   public SystemSearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
       QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
       WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
-      RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException, RepositoryConfigurationException
+      RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
+      RepositoryConfigurationException
    {
-      super(wsConfig, rEntry, rService, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder);
+      super(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder,
+         rpcService);
    }
 
-   public SystemSearchManager(WorkspaceEntry wsConfig, RepositoryEntry rEntry, RepositoryService rService,
+   public SystemSearchManager(WorkspaceEntry wEntry, RepositoryEntry rEntry, RepositoryService rService,
       QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
-      WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
-      DocumentReaderService extractor, ConfigurationManager cfm,
-      final RepositoryIndexSearcherHolder indexSearcherHolder, RPCService rpcService) throws RepositoryException,
-      RepositoryConfigurationException
+      WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
+      RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException, RepositoryConfigurationException
    {
-      super(wsConfig, rEntry, rService, config, nsReg, ntReg, itemMgr, null, extractor, cfm, indexSearcherHolder,
-         rpcService);
+      this(wEntry, rEntry, rService, config, nsReg, ntReg, itemMgr, service, cfm, indexSearcherHolder, null);
    }
 
    @Override
@@ -97,9 +98,7 @@
                indexingTree = new IndexingTree(indexingRootNodeData, excludedPaths);
             }
             initializeQueryHandler();
-
          }
-
          catch (RepositoryException e)
          {
             log.error(e.getLocalizedMessage());
@@ -122,9 +121,9 @@
     * {@inheritDoc}
     */
    @Override
-   protected String getIndexDirectory() throws RepositoryConfigurationException
+   protected File getIndexDirectory() throws RepositoryConfigurationException
    {
-      return getIndexDir() + "_" + INDEX_DIR_SUFFIX;
+      return new File(getIndexDirParam() + "_" + INDEX_DIR_SUFFIX);
    }
 
    /**
@@ -139,6 +138,11 @@
    @Override
    protected void suspendLocally() throws SuspendException
    {
+      if (isResponsibleForResuming && suspendFlag == Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY)
+      {
+         return;
+      }
+
       super.suspendLocally();
       isStarted = false;
    }

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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -21,12 +21,16 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermDocs;
 import org.apache.lucene.store.Directory;
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
 import org.exoplatform.commons.utils.SecurityHelper;
 import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
 import org.exoplatform.services.jcr.datamodel.ItemData;
 import org.exoplatform.services.jcr.datamodel.NodeData;
 import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
 import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.backup.ResumeException;
+import org.exoplatform.services.jcr.impl.backup.SuspendException;
+import org.exoplatform.services.jcr.impl.backup.Suspendable;
 import org.exoplatform.services.jcr.impl.core.query.IndexerIoMode;
 import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
 import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeListener;
@@ -37,8 +41,11 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
@@ -430,31 +437,44 @@
          reindexing = true;
          try
          {
-            // traverse and index workspace
-            executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
+            if (handler.getIndexRecoveryMode().equals(SearchIndex.INDEX_RECOVERY_MODE_FROM_COORDINATOR)
+               && handler.getContext().getIndexRetrieve() != null)
+            {
+               log.info("Retrieving index from coordinator...");
+               retreiveIndexFromCoordinator();
 
-            long count;
-
-            // check if we have deal with RDBMS reindexing mechanism
-            Reindexable rdbmsReindexableComponent =
-               (Reindexable)handler.getContext().getContainer().getComponent(Reindexable.class);
-
-            if (handler.isRDBMSReindexing() && rdbmsReindexableComponent != null
-               && rdbmsReindexableComponent.isReindexingSupport())
-            {
-               count =
-                  createIndex(rdbmsReindexableComponent.getNodeDataIndexingIterator(handler.getReindexingPageSize()),
-                     indexingTree.getIndexingRoot());
+               indexNames.read();
+               refreshIndexList();
             }
             else
             {
-               count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
+               // traverse and index workspace
+               executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
+
+               long count;
+
+               // check if we have deal with RDBMS reindexing mechanism
+               Reindexable rdbmsReindexableComponent =
+                  (Reindexable)handler.getContext().getContainer().getComponent(Reindexable.class);
+
+               if (handler.isRDBMSReindexing() && rdbmsReindexableComponent != null
+                  && rdbmsReindexableComponent.isReindexingSupport())
+               {
+                  count =
+                     createIndex(
+                        rdbmsReindexableComponent.getNodeDataIndexingIterator(handler.getReindexingPageSize()),
+                        indexingTree.getIndexingRoot());
+               }
+               else
+               {
+                  count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
+               }
+
+               executeAndLog(new Commit(getTransactionId()));
+               log.info("Created initial index for {} nodes", new Long(count));
+               releaseMultiReader();
+               scheduleFlushTask();
             }
-
-            executeAndLog(new Commit(getTransactionId()));
-            log.info("Created initial index for {} nodes", new Long(count));
-            releaseMultiReader();
-            scheduleFlushTask();
          }
          catch (Exception e)
          {
@@ -3318,4 +3338,82 @@
          }
       }
    }
+
+   /** 
+    * Retrieve index from other node. 
+    * 
+    * @throws SuspendException 
+    * @throws IOException. 
+    * @throws RepositoryException. 
+    * @throws FileNotFoundException. 
+    */
+   private void retreiveIndexFromCoordinator() throws FileNotFoundException, RepositoryException, IOException,
+      SuspendException
+   {
+      List<Suspendable> suspendableComponents =
+         handler.getContext().getContainer().getComponentInstancesOfType(Suspendable.class);
+
+      // the list of components to resume 
+      List<Suspendable> resumeComponents = new ArrayList<Suspendable>();
+
+      try
+      {
+         // suspend all components 
+         for (Suspendable component : suspendableComponents)
+         {
+            component.suspend(Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY);
+            resumeComponents.add(component);
+         }
+
+         File indexDirectory = new File(handler.getContext().getIndexDirectory());
+         for (String filePath : handler.getContext().getIndexRetrieve().getIndexList())
+         {
+            File indexFile = new File(indexDirectory, filePath);
+            if (!PrivilegedFileHelper.exists(indexFile.getParentFile()))
+            {
+               PrivilegedFileHelper.mkdirs(indexFile.getParentFile());
+            }
+
+            // transfer file 
+            InputStream in = handler.getContext().getIndexRetrieve().getIndexFile(filePath);
+            OutputStream out = PrivilegedFileHelper.fileOutputStream(indexFile);
+            try
+            {
+               byte[] buf = new byte[2048];
+               int len;
+
+               while ((len = in.read(buf)) > 0)
+               {
+                  out.write(buf, 0, len);
+               }
+            }
+            finally
+            {
+               if (in != null)
+               {
+                  in.close();
+               }
+
+               if (out != null)
+               {
+                  out.close();
+               }
+            }
+         }
+      }
+      finally
+      {
+         for (Suspendable component : resumeComponents)
+         {
+            try
+            {
+               component.resume();
+            }
+            catch (ResumeException e)
+            {
+               log.error("Can't resume component", e);
+            }
+         }
+      }
+   }
 }
\ No newline at end of file

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-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -180,6 +180,16 @@
     */
    public static final boolean DEFAULT_RDBMS_REINDEXING = true;
 
+   /** 
+    * The default value for {@link #indexRecoveryMode}. 
+    */
+   public static final String INDEX_RECOVERY_MODE_FROM_INDEXING = "from-indexing";
+
+   /** 
+    * The alternative value for {@link #indexRecoveryMode}. 
+    */
+   public static final String INDEX_RECOVERY_MODE_FROM_COORDINATOR = "from-coordinator";
+
    /**
     * Default name of the error log file
     */
@@ -475,6 +485,11 @@
     */
    private boolean rdbmsReindexing = DEFAULT_RDBMS_REINDEXING;
 
+   /** 
+    * The way to create initial index.. 
+    */
+   private String indexRecoveryMode = INDEX_RECOVERY_MODE_FROM_INDEXING;
+
    /**
     * Working constructor.
     * 
@@ -2709,6 +2724,14 @@
       return rdbmsReindexing;
    }
 
+   /** 
+    * @return the current value for indexRecoveryMode 
+    */
+   public String getIndexRecoveryMode()
+   {
+      return indexRecoveryMode;
+   }
+
    /**
     * Sets a new value for termInfosIndexDivisor.
     * 
@@ -2763,6 +2786,17 @@
       this.rdbmsReindexing = rdbmsReindexing;
    }
 
+   /**
+    *  Set a new value for indexRecoveryMode. 
+    * 
+    * @param indexRecoveryMode 
+    *          the new value for indexRecoveryMode
+    */
+   public void setIndexRecoveryMode(String indexRecoveryMode)
+   {
+      this.indexRecoveryMode = indexRecoveryMode;
+   }
+
    // ----------------------------< internal
    // >----------------------------------
 
@@ -2898,7 +2932,7 @@
          if (mode == IndexerIoMode.READ_WRITE)
          {
             // reprocess any notfinished notifies;
-            log.info("Proceessing eroor log ...");
+            log.info("Proceessing error log ...");
             recoverErrorLog(errorLog);
          }
       }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	2011-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -122,6 +122,11 @@
    private RemoteCommand resume;
 
    /**
+    * Suspend flag.
+    */
+   private Integer suspendFlag;
+
+   /**
     * ItemData request, used on get operations.
     * 
     */
@@ -1095,9 +1100,10 @@
    /**
     * {@inheritDoc}
     */
-   public void suspend() throws SuspendException
+   public void suspend(int flag) throws SuspendException
    {
       isResponsibleForResuming = true;
+      suspendFlag = flag;
 
       if (rpcService != null)
       {
@@ -1146,10 +1152,16 @@
       }
 
       isResponsibleForResuming = false;
+      suspendFlag = null;
    }
 
    private void suspendLocally() throws SuspendException
    {
+      if (isResponsibleForResuming && suspendFlag == Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY)
+      {
+         return;
+      }
+
       if (isSuspended)
       {
          throw new SuspendException("Component already suspended.");
@@ -1173,6 +1185,11 @@
 
    private void resumeLocally() throws ResumeException
    {
+      if (isResponsibleForResuming && suspendFlag == Suspendable.SUSPEND_COMPONENT_ON_OTHERS_NODES_ONLY)
+      {
+         return;
+      }
+
       if (!isSuspended)
       {
          throw new ResumeException("Component is not suspended.");

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java	2011-02-16 10:02:16 UTC (rev 3980)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/DirectoryHelper.java	2011-02-17 13:57:37 UTC (rev 3981)
@@ -24,6 +24,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
@@ -42,6 +44,36 @@
 {
 
    /**
+    * Returns the files list of whole directory including its sub directories. 
+    *  
+    * @param srcPath 
+    *          source path 
+    * @return List          
+    * @throws IOException 
+    *          if any exception occurred 
+    */
+   public static List<File> listFiles(File srcPath) throws IOException
+   {
+      List<File> result = new ArrayList<File>();
+
+      if (!PrivilegedFileHelper.isDirectory(srcPath))
+      {
+         throw new IOException(PrivilegedFileHelper.getAbsolutePath(srcPath) + " is a directory");
+      }
+
+      for (File subFile : PrivilegedFileHelper.listFiles(srcPath))
+      {
+         result.add(subFile);
+         if (subFile.isDirectory())
+         {
+            result.addAll(listFiles(subFile));
+         }
+      }
+
+      return result;
+   }
+
+   /**
     * Copy directory.
     * 
     * @param srcPath



More information about the exo-jcr-commits mailing list