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

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Nov 15 08:18:57 EST 2011


Author: tolusha
Date: 2011-11-15 08:18:57 -0500 (Tue, 15 Nov 2011)
New Revision: 5188

Modified:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.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/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestRepositoryManagement.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
Log:
EXOJCR-1635: JCRDataConsistencyTool - DB and Indexes usecases

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java	2011-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -71,8 +71,6 @@
 
    private File inspectionLogFile = null;
 
-   private String lastResult = null;
-
    /**
     * The current repository.
     */

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-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -460,7 +460,9 @@
                throw new RepositoryException(ex.getMessage(), ex);
             }
          }
-      }else{
+      }
+      else
+      {
          // simply run checkIndex, if not suspended
          handler.checkIndex(itemMgr, isSystem, inspectionLog);
       }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2011-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -154,7 +154,7 @@
                : "select * from JCR_SITEM P where P.CONTAINER_NAME='" + jdbcDataContainer.containerName
                   + "' and P.I_CLASS=2 and NOT EXISTS( select * from JCR_SVALUE V where V.PROPERTY_ID=P.ID)",
             new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
-            "All properties that have not value record.", InspectionStatus.WARN));
+            "All properties that have not value record.", InspectionStatus.ERR));
       
       // The differences in the queries by DB dialect.
       // Oracle doesn't work correct with default query because empty value stored as null value.
