[jbosscache-commits] JBoss Cache SVN: r7928 - in searchable/trunk/src: test/java/org/jboss/cache/search/blackbox and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Mar 19 13:06:05 EDT 2009


Author: navssurtani
Date: 2009-03-19 13:06:05 -0400 (Thu, 19 Mar 2009)
New Revision: 7928

Added:
   searchable/trunk/src/main/java/org/jboss/cache/search/NodeRemovedTransactionContext.java
   searchable/trunk/src/test/java/org/jboss/cache/search/blackbox/IndexingInTransaction.java
Modified:
   searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCoreListener.java
Log:
Added NodeRemovedTransactionContext class ... should deal with indexes not being removed when @NodeRemoved is found

Added: searchable/trunk/src/main/java/org/jboss/cache/search/NodeRemovedTransactionContext.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/NodeRemovedTransactionContext.java	                        (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/NodeRemovedTransactionContext.java	2009-03-19 17:06:05 UTC (rev 7928)
@@ -0,0 +1,52 @@
+package org.jboss.cache.search;
+
+import org.hibernate.search.backend.TransactionContext;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+
+import javax.transaction.Synchronization;
+import javax.transaction.Transaction;
+
+/**
+ * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
+ */
+public class NodeRemovedTransactionContext implements TransactionContext
+{
+
+   NodeRemovedEvent event;
+
+   public NodeRemovedTransactionContext(NodeRemovedEvent event)
+   {
+      if (event == null) throw new NullPointerException("event cannot be null");
+      this.event = event;
+   }
+
+   public boolean isTransactionInProgress()
+   {
+      return (event.getTransaction() != null);
+   }
+
+   public Object getTransactionIdentifier()
+   {
+      return event.getTransaction();
+   }
+
+   public void registerSynchronization(Synchronization synchronization)
+   {
+      if (synchronization == null) throw new NullPointerException("Synchronization passed in is null!");
+
+      Transaction transaction = event.getTransaction();
+      if (transaction != null)
+      {
+         try
+         {
+            transaction.registerSynchronization(synchronization);
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException(e);
+         }
+
+
+      }
+   }
+}

Modified: searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCoreListener.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCoreListener.java	2009-03-19 15:47:58 UTC (rev 7927)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCoreListener.java	2009-03-19 17:06:05 UTC (rev 7928)
@@ -18,7 +18,7 @@
  * 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.jboss.cache.search;
 
@@ -28,7 +28,9 @@
 import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.jboss.cache.notifications.annotation.CacheListener;
 import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
 import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -36,8 +38,8 @@
 
 /**
  * @author Navin Surtani (<a href="mailto:nsurtani at redhat.com">nsurtani at redhat.com</a>)
- *
- * Listener class for changes made to the cache. This listener makes changes if it is a {@link org.jboss.cache.Cache} being used.
+ *         <p/>
+ *         Listener class for changes made to the cache. This listener makes changes if it is a {@link org.jboss.cache.Cache} being used.
  */
 @CacheListener
 public class SearchableCoreListener
@@ -47,7 +49,7 @@
 
    public SearchableCoreListener(SearchFactoryImplementor searchFactory)
    {
-      
+
       this.searchFactory = searchFactory;
    }
 
@@ -57,7 +59,7 @@
     * @param event that has occured - or a node that has been changed. {@link org.jboss.cache.notifications.event.NodeModifiedEvent}
     * @throws InvalidKeyException if an invalid key is passed in.
     */
-   
+
    @NodeModified
    public void updateLuceneIndexes(NodeModifiedEvent event) throws InvalidKeyException
    {
@@ -80,11 +82,47 @@
       }
    }
 
