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 2016/10/10 14:47:18 UTC

svn commit: r1764110 - in /aries/trunk/tx-control: tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/ tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/ tx-control-provider-jpa-local/src/main/...

Author: timothyjward
Date: Mon Oct 10 14:47:17 2016
New Revision: 1764110

URL: http://svn.apache.org/viewvc?rev=1764110&view=rev
Log:
ARIES-1616 Clean up XA JPA resources properly

Removed:
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/common/impl/EntityManagerWrapper.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/common/impl/ScopedEntityManagerWrapper.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/common/impl/TxEntityManagerWrapper.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/LifecycleAware.java
Modified:
    aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/JPALifecycleTest.java
    aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/JPAEntityManagerProviderFactoryImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/DelayedJPAEntityManagerProvider.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java

Modified: aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/JPALifecycleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/JPALifecycleTest.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/JPALifecycleTest.java (original)
+++ aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/JPALifecycleTest.java Mon Oct 10 14:47:17 2016
@@ -35,7 +35,6 @@ import java.util.List;
 import java.util.function.Predicate;
 
 import org.apache.aries.tx.control.itests.entity.Message;
-import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.CoreOptions;
@@ -104,18 +103,12 @@ public class JPALifecycleTest extends Ab
 
 	@Test
 	public void testStopOfTxControlBundle() {
-		// Do not run for XA tests yet
-		Assume.assumeFalse(Boolean.getBoolean(IS_XA));
-		
 		doBundleStoppingTest(b -> b.getSymbolicName().contains("tx-control-service"),
 				"The transaction control service is closed");
 	}
 
 	@Test
 	public void testStopOfJPABundle() {
-		// Do not run for XA tests yet
-		Assume.assumeFalse(Boolean.getBoolean(IS_XA));
-		
 		doBundleStoppingTest(b -> b.getSymbolicName().contains("tx-control-provider-jpa"),
 				"There was a problem getting hold of a database connection");
 	}