@@ -212,7 +212,7 @@
             try
             {
                st = jdbcConn.prepareStatement(query.getStatement());
-               // the result of query is expected to be empty
+               // the result of query is expected to be empty 
                resultSet = st.executeQuery();
                if (resultSet.next())
                {

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java	2011-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -19,18 +19,40 @@
 package org.exoplatform.services.jcr.impl;
 
 import org.exoplatform.services.jcr.BaseStandaloneTest;
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
 import org.exoplatform.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.QPath;
 import org.exoplatform.services.jcr.impl.RepositoryCheckController.DataStorage;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
 import org.exoplatform.services.jcr.impl.core.PropertyImpl;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.query.SearchManager;
+import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
+import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
 import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
+import org.exoplatform.services.jcr.util.IdGenerator;
 import org.exoplatform.services.jcr.util.TesterConfigurationHelper;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.sql.Connection;
+import java.util.List;
 
 import javax.jcr.Node;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
 
 /**
  * @author <a href="mailto:skarpenko at exoplatform.com">Sergiy Karpenko</a>
@@ -66,22 +88,10 @@
       super.setUp();
    }
 
-   public void tearDown() throws Exception
-   {
-      if (checkController != null)
-      {
-         File f = checkController.getLastLogFile();
-         if (f != null)
-         {
-            f.delete();
-         }
-      }
-      super.tearDown();
-   }
-
    public void testDB() throws Exception
    {
-      checkController = new RepositoryCheckController(repositoryService.getRepository("db1"));
+      checkController =
+         new RepositoryCheckController(repositoryService.getRepository("db1"));
 
       String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
       assertNotNull(result);
@@ -91,7 +101,8 @@
 
    public void testValueStorage() throws Exception
    {
-      checkController = new RepositoryCheckController(repositoryService.getRepository("db1"));
+      checkController =
+         new RepositoryCheckController(repositoryService.getRepository("db1"));
 
       File f = this.createBLOBTempFile(20);
       InputStream is = new FileInputStream(f);
@@ -131,17 +142,588 @@
       String result =
          checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
             DataStorage.LUCENE_INDEX});
+      checkController.getLastLogFile().delete();
+
       assertNotNull(result);
-      assertTrue("Repository data is not consistent, result: " + result, result
-         .startsWith("Repository data is consistent"));
+      assertTrue("Repository data is not consistent, result: " + result,
+         result.startsWith("Repository data is consistent"));
    }
 
    /**
+    * Index contains documents that was already removed from DB.
+    */
+   public void testIndexUsecaseWrongDocumentId() throws Exception
+   {
+      ManageableRepository repository = helper.createRepository(container, false, false);
+      
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // Remove node from DB
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+
+      conn.prepareStatement(
+         "ALTER TABLE JCR_" + (isMultiDb ? "M" : "S") + "ITEM DROP CONSTRAINT JCR_FK_" + (isMultiDb ? "M" : "S")
+            + "ITEM_PARENT").execute();
+      conn.prepareStatement(
+         "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "ITEM WHERE ID = '" + (isMultiDb ? "" : wsEntry.getName())
+            + node.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+      
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Index contains multiple documents.
+    */
+   public void testIndexUsecaseMultipleDocuments() throws Exception
+   {
+      ManageableRepository repository = helper.createRepository(container, false, false);
+
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // Indexing one more document with same UUID
+      List<SearchManager> searchManagers =
+         repository.getWorkspaceContainer(repository.getConfiguration().getSystemWorkspaceName())
+            .getComponentInstancesOfType(SearchManager.class);
+
+      PlainChangesLog log = new PlainChangesLogImpl();
+
+      NodeData data =
+         new TransientNodeData(QPath.makeChildPath(Constants.ROOT_PATH, new InternalQName("", "testNode")),
+            node.getIdentifier(), -1, Constants.NT_UNSTRUCTURED, null, 0, null, new AccessControlList());
+
+      TransientPropertyData primaryType =
+         new TransientPropertyData(QPath.makeChildPath(data.getQPath(), Constants.JCR_PRIMARYTYPE),
+            IdGenerator.generate(), -1, PropertyType.NAME, data.getIdentifier(), false, new TransientValueData(
+               Constants.NT_UNSTRUCTURED));
+
+      log.add(new ItemState(data, ItemState.ADDED, false, null));
+      log.add(new ItemState(primaryType, ItemState.ADDED, false, null));
+
+      SearchManager sm = null;
+      for (SearchManager searchManager : searchManagers)
+      {
+         if (!(searchManager instanceof SystemSearchManager))
+         {
+            sm = searchManager;
+            break;
+         }
+      }
+
+      assertNotNull(sm);
+      sm.onSaveItems(log);
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Index doesn't contain document which stored in DB.
+    */
+   public void testIndexUsecaseDocumentNotExists() throws Exception
+   {
+      ManageableRepository repository = helper.createRepository(container, false, false);
+
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // Indexing one more document with same UUID
+      List<SearchManager> searchManagers =
+         repository.getWorkspaceContainer(repository.getConfiguration().getSystemWorkspaceName())
+            .getComponentInstancesOfType(SearchManager.class);
+
+      PlainChangesLog log = new PlainChangesLogImpl();
+
+      NodeData data =
+         new TransientNodeData(QPath.makeChildPath(Constants.ROOT_PATH, new InternalQName("", "testNode")),
+            node.getIdentifier(), -1, Constants.NT_UNSTRUCTURED, null, 0, null, new AccessControlList());
+
+      TransientPropertyData primaryType =
+         new TransientPropertyData(QPath.makeChildPath(data.getQPath(), Constants.JCR_PRIMARYTYPE),
+            IdGenerator.generate(), -1, PropertyType.NAME, data.getIdentifier(), false, new TransientValueData(
+               Constants.NT_UNSTRUCTURED));
+
+      log.add(new ItemState(primaryType, ItemState.DELETED, false, null));
+      log.add(new ItemState(data, ItemState.DELETED, false, null));
+
+      SearchManager sm = null;
+      for (SearchManager searchManager : searchManagers)
+      {
+         if (!(searchManager instanceof SystemSearchManager))
+         {
+            sm = searchManager;
+            break;
+         }
+      }
+
+      assertNotNull(sm);
+      sm.onSaveItems(log);
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+
+   /**
+    *  Usecase: property doens't have have parent node.
+    */
+   public void testDBUsecasesPropertyWithoutParentSingleDB() throws Exception
+   {
+      checkDBUsecasesPropertyWithoutParent(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: property doens't have have parent node.
+    */
+   public void testDBUsecasesPropertyWithoutParentMultiDB() throws Exception
+   {
+      checkDBUsecasesPropertyWithoutParent(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesPropertyWithoutParent(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      PropertyImpl prop = (PropertyImpl)node.setProperty("prop", "test");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // change ITEM table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+
+      conn.prepareStatement(
+         "ALTER TABLE JCR_" + (isMultiDb ? "M" : "S") + "ITEM DROP CONSTRAINT JCR_FK_" + (isMultiDb ? "M" : "S")
+            + "ITEM_PARENT").execute();
+      conn.prepareStatement(
+         "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "ITEM WHERE ID = '" + (isMultiDb ? "" : wsEntry.getName())
+            + node.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase: Incorrect JCR_VALUE records.
+    */
+   public void testDBUsecasesIncorrectValueRecordsSingleDB() throws Exception
+   {
+      checkDBUsecasesIncorrectValueRecords(helper.createRepository(container, false, false));
+      checkDBUsecasesIncorrectValueRecords2(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: Incorrect JCR_VALUE records.
+    */
+   public void testDBUsecasesIncorrectValueRecordsMultiDB() throws Exception
+   {
+      checkDBUsecasesIncorrectValueRecords(helper.createRepository(container, true, false));
+      checkDBUsecasesIncorrectValueRecords2(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesIncorrectValueRecords(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      PropertyImpl prop = (PropertyImpl)session.getRootNode().addNode("testNode").setProperty("prop", "test");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // change VALUE table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "UPDATE JCR_" + (isMultiDb ? "M" : "S") + "VALUE SET STORAGE_DESC = 'unexisted-desc' WHERE PROPERTY_ID = '"
+            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   private void checkDBUsecasesIncorrectValueRecords2(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      PropertyImpl prop = (PropertyImpl)session.getRootNode().addNode("testNode").setProperty("prop", "test");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // change VALUE table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "UPDATE JCR_" + (isMultiDb ? "M" : "S") + "VALUE SET DATA = NULL WHERE PROPERTY_ID = '"
+            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase: Reference records that linked to unexisted nodes. Can be normal for some usecases.
+    */
+   public void testDBUsecasesRefPropertiesLinksToUnexistedNodesSingleDB() throws Exception
+   {
+      checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: Reference records that linked to unexisted nodes. Can be normal for some usecases.
+    */
+   public void testDBUsecasesRefPropertiesLinksToUnexistedNodesMultiDB() throws Exception
+   {
+      checkDBUsecasesRefPropertiesLinksToUnexistedNodes(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesRefPropertiesLinksToUnexistedNodes(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl refNode = (NodeImpl)session.getRootNode().addNode("refNode");
+      refNode.addMixin("mix:referenceable");
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      PropertyImpl prop = (PropertyImpl)node.setProperty("refProp", refNode);
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // change node id in REF table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "UPDATE JCR_" + (isMultiDb ? "M" : "S") + "REF SET NODE_ID = 'unexisted-id' WHERE PROPERTY_ID = '"
+            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+         "Repository data is consistent, except some warnings"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase: value records has no item record.
+    */
+   public void testDBUsecasesValueRecordHasNoItemRecordSingleDB() throws Exception
+   {
+      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: value records has no item record.
+    */
+   public void testDBUsecasesValueRecordHasNoItemRecordMultiDB() throws Exception
+   {
+      checkDBUsecasesValueRecordHasNoItemRecord(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesValueRecordHasNoItemRecord(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      PropertyImpl prop = (PropertyImpl)session.getRootNode().addNode("testNode").setProperty("prop", "test");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // remove records from item table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "ALTER TABLE JCR_" + (isMultiDb ? "M" : "S") + "VALUE DROP CONSTRAINT JCR_FK_" + (isMultiDb ? "M" : "S")
+            + "VALUE_PROPERTY").execute();
+      conn.prepareStatement(
+         "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "ITEM WHERE ID = '" + (isMultiDb ? "" : wsEntry.getName())
+            + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase: properties that have not value record.
+    */
+   public void testDBUsecasesPropertiesHasNoValueRecordSingleDB() throws Exception
+   {
+      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: properties that have not value record. 
+    */
+   public void testDBUsecasesPropertiesHasNoValueRecordMultiDB() throws Exception
+   {
+      checkDBUsecasesPropertiesHasNoValueRecord(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesPropertiesHasNoValueRecord(ManageableRepository repository) throws Exception
+   {
+      // create repository and add property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      PropertyImpl prop = (PropertyImpl)session.getRootNode().addNode("testNode").setProperty("prop", "test");
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // remove records from value table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "VALUE WHERE PROPERTY_ID = '"
+            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase: reference properties without reference records.
+    */
+   public void testDBUsecasesReferencePropertyWithoutReferenceRecordSingleDB() throws Exception
+   {
+      checkDBUsecasesReferencePropertyWithoutReferenceRecord(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase: reference properties without reference records.
+    */
+   public void testDBUsecasesReferencePropertyWithoutReferenceRecordMultiDB() throws Exception
+   {
+      checkDBUsecasesReferencePropertyWithoutReferenceRecord(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesReferencePropertyWithoutReferenceRecord(ManageableRepository repository)
+      throws Exception
+   {
+      // create repository and add ref property
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl refNode = (NodeImpl)session.getRootNode().addNode("refNode");
+      refNode.addMixin("mix:referenceable");
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      PropertyImpl prop = (PropertyImpl)node.setProperty("refProp", refNode);
+      session.save();
+      session.logout();
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // remove records from ref table
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      conn.prepareStatement(
+         "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "REF WHERE PROPERTY_ID = '"
+            + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+
+      conn.commit();
+      conn.close();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
+    * Usecase when node doesn't have at least one property.
+    */
+   public void testDBUsecasesNodeHasNoPropertiesSingleDB() throws Exception
+   {
+      checkDBUsecasesNodeHasNoProperties(helper.createRepository(container, false, false));
+   }
+
+   /**
+    * Usecase when node doesn't have at least one property.
+    */
+   public void testDBUsecasesNodeHasNoPropertiesMultiDB() throws Exception
+   {
+      checkDBUsecasesNodeHasNoProperties(helper.createRepository(container, true, false));
+   }
+
+   private void checkDBUsecasesNodeHasNoProperties(ManageableRepository repository) throws Exception
+   {
+      // create repository and add node
+      SessionImpl session =
+         (SessionImpl)repository.login(credentials, repository.getConfiguration().getSystemWorkspaceName());
+      NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+      session.save();
+
+      PropertyIterator iter = node.getProperties();
+
+
+      // repository is consistent
+      checkController = new RepositoryCheckController(repository);
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
+
+      WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
+      boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
+
+      // remove all properties
+      String sourceName = wsEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+      Connection conn = ((DataSource)new InitialContext().lookup(sourceName)).getConnection();
+      while (iter.hasNext())
+      {
+         PropertyImpl prop = (PropertyImpl)iter.nextProperty();
+
+         conn.prepareStatement(
+            "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "VALUE WHERE PROPERTY_ID = '"
+               + (isMultiDb ? "" : wsEntry.getName()) + prop.getInternalIdentifier() + "'").execute();
+         conn.prepareStatement(
+            "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") + "ITEM WHERE ID = '" + (isMultiDb ? "" : wsEntry.getName())
+               + prop.getInternalIdentifier() + "'").execute();
+      }
+
+      conn.commit();
+      conn.close();
+
+      assertFalse(node.getProperties().hasNext());
+
+      session.logout();
+
+      // repository is inconsistent
+      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
+   }
+
+   /**
     * Usescase when STORAGE_DESC field in JCR_SVALUE table is not empty but there is no file in the value storage.
     */
    public void testValueStorageUsecasesSingleDb() throws Exception
    {
-      checkValueStorageUsecases(helper.createRepository(container, false));
+      checkValueStorageUsecases(helper.createRepository(container, false, false));
    }
 
    /**
@@ -149,7 +731,7 @@
     */
    public void testValueStorageUsecasesMultiDb() throws Exception
    {
-      checkValueStorageUsecases(helper.createRepository(container, true));
+      checkValueStorageUsecases(helper.createRepository(container, true, false));
    }
 
    private void checkValueStorageUsecases(ManageableRepository repository) throws Exception
@@ -166,8 +748,8 @@
 
       // repository is consistent
       checkController = new RepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryValueStorageConsistency().startsWith(
-         "Repository data is consistent"));
+      assertTrue(checkController.checkRepositoryValueStorageConsistency().startsWith("Repository data is consistent"));
+      checkController.getLastLogFile().delete();
 
       // remove the file from the value storage
       String vsPath =
@@ -179,7 +761,7 @@
       assertTrue(vsFile.delete());
 
       // repository is inconsistent
-      assertTrue(checkController .checkRepositoryValueStorageConsistency().startsWith(
-         "Repository data is inconsistent"));
+      assertTrue(checkController.checkRepositoryValueStorageConsistency().startsWith("Repository data is inconsistent"));
+      checkController.getLastLogFile().delete();
    }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestRepositoryManagement.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestRepositoryManagement.java	2011-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestRepositoryManagement.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -137,7 +137,7 @@
 
       try
       {
-         RepositoryEntry rEntry = helper.createRepositoryEntry(false, null, null);
+         RepositoryEntry rEntry = helper.createRepositoryEntry(false, null, null, true);
          rEntry.setName(repository.getConfiguration().getName());
 
          helper.createRepository(container, rEntry);

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java	2011-11-15 09:34:55 UTC (rev 5187)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java	2011-11-15 13:18:57 UTC (rev 5188)
@@ -103,18 +103,18 @@
       throws Exception
    {
       RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
-      RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, dsName);
+      RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, dsName, true);
       service.createRepository(repoEntry);
       service.getConfig().retain();
 
       return service.getRepository(repoEntry.getName());
    }
 
-   public ManageableRepository createRepository(ExoContainer container, boolean isMultiDb)
+   public ManageableRepository createRepository(ExoContainer container, boolean isMultiDb, boolean cacheEnabled)
       throws Exception
    {
       RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
-      RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, null);
+      RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, null, cacheEnabled);
       service.createRepository(repoEntry);
       service.getConfig().retain();
 
@@ -132,12 +132,13 @@
    /**
    * Create workspace entry. 
    */
-   public RepositoryEntry createRepositoryEntry(boolean isMultiDb, String systemWSName, String dsName) throws Exception
+   public RepositoryEntry createRepositoryEntry(boolean isMultiDb, String systemWSName, String dsName,
+      boolean cacheEnabled) throws Exception
    {
       // create system workspace entry
       List<String> ids = new ArrayList<String>();
       ids.add("id");
-      WorkspaceEntry wsEntry = createWorkspaceEntry(isMultiDb, dsName, ids);
+      WorkspaceEntry wsEntry = createWorkspaceEntry(isMultiDb, dsName, ids, cacheEnabled);
 
       if (systemWSName != null)
       {
@@ -164,14 +165,14 @@
       List<String> ids = new ArrayList<String>();
       ids.add("id");
 
-      return createWorkspaceEntry(isMultiDb, dsName, ids);
+      return createWorkspaceEntry(isMultiDb, dsName, ids, true);
    }
 
    /**
     * Create workspace entry. 
     */
-   public WorkspaceEntry createWorkspaceEntry(boolean isMultiDb, String dsName, List<String> valueStorageIds)
-      throws Exception
+   public WorkspaceEntry createWorkspaceEntry(boolean isMultiDb, String dsName, List<String> valueStorageIds,
+      boolean cacheEnabled) throws Exception
    {
       if (dsName == null)
       {
@@ -233,6 +234,7 @@
       cacheParams.add(new SimpleParameterEntry("maxSize", "2000"));
       cacheParams.add(new SimpleParameterEntry("liveTime", "20m"));
       CacheEntry cacheEntry = new CacheEntry(cacheParams);
+      cacheEntry.setEnabled(cacheEnabled);
       cacheEntry.setType("org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl");
 
       // Lock



More information about the exo-jcr-commits mailing list