-      /**
+
+   @NodeRemoved
+   protected void handleNodeRemoved(NodeRemovedEvent event) throws InvalidKeyException
+   {
+
+      if (log.isDebugEnabled()) log.debug("Entered the SCL. @NodeRemoved annotation found");
+      if (!event.isPre())
+      {
+         // Directly going to handle the deletion of data.
+         Map dataMap = event.getData();
+         if (log.isTraceEnabled()) log.trace("Called event.getData() and saved to a Map");
+
+
+         TransactionContext ctx = new NodeRemovedTransactionContext(event);
+
+         for (Object key : dataMap.keySet())
+         {
+            CacheEntityId cacheEntityId = new CacheEntityId(event.getFqn(), (String) key);
+            if (log.isTraceEnabled()) log.trace("Created new CacheEntityId");
+
+            String fqnString = cacheEntityId.getFqn().toString();  // Vars for logging
+            String keyString = (String) key;
+
+
+            searchFactory.getWorker().performWork(new Work(dataMap.get(key), cacheEntityId.getDocumentId(), WorkType.DELETE), ctx);
+            searchFactory.getWorker().performWork(new Work(dataMap.get(key), cacheEntityId.getDocumentId(), WorkType.ADD), ctx);
+
+
+            if (log.isTraceEnabled())
+            {
+               log.debug("Added your object into Lucene with Fqn " + fqnString + " and key " + keyString);
+            }
+         }
+      }
+   }
+
+   /**
     * If the modification type is PUT_MAP or PUT_DATA then this method will be called.
     * Takes in the event as a parameter
     *
-    * @param event that has occured - or a node that has been changed. {@link org.jboss.cache.notifications.event.NodeModifiedEvent}
+    * @param event         that has occured - or a node that has been changed. {@link org.jboss.cache.notifications.event.NodeModifiedEvent}
     * @param searchFactory - a SearchFactoryImpl instance.
     * @throws InvalidKeyException
     */
@@ -122,12 +160,11 @@
    }
 
 
-
    /**
     * If the modification type is DELETE_DATA then this method will be called.
     * Takes in the event as a parameter
     *
-    * @param event that has occured - or a node that has been changed. {@link org.jboss.cache.notifications.event.NodeModifiedEvent}
+    * @param event         that has occured - or a node that has been changed. {@link org.jboss.cache.notifications.event.NodeModifiedEvent}
     * @param searchFactory - a SearchFactoryImpl instance.
     * @throws InvalidKeyException
     */
@@ -146,7 +183,8 @@
 
 
          searchFactory.getWorker().performWork(new Work(dataMap.get(key), cacheEntityId.getDocumentId(), WorkType.DELETE), ctx);
-         if (log.isTraceEnabled()) log.trace("Deleted your object from Lucene with Fqn " + fqnString + " and key " + keyString);
+         if (log.isTraceEnabled())
+            log.trace("Deleted your object from Lucene with Fqn " + fqnString + " and key " + keyString);
 
 
       }

