You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by as...@apache.org on 2015/11/11 22:24:06 UTC

[34/50] [abbrv] incubator-geode git commit: Adding a new CacheService extension point to GemFireCache

Adding a new CacheService extension point to GemFireCache

I had previously modified the existing Extension mechanism on this
branch to be able to fetch Extensions by key.

However, after digging more, I think those Extensions are mostly just
useful for Xml parsing since they have callbacks specific to
transitioning an object from a *Creation to a real object. In addition,
I was worried the changes I made would break existing extensions. So I
have rolled back those changes.

Instead of that, I've added the concept of a CacheService, which is
loaded by the ServiceLoader during cache initialization and has the same
lifecycle as the cache. Services can be retrieved using
GemfireCacheImpl.getService(SomeService.class).

I've used this new mechanism to install the LuceneService. This is
currently only an internal service, but we may want to make this public,
eg

Cache.getService(SomeService.class)


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/5d7535a7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/5d7535a7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/5d7535a7

Branch: refs/heads/develop
Commit: 5d7535a7c0eb4126d017a26362ae479ed3d050c0
Parents: 0f78330
Author: Dan Smith <up...@apache.org>
Authored: Thu Oct 15 15:38:59 2015 -0700
Committer: Dan Smith <up...@apache.org>
Committed: Fri Oct 16 12:46:55 2015 -0700

----------------------------------------------------------------------
 .../gemfire/internal/cache/CacheService.java    | 26 ++++++++++++
 .../internal/cache/GemFireCacheImpl.java        | 22 ++++++++++
 .../gemfire/internal/cache/InternalCache.java   |  2 +
 .../cache/extension/ExtensionPoint.java         | 12 +-----
 .../cache/extension/SimpleExtensionPoint.java   | 25 +++++-------
 .../internal/cache/xmlcache/CacheCreation.java  |  6 ++-
 .../gemfire/cache30/CacheXml81DUnitTest.java    |  6 +--
 .../internal/cache/CacheServiceJUnitTest.java   | 43 ++++++++++++++++++++
 .../internal/cache/MockCacheService.java        |  8 ++++
 .../internal/cache/MockCacheServiceImpl.java    | 23 +++++++++++
 .../SimpleExtensionPointJUnitTest.java          | 20 ++++-----
 .../mock/DestroyMockCacheExtensionFunction.java |  9 +++-
 .../extension/mock/MockCacheExtension.java      |  2 +-
 .../extension/mock/MockExtensionXmlParser.java  |  4 +-
 .../extension/mock/MockRegionExtension.java     |  2 +-
 ...gemstone.gemfire.internal.cache.CacheService |  1 +
 .../cache/lucene/LuceneServiceProvider.java     | 15 ++-----
 .../lucene/internal/InternalLuceneService.java  |  3 +-
 .../cache/lucene/internal/LuceneIndexImpl.java  |  2 +-
 .../lucene/internal/LuceneServiceImpl.java      | 13 +++++-
 .../internal/xml/LuceneIndexCreation.java       |  2 +-
 .../lucene/internal/xml/LuceneXmlParser.java    |  2 +-
 ...gemstone.gemfire.internal.cache.CacheService |  1 +
 .../internal/LuceneServiceImplJUnitTest.java    |  2 +-
 .../distributed/LuceneFunctionJUnitTest.java    |  4 +-
 25 files changed, 187 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheService.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheService.java
