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));
+ }
+}