Added: searchable/trunk/src/test/java/org/jboss/cache/search/blackbox/IndexingInTransaction.java
===================================================================
--- searchable/trunk/src/test/java/org/jboss/cache/search/blackbox/IndexingInTransaction.java	                        (rev 0)
+++ searchable/trunk/src/test/java/org/jboss/cache/search/blackbox/IndexingInTransaction.java	2009-03-19 17:06:05 UTC (rev 7928)
@@ -0,0 +1,194 @@
+package org.jboss.cache.search.blackbox;
+
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.ProvidedId;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+import org.jboss.cache.*;
+import org.jboss.cache.loader.jdbm.JdbmCacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.search.SearchableCacheFactory;
+import org.jboss.cache.search.SearchableCache;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.index.Term;
+
+import static org.testng.AssertJUnit.*;
+
+import java.util.Properties;
+import java.util.List;
+import java.io.Serializable;
+
+ at Test(groups = {"unit"}, sequential = true)
+public class IndexingInTransaction
+{
+
+   private static final Fqn fname = Fqn.fromString("blah");
+
+   private Cache coreCache;
+
+   private SearchableCache searchableCache;
+
+   Node node;
+
+   public IndexingInTransaction()
+   {
+      init();
+   }
+
+   @BeforeMethod
+   public void init()
+   {
+      CacheFactory factory = new DefaultCacheFactory();
+      Configuration c = new Configuration();
+      c.setInvocationBatchingEnabled(true);
+
+      CacheLoaderConfig clc = new CacheLoaderConfig();
+
+      JdbmCacheLoaderConfig jclc = new JdbmCacheLoaderConfig();
+      jclc.setAsync(false);
+      jclc.setFetchPersistentState(false);
+      jclc.setIgnoreModifications(false);
+      jclc.setPurgeOnStartup(true);
+      jclc.setLocation("/tmp/c1");
+
+      clc.addIndividualCacheLoaderConfig(jclc);
+      c.setCacheLoaderConfig(clc);
+
+      coreCache = factory.createCache(c, false);
+
+      SearchableCacheFactory f = new SearchableCacheFactory();
+      Properties p = new Properties();
+      p.put("hibernate.search.default.indexBase", "/tmp/c1idx");
+      p.put("hibernate.search.worker.batch_size", "1");
+      searchableCache = f.createSearchableCache(coreCache, p, Entity.class);
+      searchableCache.create();
+      searchableCache.start();
+      node = searchableCache.getRoot().addChild(fname);
+   }
+
+   @Test
+   public void testPutEntitiesWithoutTransaction()
+   {
+      for (int i = 1; i <= 10; i++)
+      {
+         Entity e = getEntity(i);
+         System.out.println("caching: " + e);
+         Node c = node.addChild(Fqn.fromString(e.getName()));
+         c.put("" + e.getId(), e);
+      }
+      assertFalse(searchableCache.createQuery(
+              Entity.searchByName("Name5")).list().isEmpty());
+   }
+
+   @Test
+   public void testPutEntitiesWithTransaction() throws Exception
+   {
+      ((CacheSPI) (coreCache)).getTransactionManager().begin();
+      for (int i = 15; i <= 15; i++)
+      {
+         Entity e = getEntity(i);
+         System.out.println("caching: " + e);
+         Node c = node.addChild(Fqn.fromString(e.getName()));
+         c.put("" + e.getId(), e);
+      }
+      ((CacheSPI) (coreCache)).getTransactionManager().commit();
+
+      assertFalse("there should be record for the name15",
+              searchableCache.createQuery(
+                      Entity.searchByName("Name15")).list().isEmpty());
+
+      node.removeChild(Fqn.fromString("Name15"));
+
+      List l = searchableCache.createQuery(Entity.searchByName("Name15")).list();
+
+      // bug: collection is not empty - there is null as there are inconsistencies in the indexes
+      assertTrue("there should be no record found", l.isEmpty());
+
+   }
+
+   Entity getEntity(long id)
+   {
+      return new Entity(id, "Name" + id, "Surname" + id, true);
+   }
+
+//    public static void main(String[] args) {
+//        IndexingInTransaction stb = new IndexingInTransaction();
+//        stb.init();
+//    }
+
+}
+
+ at ProvidedId
+ at Indexed
+class Entity implements Serializable
+{
+
+   public static final String IDX_NAME = "name";
+   public static final String IDX_SURNAME = "surname";
+
+   private long id;
+
+   @Field(store = Store.YES)
+   private String name;
+
+   @Field(store = Store.YES)
+   private String surname;
+
+   private boolean dead;
+
+   Entity(long id, String name, String surname, boolean dead)
+   {
+      this.id = id;
+      this.name = name;
+      this.surname = surname;
+      this.dead = dead;
+   }
+
+   public long getId()
+   {
+      return id;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   public String getSurname()
+   {
+      return surname;
+   }
+
+   public boolean isDead()
+   {
+      return dead;
+   }
+
+   public static Query searchByName(String name)
+   {
+      BooleanQuery query = new BooleanQuery();
+      query.add(new TermQuery(
+              new Term(Entity.IDX_NAME,
+                      name.toLowerCase())),
+              BooleanClause.Occur.MUST);
+      return query;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "Entity{" +
+              "id=" + id +
+              ", name='" + name + '\'' +
+              ", surname='" + surname + '\'' +
+              ", dead=" + dead +
+              '}';
+   }
+
+}
\ No newline at end of file




More information about the jbosscache-commits mailing list