new file mode 100644
index 0000000..e26602d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/CacheService.java
@@ -0,0 +1,26 @@
+package com.gemstone.gemfire.internal.cache;
+
+import com.gemstone.gemfire.cache.Cache;
+
+/**
+ * Interface for a service that is linked to a cache.
+ * 
+ * These services are loaded during cache initialization using the java
+ * ServiceLoader and can be retrieved from the cache by calling
+ * Cache.getService(YourInterface.class)
+ */
+public interface CacheService {
+  /**
+   * Initialize the service with a cache.
+   * 
+   * Services are initialized in random order, fairly early on in cache
+   * initialization. In particular, the cache.xml has not yet been parsed.
+   */
+  public void init(Cache cache);
+
+  /**
+   * Return the class or interface used to look up
+   * this service. 
+   */
+  public Class<? extends CacheService> getInterface();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
index e73af49..2cce156 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
@@ -39,6 +39,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
+import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -592,6 +593,8 @@ public class GemFireCacheImpl implements InternalCache, ClientCache, HasCachePer
   
   private final Set<RegionListener> regionListeners = new ConcurrentHashSet<RegionListener>();
   
+  private final Map<Class<? extends CacheService>, CacheService> services = new HashMap<Class<? extends CacheService>, CacheService>();
+  
   public static final int DEFAULT_CLIENT_FUNCTION_TIMEOUT = 0;
 
   private static int clientFunctionTimeout;
@@ -1126,6 +1129,8 @@ public class GemFireCacheImpl implements InternalCache, ClientCache, HasCachePer
     
     boolean completedCacheXml = false;
     
+    initializeServices();
+    
     try {
       //Deploy all the jars from the deploy working dir.
       new JarDeployer(this.system.getConfig().getDeployWorkingDir()).loadPreviouslyDeployedJars();
@@ -1160,6 +1165,18 @@ public class GemFireCacheImpl implements InternalCache, ClientCache, HasCachePer
 
     return this;
   }
+
+  /**
+   * Initialize any services that provided as extensions to the cache using the
+   * service loader mechanism.
+   */
+  private void initializeServices() {
+    ServiceLoader<CacheService> loader = ServiceLoader.load(CacheService.class);
+    for(CacheService service : loader) {
+      service.init(this);
+      this.services.put(service.getInterface(), service);
+    }
+  }
   
   private boolean isNotJmxManager(){
     return (this.system.getConfig().getJmxManagerStart() != true);
@@ -3740,6 +3757,11 @@ public class GemFireCacheImpl implements InternalCache, ClientCache, HasCachePer
   public void removeRegionListener(RegionListener l ) {
     this.regionListeners.remove(l);
   }
+  
+  @SuppressWarnings("unchecked")
+  public <T extends CacheService> T getService(Class<T> clazz) {
+    return (T) services.get(clazz);
+  }
 
   /**
    * Creates the single instance of the Transation Manager for this cache. Returns the existing one upon request.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/InternalCache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/InternalCache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/InternalCache.java
index cf1a4dc..403e1ce 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/InternalCache.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/InternalCache.java
@@ -37,4 +37,6 @@ public interface InternalCache extends Cache, Extensible<Cache> {
   public CqService getCqService();
   
   public Collection<HDFSStoreImpl> getHDFSStores() ;
+  
+  public <T extends CacheService> T getService(Class<T> clazz);
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/ExtensionPoint.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/ExtensionPoint.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/ExtensionPoint.java
index dedc50f..8022be5 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/ExtensionPoint.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/ExtensionPoint.java
@@ -24,15 +24,7 @@ public interface ExtensionPoint<T> {
    *          to add.
    * @since 8.1
    */
-  void addExtension(Object key, Extension<T> extension);
-  
-  /**
-   * Retrieve an {@link Extension} by key
-   * 
-   * @param key key to retrieve 
-   * @since 9.0
-   */
-  Extension<T> getExtension(Object key);
+  void addExtension(Extension<T> extension);
 
   /**
    * Remove {@link Extension} from {@link ExtensionPoint}.
@@ -41,7 +33,7 @@ public interface ExtensionPoint<T> {
    *          to remove.
    * @since 8.1
    */
-  void removeExtension(Object key);
+  void removeExtension(Extension<T> extension);
 
   /**
    * Get {@link Iterable} of {@link Extension}s.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPoint.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPoint.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPoint.java
index 06e855f..66fb8f3 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPoint.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPoint.java
@@ -8,9 +8,9 @@
 
 package com.gemstone.gemfire.internal.cache.extension;
 
-import java.util.Map;
+import java.util.ArrayList;
 
-import com.gemstone.gemfire.internal.util.concurrent.CopyOnWriteHashMap;
+import com.gemstone.gemfire.internal.util.CollectionUtils;
 
 /**
  * Simple implementation of {@link ExtensionPoint} for easy integration with
@@ -23,7 +23,9 @@ import com.gemstone.gemfire.internal.util.concurrent.CopyOnWriteHashMap;
 // UnitTest SimpleExtensionPointJUnitTest
 public class SimpleExtensionPoint<T> implements ExtensionPoint<T> {
 
-  protected final Map<Object, Extension<T>> extensions = new CopyOnWriteHashMap<Object, Extension<T>>();
+  protected final ArrayList<Extension<T>> extensions = new ArrayList<Extension<T>>();
+
+  protected final Iterable<Extension<T>> iterable = CollectionUtils.unmodifiableIterable(extensions);
 
   protected final Extensible<T> extensible;
 
@@ -48,22 +50,17 @@ public class SimpleExtensionPoint<T> implements ExtensionPoint<T> {
 
   @Override
   public Iterable<Extension<T>> getExtensions() {
-    return extensions.values();
-  }
-
-  @Override
-  public void addExtension(Object key, Extension<T> extension) {
-    extensions.put(key, extension);
+    return iterable;
   }
 
   @Override
-  public Extension<T> getExtension(Object key) {
-    return extensions.get(key);
+  public void addExtension(Extension<T> extension) {
+    extensions.add(extension);
   }
   
   @Override
-  public void removeExtension(Object key) {
-    extensions.remove(key);
+  public void removeExtension(Extension<T> extension) {
+    extensions.remove(extension);
   }
 
   @Override
@@ -72,7 +69,7 @@ public class SimpleExtensionPoint<T> implements ExtensionPoint<T> {
   }
 
   public void fireCreate(final Extensible<T> newTarget) {
-    for (final Extension<T> extension : getExtensions()) {
+    for (final Extension<T> extension : extensions) {
       extension.onCreate(extensible, newTarget);
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
index 31de4e9..c0278cc 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/xmlcache/CacheCreation.java
@@ -91,6 +91,7 @@ import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreImpl;
 import com.gemstone.gemfire.internal.cache.CacheServerImpl;
 import com.gemstone.gemfire.internal.cache.CacheConfig;
 import com.gemstone.gemfire.internal.cache.CacheServerLauncher;
+import com.gemstone.gemfire.internal.cache.CacheService;
 import com.gemstone.gemfire.internal.cache.DiskStoreFactoryImpl;
 import com.gemstone.gemfire.internal.cache.DiskStoreImpl;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
@@ -1652,6 +1653,9 @@ public class CacheCreation implements InternalCache {
     }
     
   };
-	  
 
+  @Override
+  public <T extends CacheService> T getService(Class<T> clazz) {
+    throw new UnsupportedOperationException();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/CacheXml81DUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/CacheXml81DUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/CacheXml81DUnitTest.java
index 54f1208..f1cc1f9 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/CacheXml81DUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/CacheXml81DUnitTest.java
@@ -56,7 +56,7 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
   public void testCacheExtension() {
     final CacheCreation cache = new CacheCreation();
     final MockCacheExtension extension = new MockCacheExtension("testCacheExtension");
-    cache.getExtensionPoint().addExtension(MockCacheExtension.class, extension);
+    cache.getExtensionPoint().addExtension(extension);
 
     assertEquals(0, extension.onCreateCounter.get());
     assertEquals(0, extension.getXmlGeneratorCounter.get());
@@ -91,7 +91,7 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
     Extensible<Region<?, ?>> region = (Extensible<Region<?, ?>>) cache.createRegion(regionName, attrs);
 
     final MockRegionExtension extension = new MockRegionExtension("test");
-    region.getExtensionPoint().addExtension(MockRegionExtension.class, extension);
+    region.getExtensionPoint().addExtension(extension);
 
     assertEquals(0, extension.onCreateCounter.get());
     assertEquals(0, extension.getXmlGeneratorCounter.get());
@@ -127,7 +127,7 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
     Extensible<Region<?, ?>> region = (Extensible<Region<?, ?>>) cache.createRegion(regionName, attrs);
 
     final MockRegionExtension extension = new MockRegionExtension("exception");
-    region.getExtensionPoint().addExtension(MockRegionExtension.class, extension);
+    region.getExtensionPoint().addExtension(extension);
 
     assertEquals(0, extension.onCreateCounter.get());
     assertEquals(0, extension.getXmlGeneratorCounter.get());

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/CacheServiceJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/CacheServiceJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/CacheServiceJUnitTest.java
new file mode 100644
index 0000000..b3bcc93
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/CacheServiceJUnitTest.java
@@ -0,0 +1,43 @@
+package com.gemstone.gemfire.internal.cache;
+
+import static org.junit.Assert.*;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class CacheServiceJUnitTest {
+  
+  private GemFireCacheImpl cache;
+
+  @Before
+  public void setUp() {
+    cache = (GemFireCacheImpl) new CacheFactory().set("mcast-port", "0").create();
+  }
+  
+  @After
+  public void tearDown() {
+    if(cache != null) {
+      cache.close();
+    }
+  }
+
+  @Test
+  public void test() {
+    MockCacheService service = cache.getService(MockCacheService.class);
+    assertEquals(cache, service.getCache());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheService.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheService.java
new file mode 100644
index 0000000..6eb1c37
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheService.java
@@ -0,0 +1,8 @@
+package com.gemstone.gemfire.internal.cache;
+
+import com.gemstone.gemfire.cache.Cache;
+
+public interface MockCacheService extends CacheService {
+  
+  public Cache getCache();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheServiceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheServiceImpl.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheServiceImpl.java
new file mode 100644
index 0000000..58b256d
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/MockCacheServiceImpl.java
@@ -0,0 +1,23 @@
+package com.gemstone.gemfire.internal.cache;
+
+import com.gemstone.gemfire.cache.Cache;
+
+public class MockCacheServiceImpl implements MockCacheService {
+  
+  private Cache cache;
+
+  @Override
+  public void init(Cache cache) {
+    this.cache = cache;
+  }
+
+  @Override
+  public Class<? extends CacheService> getInterface() {
+    return MockCacheService.class;
+  }
+
+  @Override
+  public Cache getCache() {
+    return cache;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPointJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPointJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPointJUnitTest.java
index 35bb7ef..2899669 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPointJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/SimpleExtensionPointJUnitTest.java
@@ -7,11 +7,7 @@
  */
 package com.gemstone.gemfire.internal.cache.extension;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
@@ -42,7 +38,7 @@ public class SimpleExtensionPointJUnitTest {
     final MockImpl m = new MockImpl();
     assertSame(m.extensionPoint.extensible, m.extensionPoint.target);
     assertNotNull(m.extensionPoint.extensions);
-    assertNotNull(m.extensionPoint.extensions);
+    assertNotNull(m.extensionPoint.iterable);
   }
 
   /**
@@ -53,7 +49,7 @@ public class SimpleExtensionPointJUnitTest {
     final MockImpl m = new MockImpl();
 
     assertEquals(0, m.extensionPoint.extensions.size());
-    assertTrue(!m.extensionPoint.extensions.values().iterator().hasNext());
+    assertTrue(!m.extensionPoint.iterable.iterator().hasNext());
 
     final Iterable<Extension<MockInterface>> extensions = m.getExtensionPoint().getExtensions();
     assertNotNull(extensions);
@@ -77,7 +73,7 @@ public class SimpleExtensionPointJUnitTest {
     final MockImpl m = new MockImpl();
     final MockExtension extension = new MockExtension();
 
-    m.getExtensionPoint().addExtension(MockExtension.class, extension);
+    m.getExtensionPoint().addExtension(extension);
     assertEquals(1, m.extensionPoint.extensions.size());
 
     final Iterable<Extension<MockInterface>> extensions = m.getExtensionPoint().getExtensions();
@@ -105,7 +101,7 @@ public class SimpleExtensionPointJUnitTest {
   public void testRemoveExtension() {
     final MockImpl m = new MockImpl();
     final MockExtension extension = new MockExtension();
-    m.getExtensionPoint().addExtension(MockExtension.class, extension);
+    m.getExtensionPoint().addExtension(extension);
 
     final Iterable<Extension<MockInterface>> extensions = m.getExtensionPoint().getExtensions();
     assertNotNull(extensions);
@@ -124,7 +120,7 @@ public class SimpleExtensionPointJUnitTest {
       // ignore
     }
 
-    m.getExtensionPoint().removeExtension(MockExtension.class);
+    m.getExtensionPoint().removeExtension(extension);
     assertEquals(0, m.extensionPoint.extensions.size());
 
     // extensions should be empty
@@ -163,13 +159,13 @@ public class SimpleExtensionPointJUnitTest {
     };
 
     counter.set(0);
-    m.getExtensionPoint().addExtension(MockExtension.class, extension);
+    m.getExtensionPoint().addExtension(extension);
     // fire with itself as the target
     m.extensionPoint.fireCreate(m);
     assertEquals(1, counter.get());
 
     counter.set(0);
-    m.getExtensionPoint().removeExtension(MockExtension.class);
+    m.getExtensionPoint().removeExtension(extension);
     // fire with itself as the target
     m.extensionPoint.fireCreate(m);
     assertEquals(0, counter.get());

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
index 29b6acb..61db465 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
@@ -48,7 +48,12 @@ public class DestroyMockCacheExtensionFunction extends FunctionAdapter {
 
     @SuppressWarnings("unchecked")
     final Extensible<Cache> extensible = (Extensible<Cache>) cache;
-    extensible.getExtensionPoint().removeExtension(MockCacheExtension.class);
+    for (Extension<Cache> extension : extensible.getExtensionPoint().getExtensions()) {
+      if (extension instanceof MockCacheExtension) {
+        extensible.getExtensionPoint().removeExtension(extension);
+        break;
+      }
+    }
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE).build();
 
@@ -72,4 +77,4 @@ public class DestroyMockCacheExtensionFunction extends FunctionAdapter {
   public static Object[] toArgs(final String value) {
     return new Object[] { value };
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockCacheExtension.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockCacheExtension.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockCacheExtension.java
index b5b9e65..b37a9cf 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockCacheExtension.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockCacheExtension.java
@@ -33,7 +33,7 @@ public final class MockCacheExtension extends AbstractMockExtension<Cache> {
   @Override
   public void onCreate(Extensible<Cache> source, Extensible<Cache> target) {
     super.onCreate(source, target);
-    target.getExtensionPoint().addExtension(MockCacheExtension.class, this);
+    target.getExtensionPoint().addExtension(this);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockExtensionXmlParser.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockExtensionXmlParser.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockExtensionXmlParser.java
index cf9a2ec..6e9b529 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockExtensionXmlParser.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockExtensionXmlParser.java
@@ -76,13 +76,13 @@ public class MockExtensionXmlParser extends AbstractXmlParser {
     case ELEMENT_CACHE: {
       MockCacheExtension extension = (MockCacheExtension) stack.pop();
       CacheCreation cache = (CacheCreation) stack.peek();
-      cache.getExtensionPoint().addExtension(MockCacheExtension.class, extension);
+      cache.getExtensionPoint().addExtension(extension);
       break;
     }
     case ELEMENT_REGION: {
       MockRegionExtension extension = (MockRegionExtension) stack.pop();
       RegionCreation region = (RegionCreation) stack.peek();
-      region.getExtensionPoint().addExtension(MockRegionExtension.class, extension);
+      region.getExtensionPoint().addExtension(extension);
       break;
     }
     default:

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockRegionExtension.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockRegionExtension.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockRegionExtension.java
index 571b5a1..a5d2ce0 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockRegionExtension.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/extension/mock/MockRegionExtension.java
@@ -27,7 +27,7 @@ public final class MockRegionExtension extends AbstractMockExtension<Region<?, ?
   @Override
   public void onCreate(Extensible<Region<?, ?>> source, Extensible<Region<?, ?>> target) {
     super.onCreate(source, target);
-    target.getExtensionPoint().addExtension(MockRegionExtension.class, this);
+    target.getExtensionPoint().addExtension(this);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-core/src/test/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService b/gemfire-core/src/test/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
new file mode 100644
index 0000000..4573990
--- /dev/null
+++ b/gemfire-core/src/test/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
@@ -0,0 +1 @@
+com.gemstone.gemfire.internal.cache.MockCacheServiceImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneServiceProvider.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneServiceProvider.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneServiceProvider.java
index 7d90b7d..35427ae 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneServiceProvider.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneServiceProvider.java
@@ -2,8 +2,7 @@ package com.gemstone.gemfire.cache.lucene;
 
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneService;
-import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl;
-import com.gemstone.gemfire.internal.cache.extension.Extensible;
+import com.gemstone.gemfire.internal.cache.InternalCache;
 
 /**
  * Class for retrieving or creating the currently running
@@ -16,16 +15,8 @@ public class LuceneServiceProvider {
    * Retrieve or create the lucene service for this cache
    */
   public static LuceneService get(Cache cache) {
-    synchronized(LuceneService.class) {
-      Extensible<Cache> extensible = (Extensible<Cache>) cache;
-      InternalLuceneService service = (InternalLuceneService) extensible.getExtensionPoint().getExtension(LuceneService.class);
-      if(service == null) {
-        service = new LuceneServiceImpl(cache);
-        extensible.getExtensionPoint().addExtension(LuceneService.class, service);
-      }
-      
-      return service;
-    }
+    InternalCache internalCache = (InternalCache) cache;
+    return internalCache.getService(InternalLuceneService.class);
   }
   
   private LuceneServiceProvider() {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/InternalLuceneService.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/InternalLuceneService.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/InternalLuceneService.java
index d09ef19..cd78c2c 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/InternalLuceneService.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/InternalLuceneService.java
@@ -2,8 +2,9 @@ package com.gemstone.gemfire.cache.lucene.internal;
 
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.lucene.LuceneService;
+import com.gemstone.gemfire.internal.cache.CacheService;
 import com.gemstone.gemfire.internal.cache.extension.Extension;
 
-public interface InternalLuceneService extends LuceneService, Extension<Cache> {
+public interface InternalLuceneService extends LuceneService, Extension<Cache>, CacheService {
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java
index 257861b..c8d4bb6 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java
@@ -88,6 +88,6 @@ public abstract class LuceneIndexImpl implements InternalLuceneIndex {
     creation.addFieldNames(this.getFieldNames());
     creation.setRegion(dataRegion);
     creation.setFieldFieldAnalyzerMap(this.getFieldAnalyzerMap());
-    dataRegion.getExtensionPoint().addExtension(creation, creation);
+    dataRegion.getExtensionPoint().addExtension(creation);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
index c4a2047..5efe300 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
@@ -27,6 +27,7 @@ import com.gemstone.gemfire.cache.lucene.internal.filesystem.File;
 import com.gemstone.gemfire.cache.lucene.internal.xml.LuceneServiceXmlGenerator;
 import com.gemstone.gemfire.internal.DSFIDFactory;
 import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.cache.CacheService;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 import com.gemstone.gemfire.internal.cache.InternalRegionArguments;
 import com.gemstone.gemfire.internal.cache.PartitionedRegion;
@@ -46,11 +47,14 @@ import com.gemstone.gemfire.internal.logging.LogService;
 public class LuceneServiceImpl implements InternalLuceneService {
   private static final Logger logger = LogService.getLogger();
   
-  private final GemFireCacheImpl cache;
+  private GemFireCacheImpl cache;
   private final HashMap<String, LuceneIndex> indexMap = new HashMap<String, LuceneIndex>();;
   
+  public LuceneServiceImpl() {
+    
+  }
 
-  public LuceneServiceImpl(final Cache cache) {
+  public void init(final Cache cache) {
     if (cache == null) {
       throw new IllegalStateException(LocalizedStrings.CqService_CACHE_IS_NULL.toLocalizedString());
     }
@@ -63,6 +67,11 @@ public class LuceneServiceImpl implements InternalLuceneService {
     registerDataSerializables();
   }
   
+  @Override
+  public Class<? extends CacheService> getInterface() {
+    return InternalLuceneService.class;
+  }
+
   public static String getUniqueIndexName(String indexName, String regionPath) {
     if (!regionPath.startsWith("/")) {
       regionPath = "/"+regionPath;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
index 02ecd8f..3609ae8 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
@@ -68,7 +68,7 @@ public class LuceneIndexCreation implements LuceneIndex, Extension<Region<?, ?>>
   @Override
   public void onCreate(Extensible<Region<?, ?>> source,
       Extensible<Region<?, ?>> target) {
-    target.getExtensionPoint().addExtension(LuceneIndex.class, this);
+    target.getExtensionPoint().addExtension(this);
     Cache cache = target.getExtensionPoint().getTarget().getCache();
     LuceneServiceImpl service = (LuceneServiceImpl) LuceneServiceProvider.get(cache);
     Region region = target.getExtensionPoint().getTarget();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
index e11814a..25aac41 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
@@ -51,7 +51,7 @@ public class LuceneXmlParser extends AbstractXmlParser {
     LuceneIndexCreation indexCreation = new LuceneIndexCreation();
     indexCreation.setName(name);
     indexCreation.setRegion(region);
-    region.getExtensionPoint().addExtension(indexCreation, indexCreation);
+    region.getExtensionPoint().addExtension(indexCreation);
     stack.push(indexCreation);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService b/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
new file mode 100644
index 0000000..bd05ef7
--- /dev/null
+++ b/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.CacheService
@@ -0,0 +1 @@
+com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImplJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImplJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImplJUnitTest.java
index 26487a0..0cfd989 100644
--- a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImplJUnitTest.java
+++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImplJUnitTest.java
@@ -55,7 +55,7 @@ public class LuceneServiceImplJUnitTest {
     assertNull(function);
 
     cache = createBasicCache();
-    new LuceneServiceImpl(cache);
+    new LuceneServiceImpl().init(cache);
 
     function = FunctionService.getFunction(LuceneFunction.ID);
     assertNotNull(function);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5d7535a7/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java
index 6c37468..431ed4c 100644
--- a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java
+++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java
@@ -387,9 +387,7 @@ public class LuceneFunctionJUnitTest {
       will(returnValue(mockCache));
       allowing(mockRegion).getFullPath();
       will(returnValue(regionPath));
-      allowing(mockCache).getExtensionPoint();
-      will(returnValue(mockExtensionPoint));
-      allowing(mockExtensionPoint).getExtension(LuceneService.class);
+      allowing(mockCache).getService(InternalLuceneService.class);
       will(returnValue(mockService));
       allowing(mockService).getIndex(with("indexName"), with(regionPath));
       will(returnValue(mockIndex));