@@ -142,7 +135,7 @@ public class JPALifecycleTest extends Ab
 
 			try {
 				assertEquals(m.message, txControl.notSupported(() -> em.find(Message.class, m.id).message));
-				fail("Should not be accessible");
+				fail("Should not be accessible " + (Boolean.getBoolean(IS_XA) ? "xa" : "local"));
 			} catch (ScopedWorkException swe) {
 				assertTrue(swe.getCause().toString(), swe.getCause() instanceof TransactionException);
 				assertEquals(exceptionMessage, swe.getCause().getMessage());
@@ -164,9 +157,6 @@ public class JPALifecycleTest extends Ab
 	@Test
 	public void testDeleteOfConfig() throws Exception {
 		
-		// Do not run for XA tests yet
-		Assume.assumeFalse(Boolean.getBoolean(IS_XA));
-
 		Message m = new Message();
 		m.message = "Hello World";
 		txControl.required(() -> {em.persist(m); return null;});
@@ -187,7 +177,7 @@ public class JPALifecycleTest extends Ab
 
 		try {
 			assertEquals(m.message, txControl.notSupported(() -> em.find(Message.class, m.id).message));
-			fail("Should not be accessible");
+			fail("Should not be accessible " + (Boolean.getBoolean(IS_XA) ? "xa" : "local"));
 		} catch (ScopedWorkException swe) {
 			assertTrue(swe.getCause().toString(), swe.getCause() instanceof TransactionException);
 			assertEquals("There was a problem getting hold of a database connection", swe.getCause().getMessage());
@@ -196,8 +186,6 @@ public class JPALifecycleTest extends Ab
 
 	@Test
 	public void testUpdateOfConfig() throws Exception {
-		// Do not run for XA tests yet
-		Assume.assumeFalse(Boolean.getBoolean(IS_XA));
 		
 		Message m = new Message();
 		m.message = "Hello World";
@@ -219,7 +207,7 @@ public class JPALifecycleTest extends Ab
 
 		try {
 			assertEquals(m.message, txControl.notSupported(() -> em.find(Message.class, m.id).message));
-			fail("Should not be accessible");
+			fail("Should not be accessible " + (Boolean.getBoolean(IS_XA) ? "xa" : "local"));
 		} catch (ScopedWorkException swe) {
 			assertTrue(swe.getCause().toString(), swe.getCause() instanceof TransactionException);
 			assertEquals("There was a problem getting hold of a database connection", swe.getCause().getMessage());

Modified: aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-common/src/main/java/org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.java Mon Oct 10 14:47:17 2016
@@ -13,10 +13,6 @@ public interface InternalJPAEntityManage
 	AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, 
 			Map<String, Object> jpaProperties, Map<String, Object> resourceProviderProperties);
 
-	AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, 
-	Map<String, Object> jpaProperties, Map<String, Object> resourceProviderProperties, 
-	Runnable onClose);
-
 	@Override
 	AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactory emf,
 			Map<String, Object> resourceProviderProperties);

Modified: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/JPAEntityManagerProviderFactoryImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/JPAEntityManagerProviderFactoryImpl.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/JPAEntityManagerProviderFactoryImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/JPAEntityManagerProviderFactoryImpl.java Mon Oct 10 14:47:17 2016
@@ -45,26 +45,25 @@ public class JPAEntityManagerProviderFac
 		return new JPAEntityManagerProviderImpl(emf, () -> emf.close());
 	}
 
-	@Override
-		public AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, 
-				Map<String, Object> jpaProperties, Map<String, Object> resourceProviderProperties, 
-				Runnable onClose) {
-			checkEnlistment(resourceProviderProperties);
-			
-			EntityManagerFactory emf = emfb.createEntityManagerFactory(jpaProperties);
-			
-			validateEMF(emf);
-			
-			return new JPAEntityManagerProviderImpl(emf, () -> {
-				try {
-					emf.close();
-				} catch (Exception e) {
-				}
-				if (onClose != null) {
-					onClose.run();
-				}
-			});
-		}
+	public AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, 
+			Map<String, Object> jpaProperties, Map<String, Object> resourceProviderProperties, 
+			Runnable onClose) {
+		checkEnlistment(resourceProviderProperties);
+		
+		EntityManagerFactory emf = emfb.createEntityManagerFactory(jpaProperties);
+		
+		validateEMF(emf);
+		
+		return new JPAEntityManagerProviderImpl(emf, () -> {
+			try {
+				emf.close();
+			} catch (Exception e) {
+			}
+			if (onClose != null) {
+				onClose.run();
+			}
+		});
+	}
 
 	private void validateEMF(EntityManagerFactory emf) {
 		Object o = emf.getProperties().get("javax.persistence.transactionType");

Modified: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedJPADataSourceSetup.java Mon Oct 10 14:47:17 2016
@@ -178,7 +178,6 @@ public class ManagedJPADataSourceSetup i
 		}
 	}
 	
