You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2010/01/19 13:38:22 UTC

svn commit: r900753 - in /incubator/aries/trunk/jpa/jpa-container-context/src: main/java/org/apache/aries/jpa/container/context/impl/ test/java/org/apache/aries/jpa/container/context/namespace/

Author: timothyjward
Date: Tue Jan 19 12:38:22 2010
New Revision: 900753

URL: http://svn.apache.org/viewvc?rev=900753&view=rev
Log:
ARIES-118 : Add support for container managed persistence contexts

Added:
    incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/PersistenceContextManagerTest.java
Modified:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java?rev=900753&r1=900752&r2=900753&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java Tue Jan 19 12:38:22 2010
@@ -90,13 +90,15 @@
   public Object addingService(ServiceReference reference) {
 
     String unitName = (String) reference.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME);
+    if(unitName == null)
+      unitName = "";
     boolean register;
     //Use a synchronized block to ensure that we get an atomic view of the persistenceUnits
     //and the persistenceContextDefinitions
     synchronized (this) {
       //If we already track a unit with the same name then we are in trouble!
       //only one unit with a given name should exist at a single scope
-      if(!!!persistenceUnits.containsKey(unitName)) {
+      if(persistenceUnits.containsKey(unitName)) {
         //TODO log a big warning here!
         //Stop tracking the duplicate unit.
         return null;
@@ -115,7 +117,9 @@
 
   public void removedService(ServiceReference ref, Object o)
   {
-    String unitName = (String) ref.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME);;
+    String unitName = (String) ref.getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME);
+    if(unitName == null)
+      unitName = "";
     //Remove the persistence Unit service to prevent other people from trying to use it
     synchronized (this) {
       persistenceUnits.remove(unitName);
@@ -152,6 +156,7 @@
       if(oldProps != null) {
         if(!!!oldProps.equals(properties)) {
           //TODO log an error and use the old properties
+          persistenceContextDefinitions.put(name, oldProps);
         }
       }
       //We should only register if our persistence unit exists
@@ -199,13 +204,16 @@
     ServiceFactory entityManagerServiceFactory;
     ServiceReference unit;
     ServiceRegistration reg = null;
+    boolean alreadyRegistered = false;
     try
     {
       //Synchronize for an atomic view
       synchronized (this) {
         //Not our job to register if someone is already doing it, or has already done it
-        if(entityManagerRegistrations.containsKey(name))
+        if(entityManagerRegistrations.containsKey(name)){
+          alreadyRegistered = true;
           return;
+        }
         //Block other threads from trying to register by adding the key
         entityManagerRegistrations.put(name, null);
         
@@ -244,19 +252,21 @@
         //If we created a registration
         if(reg != null) {
           //If the key still exists then all is well
-          if(entityManagerRegistrations.containsKey(name))
+          if(entityManagerRegistrations.containsKey(name)) {
             entityManagerRegistrations.put(name, reg);
           //Else we were in a potential live-lock and the service could not be unregistered
           //earlier. This means we have to do it (but outside the synchronized. Make sure we
           //also remove the registration key!
-          else {
+          } else {
             entityManagerRegistrations.remove(name);
             recoverFromLiveLock = true;
           }
         }
-        //There was no registration created. Remove the key.
-        else
-          entityManagerRegistrations.remove(name);
+        //There was no registration created. Remove the key if we were registering.
+        else {
+          if(!!!alreadyRegistered)
+            entityManagerRegistrations.remove(name);
+        }
         
         //Notify any waiting unregistrations that they can proceed
         this.notifyAll();

Added: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/PersistenceContextManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/PersistenceContextManagerTest.java?rev=900753&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/PersistenceContextManagerTest.java (added)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/PersistenceContextManagerTest.java Tue Jan 19 12:38:22 2010
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.jpa.container.context.namespace;
+
+import static java.lang.Boolean.TRUE;
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.impl.PersistenceContextManager;
+import org.apache.aries.mocks.BundleContextMock;
+import org.apache.aries.mocks.BundleMock;
+import org.apache.aries.unittest.mocks.Skeleton;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+
+public class PersistenceContextManagerTest {
+
+  private BundleContext context;
+  private PersistenceContextManager mgr;
+  
+  private EntityManagerFactory emf1;
+  private EntityManagerFactory emf2;
+  
+  private ServiceRegistration reg1;
+  private ServiceRegistration reg2;
+  
+  private Bundle client1;
+  private Bundle client2;
+  
+  @Before
+  public void setUp()
+  {
+    client1 = Skeleton.newMock(Bundle.class);
+    client2 = Skeleton.newMock(Bundle.class);
+    emf1 = Skeleton.newMock(EntityManagerFactory.class);
+    emf2 = Skeleton.newMock(EntityManagerFactory.class);
+    context = Skeleton.newMock(new BundleMock("system.bundle", new Hashtable<Object, Object>()), Bundle.class).getBundleContext();
+    mgr = new PersistenceContextManager(context, null);
+    mgr.open();
+  }
+  
+  @After
+  public void tearDown()
+  {
+    BundleContextMock.clear();
+  }
+  
+  /**
+   * A simple test to show we get a service registered when a unit
+   * is registered first.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testUnitThenContext() throws InvalidSyntaxException
+  {
+    String unitName = "unit";
+    
+    reg1 = registerUnit(emf1, unitName, TRUE);
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    
+    mgr.registerContext(unitName, client1, new HashMap<String, Object>());
+    
+    assertContextRegistered(unitName);
+  }
+
+  /**
+   * A simple test to show we get a service unregistered when a context
+   * is removed.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testUnitThenContextThenRemoveContext() throws InvalidSyntaxException
+  {
+    testUnitThenContext();
+    mgr.unregisterContext("unit", client1);
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * A simple test to show we get a service unregistered when a unit
+   * is removed.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testUnitThenContextThenRemoveUnit() throws InvalidSyntaxException
+  {
+    testUnitThenContext();
+    reg1.unregister();
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * A simple test to show we get a service registered when a context
+   * is registered first.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testContextThenUnit() throws InvalidSyntaxException
+  {
+    String unitName = "unit";
+    
+    mgr.registerContext(unitName, client1, new HashMap<String, Object>());
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    
+    reg1 = registerUnit(emf1, unitName, TRUE);
+    
+    assertContextRegistered(unitName);
+  }
+
+  /**
+   * A simple test to show we get a service unregistered when a context
+   * is removed.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testContextThenUnitThenRemoveContext() throws InvalidSyntaxException
+  {
+    testContextThenUnit();
+    mgr.unregisterContext("unit", client1);
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * A simple test to show we get a service unregistered when a unit
+   * is removed.
+   * 
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testContextThenUnitThenRemoveUnit() throws InvalidSyntaxException
+  {
+    testContextThenUnit();
+    reg1.unregister();
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * Test that we don't register a service when the unit and
+   * context don't match
+   */
+  @Test
+  public void testAddDifferentContext()
+  {
+    reg1 = registerUnit(emf1, "unit", TRUE);
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    
+    mgr.registerContext("context", client1, new HashMap<String, Object>());
+    
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * Test that we don't unregister a service when a different context is
+   * removed
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testRemoveDifferentContext() throws InvalidSyntaxException
+  {
+    testAddDifferentContext();
+    
+    mgr.registerContext("unit", client1, new HashMap<String, Object>());
+    
+    assertContextRegistered("unit");
+    
+    mgr.unregisterContext("context", client1);
+    
+    assertContextRegistered("unit");
+  }
+  
+  /**
+   * Test that we don't unregister a service when a different unit is
+   * removed
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testRemoveDifferentUnit() throws InvalidSyntaxException
+  {
+    testAddDifferentContext();
+    reg2 = registerUnit(emf2, "context", TRUE);
+    assertContextRegistered("context");
+    reg1.unregister();
+    assertContextRegistered("context");
+    reg2.unregister();
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  /**
+   * Test that we cope when multiple clients consume the same context
+   * @throws InvalidSyntaxException
+   */
+  @Test
+  public void testMultipleClients() throws InvalidSyntaxException
+  {
+    testContextThenUnit();
+    
+    mgr.registerContext("unit", client2, new HashMap<String, Object>());
+    assertContextRegistered("unit");
+    
+    mgr.unregisterContext("unit", client1);
+    assertContextRegistered("unit");
+    
+    mgr.unregisterContext("unit", client2);
+    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+  }
+  
+  
+  private ServiceRegistration registerUnit(EntityManagerFactory emf, String name, Boolean managed) {
+    
+    Hashtable<String, Object> props = new Hashtable<String, Object>();
+    
+    if(name != null)
+      props.put(PersistenceUnitConstants.OSGI_UNIT_NAME, name);
+    
+    if(managed)
+      props.put(PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT, managed);
+    
+    props.put(PersistenceUnitConstants.OSGI_UNIT_PROVIDER, "some.provider.Name");
+    
+    return context.registerService(
+        EntityManagerFactory.class.getName(), emf, props);
+  }
+  
+  private void assertContextRegistered(String name) throws InvalidSyntaxException {
+    BundleContextMock.assertServiceExists(EntityManager.class.getName());
+    
+    ServiceReference[] refs = context.getServiceReferences(EntityManager.class.getName(), null);
+    
+    assertEquals("Too many EntityManagers", 1, refs.length);
+    
+    assertEquals("Wrong unit name", name, refs[0].getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
+    
+    assertEquals("Wrong provider name", "some.provider.Name", refs[0].getProperty(PersistenceUnitConstants.OSGI_UNIT_PROVIDER));
+    
+    assertEquals("Unit should be managed", Boolean.TRUE, refs[0].getProperty(PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT));
+  }
+}