-	
 	private DataSource poolIfNecessary(Map<String, Object> resourceProviderProperties, DataSource unpooled) {
 		DataSource toUse;
 

Modified: aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-local/src/main/java/org/apache/aries/tx/control/jpa/local/impl/ManagedServiceFactoryImpl.java Mon Oct 10 14:47:17 2016
@@ -75,7 +75,6 @@ public class ManagedServiceFactoryImpl e
 	protected LifecycleAware getConfigurationDrivenResource(BundleContext context, String pid,
 			Map<String, Object> properties) throws Exception {
 
-
 		Properties jdbcProps = getJdbcProps(pid, properties);
 		Map<String, Object> jpaProps = getJPAProps(pid, properties);
 
@@ -149,7 +148,6 @@ public class ManagedServiceFactoryImpl e
 		return result;
 	}
 
-	
 	private static class AllCollection implements Collection<String> {
 
 		@Override

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml Mon Oct 10 14:47:17 2016
@@ -57,6 +57,18 @@
 		</dependency>
 		<dependency>
             <groupId>org.apache.aries.tx-control</groupId>
+            <artifactId>tx-control-provider-common</artifactId>
+            <version>0.0.2-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+		<dependency>
+            <groupId>org.apache.aries.tx-control</groupId>
+            <artifactId>tx-control-provider-jpa-common</artifactId>
+            <version>0.0.2-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+		<dependency>
+            <groupId>org.apache.aries.tx-control</groupId>
             <artifactId>tx-control-provider-jdbc-common</artifactId>
             <version>0.0.2-SNAPSHOT</version>
             <scope>provided</scope>

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/Activator.java Mon Oct 10 14:47:17 2016
@@ -18,57 +18,49 @@
  */
 package org.apache.aries.tx.control.jpa.xa.impl;
 
-import static org.osgi.framework.Constants.SERVICE_PID;
-
 import java.util.Dictionary;
 import java.util.Hashtable;
 
-import org.apache.geronimo.specs.jpa.PersistenceActivator;
-import org.osgi.framework.BundleActivator;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
+import org.apache.aries.tx.control.jpa.common.impl.InternalJPAEntityManagerProviderFactory;
+import org.apache.aries.tx.control.jpa.common.impl.JPAResourceActivator;
+import org.apache.aries.tx.control.jpa.common.impl.ResourceTrackingJPAEntityManagerProviderFactory;
+import org.apache.aries.tx.control.resource.common.impl.ConfigurationDefinedResourceFactory;
+import org.apache.aries.tx.control.resource.common.impl.ResourceProviderFactoryServiceFactory;
+import org.apache.aries.tx.control.resource.common.impl.TrackingResourceProviderFactory;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
-
-public class Activator implements BundleActivator {
-
-	private final BundleActivator geronimoActivator;
-	
-	private ServiceRegistration<JPAEntityManagerProviderFactory> reg;
-	private ServiceRegistration<ManagedServiceFactory> factoryReg;
-	
-	public Activator() {
-		geronimoActivator = new PersistenceActivator();
-	}
-	
+
+public class Activator extends JPAResourceActivator {
+
 	@Override
-	public void start(BundleContext context) throws Exception {
-		geronimoActivator.start(context);
+	protected ResourceProviderFactoryServiceFactory<AbstractJPAEntityManagerProvider, ResourceTrackingJPAEntityManagerProviderFactory> getServiceFactory(
+			BundleContext context) {
 		
-		reg = context.registerService(JPAEntityManagerProviderFactory.class, 
-				new JPAEntityManagerProviderFactoryImpl(), getProperties());
-		
-		factoryReg = context.registerService(ManagedServiceFactory.class, 
-				new ManagedServiceFactoryImpl(context), getMSFProperties());
+		InternalJPAEntityManagerProviderFactory ijempf = new JPAEntityManagerProviderFactoryImpl();
+		return new ResourceProviderFactoryServiceFactory<AbstractJPAEntityManagerProvider, ResourceTrackingJPAEntityManagerProviderFactory>() {
+			@Override
+			protected TrackingResourceProviderFactory<AbstractJPAEntityManagerProvider> getTrackingResourceManagerProviderFactory() {
+				return new ResourceTrackingJPAEntityManagerProviderFactory(ijempf);
+			}
+			
+		};
 	}
 
 	@Override
-	public void stop(BundleContext context) throws Exception {
-		reg.unregister();
-		factoryReg.unregister();
-		geronimoActivator.stop(context);
-	}
-
-	private Dictionary<String, Object> getProperties() {
+	protected Dictionary<String, Object> getServiceProperties() {
 		Dictionary<String, Object> props = new Hashtable<>();
 		props.put("osgi.xa.enabled", Boolean.TRUE);
 		return props;
 	}
 
-	private Dictionary<String, ?> getMSFProperties() {
-		Dictionary<String, Object> props = new Hashtable<>();
-		props.put(SERVICE_PID, "org.apache.aries.tx.control.jpa.xa");
-		return props;
+	@Override
+	protected ConfigurationDefinedResourceFactory getConfigurationDefinedResourceFactory(BundleContext context) {
+		return new ManagedServiceFactoryImpl(context);
+	}
+
+	@Override
+	protected String getMSFPid() {
+		return "org.apache.aries.tx.control.jpa.xa";
 	}
 
-}
+}
\ No newline at end of file

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/DelayedJPAEntityManagerProvider.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/DelayedJPAEntityManagerProvider.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/DelayedJPAEntityManagerProvider.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/DelayedJPAEntityManagerProvider.java Mon Oct 10 14:47:17 2016
@@ -22,26 +22,32 @@ import java.util.function.Function;
 
 import javax.persistence.EntityManager;
 
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
 import org.osgi.service.transaction.control.TransactionControl;
 import org.osgi.service.transaction.control.TransactionException;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
 
-public class DelayedJPAEntityManagerProvider implements JPAEntityManagerProvider {
+public class DelayedJPAEntityManagerProvider extends AbstractJPAEntityManagerProvider {
 	
-	private final Function<ThreadLocal<TransactionControl>, JPAEntityManagerProvider> wireToTransactionControl;
+	private final Function<ThreadLocal<TransactionControl>, AbstractJPAEntityManagerProvider> wireToTransactionControl;
 	
 	private final ThreadLocal<TransactionControl> commonStore = new ThreadLocal<>();
 	
-	private JPAEntityManagerProvider delegate;
+	private AbstractJPAEntityManagerProvider delegate;
+	
+	private boolean closed;
 	
 	public DelayedJPAEntityManagerProvider(Function<ThreadLocal<TransactionControl>, 
-			JPAEntityManagerProvider> wireToTransactionControl) {
+			AbstractJPAEntityManagerProvider> wireToTransactionControl) {
+		super(null, null);
 		this.wireToTransactionControl = wireToTransactionControl;
 	}
 
 	@Override
 	public EntityManager getResource(TransactionControl txControl) throws TransactionException {
 		synchronized (wireToTransactionControl) {
+			if(closed) {
+				throw new IllegalStateException("This XA JPA resource provider has been closed");
+			}
 			if(delegate == null) {
 				commonStore.set(txControl);
 				delegate = wireToTransactionControl.apply(commonStore);
@@ -50,6 +56,19 @@ public class DelayedJPAEntityManagerProv
 		return delegate.getResource(txControl);
 	}
 	
-	
+	public void close() {
+		AbstractJPAEntityManagerProvider toClose = null;
+		synchronized (wireToTransactionControl) {
+			if(!closed) {
+				closed = true;
+				toClose = delegate;
+				delegate = null;
+			}
+		}
+		
+		if(toClose != null) {
+			toClose.close();
+		}
+	}
 
 }

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java Mon Oct 10 14:47:17 2016
@@ -40,30 +40,30 @@ import javax.transaction.xa.XAResource;
 import org.apache.aries.tx.control.jdbc.common.impl.ScopedConnectionWrapper;
 import org.apache.aries.tx.control.jdbc.common.impl.TxConnectionWrapper;
 import org.apache.aries.tx.control.jdbc.xa.connection.impl.XAConnectionWrapper;
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
+import org.apache.aries.tx.control.jpa.common.impl.InternalJPAEntityManagerProviderFactory;
 import org.osgi.service.jpa.EntityManagerFactoryBuilder;
 import org.osgi.service.transaction.control.TransactionContext;
 import org.osgi.service.transaction.control.TransactionControl;
 import org.osgi.service.transaction.control.TransactionException;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
 
-public class JPAEntityManagerProviderFactoryImpl implements JPAEntityManagerProviderFactory {
+public class JPAEntityManagerProviderFactoryImpl implements InternalJPAEntityManagerProviderFactory {
 
 	@Override
-	public JPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, Map<String, Object> jpaProperties,
+	public AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, Map<String, Object> jpaProperties,
 			Map<String, Object> resourceProviderProperties) {
-		return new DelayedJPAEntityManagerProvider(tx -> getProviderFor(emfb, jpaProperties, resourceProviderProperties, tx));
+		return new DelayedJPAEntityManagerProvider(tx -> getProviderFor(emfb, jpaProperties, resourceProviderProperties, tx, null));
 	}
 
-	public JPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, Map<String, Object> jpaProperties,
-		Map<String, Object> resourceProviderProperties, ThreadLocal<TransactionControl> localStore) {
+	public AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactoryBuilder emfb, Map<String, Object> jpaProperties,
+		Map<String, Object> resourceProviderProperties, ThreadLocal<TransactionControl> localStore, Runnable onClose) {
 		Map<String, Object> toUse;
 		if(checkEnlistment(resourceProviderProperties)) {
 			toUse = enlistDataSource(localStore, jpaProperties);
 		} else {
 			toUse = jpaProperties;
 		}
-		return localStore.get().notSupported(() -> internalBuilderCreate(emfb, toUse, localStore));
+		return localStore.get().notSupported(() -> internalBuilderCreate(emfb, toUse, localStore, onClose));
 	}
 
 	private Map<String, Object> enlistDataSource(ThreadLocal<TransactionControl> tx, Map<String, Object> jpaProperties) {
@@ -80,13 +80,21 @@ public class JPAEntityManagerProviderFac
 		return toReturn;
 	}
 
-	private JPAEntityManagerProvider internalBuilderCreate(EntityManagerFactoryBuilder emfb,
-			Map<String, Object> jpaProperties, ThreadLocal<TransactionControl> tx) {
+	private AbstractJPAEntityManagerProvider internalBuilderCreate(EntityManagerFactoryBuilder emfb,
+			Map<String, Object> jpaProperties, ThreadLocal<TransactionControl> tx, Runnable onClose) {
 		EntityManagerFactory emf = emfb.createEntityManagerFactory(jpaProperties);
 		
 		validateEMF(emf);
 		
-		return new JPAEntityManagerProviderImpl(emf, tx);
+		return new JPAEntityManagerProviderImpl(emf, tx, () -> {
+			try {
+				emf.close();
+			} catch (Exception e) {
+			}
+			if (onClose != null) {
+				onClose.run();
+			}
+		});
 	}
 
 	private void validateEMF(EntityManagerFactory emf) {
@@ -108,12 +116,12 @@ public class JPAEntityManagerProviderFac
 	}
 
 	@Override
-	public JPAEntityManagerProvider getProviderFor(EntityManagerFactory emf,
+	public AbstractJPAEntityManagerProvider getProviderFor(EntityManagerFactory emf,
 			Map<String, Object> resourceProviderProperties) {
 		checkEnlistment(resourceProviderProperties);
 		validateEMF(emf);
 		
-		return new JPAEntityManagerProviderImpl(emf, new ThreadLocal<>());
+		return new JPAEntityManagerProviderImpl(emf, new ThreadLocal<>(), null);
 	}
 
 	private boolean checkEnlistment(Map<String, Object> resourceProviderProperties) {

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.java Mon Oct 10 14:47:17 2016
@@ -23,20 +23,19 @@ import java.util.UUID;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
 import org.osgi.service.transaction.control.TransactionControl;
 import org.osgi.service.transaction.control.TransactionException;
-import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
 
-public class JPAEntityManagerProviderImpl implements JPAEntityManagerProvider {
+public class JPAEntityManagerProviderImpl extends AbstractJPAEntityManagerProvider {
 
 	private final UUID					uuid	= UUID.randomUUID();
 
-	private final EntityManagerFactory 	emf;
-
 	private final ThreadLocal<TransactionControl> tx;
 
-	public JPAEntityManagerProviderImpl(EntityManagerFactory emf, ThreadLocal<TransactionControl> tx) {
-		this.emf = emf;
+	public JPAEntityManagerProviderImpl(EntityManagerFactory emf, ThreadLocal<TransactionControl> tx,
+			Runnable onClose) {
+		super(emf, onClose);
 		this.tx = tx;
 	}
 

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPADataSourceSetup.java Mon Oct 10 14:47:17 2016
@@ -42,6 +42,7 @@ import java.util.concurrent.atomic.Atomi
 import javax.sql.DataSource;
 
 import org.apache.aries.tx.control.jdbc.xa.connection.impl.XADataSourceMapper;
+import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -57,6 +58,8 @@ import com.zaxxer.hikari.HikariDataSourc
 public class ManagedJPADataSourceSetup implements LifecycleAware,
 		ServiceTrackerCustomizer<DataSourceFactory, ManagedJPAEMFLocator> {
 
+	private static final String JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE = "javax.persistence.nonJtaDataSource";
+	
 	private final BundleContext context;
 	private final String pid;
 	private final Properties jdbcProperties;
@@ -104,7 +107,12 @@ public class ManagedJPADataSourceSetup i
 		ManagedJPAEMFLocator toReturn;
 		try {
 			toReturn = new ManagedJPAEMFLocator(context, pid, 
-					getJPAProperties(service), providerProperties);
+					getJPAProperties(service), providerProperties, () -> {
+						Object o = providerProperties.get(JAVAX_PERSISTENCE_NON_JTA_DATA_SOURCE);
+						if (o instanceof HikariDataSource) {
+							((HikariDataSource)o).close();
+						}
+					});
 		} catch (Exception e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java Mon Oct 10 14:47:17 2016
@@ -37,6 +37,8 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.persistence.spi.PersistenceProvider;
 
+import org.apache.aries.tx.control.jpa.common.impl.AbstractJPAEntityManagerProvider;
+import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
@@ -58,17 +60,21 @@ public class ManagedJPAEMFLocator implem
 	private final String pid;
 	private final Map<String, Object> jpaProperties;
 	private final Map<String, Object> providerProperties;
+	private final Runnable onClose;
 	private final ServiceTracker<EntityManagerFactoryBuilder, EntityManagerFactoryBuilder> emfBuilderTracker;
 
-	private final AtomicReference<EntityManagerFactoryBuilder> activeDsf = new AtomicReference<>();
+	private final AtomicReference<EntityManagerFactoryBuilder> activeEMFB = new AtomicReference<>();
+	private final AtomicReference<AbstractJPAEntityManagerProvider> providerObject = new AtomicReference<>();
+	
 	private final AtomicReference<ServiceRegistration<JPAEntityManagerProvider>> serviceReg = new AtomicReference<>();
 
 	public ManagedJPAEMFLocator(BundleContext context, String pid, Map<String, Object> jpaProperties,
-			Map<String, Object> providerProperties) throws InvalidSyntaxException, ConfigurationException {
+			Map<String, Object> providerProperties, Runnable onClose) throws InvalidSyntaxException, ConfigurationException {
 		this.context = context;
 		this.pid = pid;
 		this.jpaProperties = jpaProperties;
 		this.providerProperties = providerProperties;
+		this.onClose = onClose;
 
 		String unitName = (String) providerProperties.get(JPA_UNIT_NAME);
 		if (unitName == null) {
@@ -106,12 +112,13 @@ public class ManagedJPAEMFLocator implem
 	private void updateService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
 		boolean setEMFB;
 		synchronized (this) {
-			setEMFB = activeDsf.compareAndSet(null, service);
+			setEMFB = activeEMFB.compareAndSet(null, service);
 		}
 
 		if (setEMFB) {
+			AbstractJPAEntityManagerProvider jpaEM = null;
 			try {
-				JPAEntityManagerProvider jpaEM = new DelayedJPAEntityManagerProvider(t -> {
+				jpaEM = new DelayedJPAEntityManagerProvider(t -> {
 					
 					Map<String, Object> jpaProps = new HashMap<String, Object>(jpaProperties);
 					Map<String, Object> providerProps = new HashMap<String, Object>(providerProperties);
@@ -119,8 +126,9 @@ public class ManagedJPAEMFLocator implem
 					setupTransactionManager(jpaProps, providerProps, t, reference);
 					
 					return new JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
-							jpaProps, providerProps, t);
+							jpaProps, providerProps, t, onClose);
 				});
+				providerObject.set(jpaEM);
 				ServiceRegistration<JPAEntityManagerProvider> reg = context
 						.registerService(JPAEntityManagerProvider.class, jpaEM, getServiceProperties());
 				if (!serviceReg.compareAndSet(null, reg)) {
@@ -128,7 +136,10 @@ public class ManagedJPAEMFLocator implem
 				}
 			} catch (Exception e) {
 				ManagedServiceFactoryImpl.LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
-				activeDsf.compareAndSet(service, null);
+				activeEMFB.compareAndSet(service, null);
+				if(jpaEM != null) {
+					jpaEM.close();
+				}
 			}
 		}
 	}
@@ -279,11 +290,13 @@ public class ManagedJPAEMFLocator implem
 
 	@Override
 	public void removedService(ServiceReference<EntityManagerFactoryBuilder> reference, EntityManagerFactoryBuilder service) {
-		boolean dsfLeft;
+		boolean emfbLeft;
 		ServiceRegistration<JPAEntityManagerProvider> oldReg = null;
+		AbstractJPAEntityManagerProvider toClose = null;
 		synchronized (this) {
-			dsfLeft = activeDsf.compareAndSet(service, null);
-			if (dsfLeft) {
+			emfbLeft = activeEMFB.compareAndSet(service, null);
+			if (emfbLeft) {
+				toClose = providerObject.get();
 				oldReg = serviceReg.getAndSet(null);
 			}
 		}
@@ -295,13 +308,22 @@ public class ManagedJPAEMFLocator implem
 				ManagedServiceFactoryImpl.LOG.debug("An exception occurred when unregistering a service for {}", pid);
 			}
 		}
+		
+		if(toClose != null) {
+			try {
+				toClose.close();
+			} catch (Exception e) {
+				ManagedServiceFactoryImpl.LOG.debug("An Exception occured when closing the Resource provider for {}", pid, e);
+			}
+		}
+		
 		try {
 			context.ungetService(reference);
 		} catch (IllegalStateException ise) {
 			ManagedServiceFactoryImpl.LOG.debug("An exception occurred when ungetting the service for {}", reference);
 		}
 
-		if (dsfLeft) {
+		if (emfbLeft) {
 			EntityManagerFactoryBuilder newEMFBuilder = emfBuilderTracker.getService();
 			if (newEMFBuilder != null) {
 				updateService(reference, newEMFBuilder);

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java?rev=1764110&r1=1764109&r2=1764110&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedServiceFactoryImpl.java Mon Oct 10 14:47:17 2016
@@ -20,7 +20,6 @@ package org.apache.aries.tx.control.jpa.
 
 import static java.lang.Integer.MAX_VALUE;
 import static java.util.Arrays.asList;
-import static java.util.Optional.ofNullable;
 import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.toMap;
 import static javax.persistence.spi.PersistenceUnitTransactionType.JTA;
@@ -38,23 +37,20 @@ import static org.osgi.service.jdbc.Data
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.aries.tx.control.resource.common.impl.ConfigurationDefinedResourceFactory;
+import org.apache.aries.tx.control.resource.common.impl.LifecycleAware;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ManagedServiceFactoryImpl implements ManagedServiceFactory {
+public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFactory {
 
 	static final Logger LOG = LoggerFactory.getLogger(ManagedServiceFactoryImpl.class);
 	
@@ -66,57 +62,41 @@ public class ManagedServiceFactoryImpl i
 			JDBC_URL, JDBC_USER);
 	static final String JPA_PROP_NAMES = "aries.jpa.property.names";
 
-	private final Map<String, LifecycleAware> managedInstances = new ConcurrentHashMap<>();
-
-	private final BundleContext context;
-
 	public ManagedServiceFactoryImpl(BundleContext context) {
-		this.context = context;
+		super(context);
 	}
 
 	@Override
 	public String getName() {
-		return "Aries JPAEntityManagerProvider (Local only) service";
+		return "Aries JPAEntityManagerProvider (XA only) service";
 	}
 
 	@Override
-	public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
-
-		Map<String, Object> propsMap = new HashMap<>();
-
-		Enumeration<String> keys = properties.keys();
-		while (keys.hasMoreElements()) {
-			String key = keys.nextElement();
-			propsMap.put(key, properties.get(key));
-		}
+	protected LifecycleAware getConfigurationDrivenResource(BundleContext context, String pid,
+			Map<String, Object> properties) throws Exception {
 
-		Properties jdbcProps = getJdbcProps(pid, propsMap);
-		Map<String, Object> jpaProps = getJPAProps(pid, propsMap);
+		Properties jdbcProps = getJdbcProps(pid, properties);
+		Map<String, Object> jpaProps = getJPAProps(pid, properties);
 
 		try {
 			LifecycleAware worker;
-			if(propsMap.containsKey(OSGI_JDBC_DRIVER_CLASS) ||
-					propsMap.containsKey(DSF_TARGET_FILTER)) {
-				worker = new ManagedJPADataSourceSetup(context, pid, jdbcProps, jpaProps, propsMap);
+			if(properties.containsKey(OSGI_JDBC_DRIVER_CLASS) ||
+					properties.containsKey(DSF_TARGET_FILTER)) {
+				worker = new ManagedJPADataSourceSetup(context, pid, jdbcProps, jpaProps, properties);
 			} else {
 				if(!jdbcProps.isEmpty()) {
 					LOG.warn("The configuration {} contains raw JDBC configuration, but no osgi.jdbc.driver.class or aries.dsf.target.filter properties. No DataSourceFactory will be used byt this bundle, so the JPA provider must be able to directly create the datasource, and these configuration properties will likely be ignored. {}",
 								pid, jdbcProps.stringPropertyNames());
 				}
-				worker = new ManagedJPAEMFLocator(context, pid, jpaProps, propsMap);
+				worker = new ManagedJPAEMFLocator(context, pid, jpaProps, properties, null);
 			}
-			ofNullable(managedInstances.put(pid, worker)).ifPresent(LifecycleAware::stop);
-			worker.start();
+			return worker;
 		} catch (InvalidSyntaxException e) {
 			LOG.error("The configuration {} contained an invalid target filter {}", pid, e.getFilter());
 			throw new ConfigurationException(DSF_TARGET_FILTER, "The target filter was invalid", e);
 		}
 	}
 
-	public void stop() {
-		managedInstances.values().forEach(LifecycleAware::stop);
-	}
-
 	@SuppressWarnings("unchecked")
 	private Properties getJdbcProps(String pid, Map<String, Object> properties) throws ConfigurationException {
 
@@ -168,12 +148,6 @@ public class ManagedServiceFactoryImpl i
 		return result;
 	}
 
-	@Override
-	public void deleted(String pid) {
-		ofNullable(managedInstances.remove(pid))
-			.ifPresent(LifecycleAware::stop);
-	}
-	
 	private static class AllCollection implements Collection<String> {
 
 		@Override