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 2018/01/25 17:08:13 UTC

[aries-tx-control] 01/02: Tx Control spec compliance - recovery should work for JDBC resources created from the factory service

This is an automated email from the ASF dual-hosted git repository.

timothyjward pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-tx-control.git

commit 1ded5dc93ec3227591e66ccc18f9d63c55163b7e
Author: Tim Ward <ti...@apache.org>
AuthorDate: Thu Jan 25 10:12:39 2018 -0500

    Tx Control spec compliance - recovery should work for JDBC resources created from the factory service
---
 .../aries/tx/control/jdbc/xa/impl/Activator.java   | 10 +++--
 .../xa/impl/JDBCConnectionProviderFactoryImpl.java | 19 +++++++--
 .../jdbc/xa/impl/JDBCConnectionProviderImpl.java   | 46 +++++++++++++++++++++-
 .../jdbc/xa/impl/ManagedServiceFactoryImpl.java    | 30 +-------------
 .../XAEnabledTxContextBindingConnectionTest.java   |  4 +-
 5 files changed, 69 insertions(+), 40 deletions(-)

diff --git a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Activator.java b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Activator.java
index 24b121c..6f5fae5 100644
--- a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Activator.java
+++ b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Activator.java
@@ -18,6 +18,9 @@
  */
 package org.apache.aries.tx.control.jdbc.xa.impl;
 
+import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.LOCAL_ENLISTMENT_ENABLED;
+import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.XA_ENLISTMENT_ENABLED;
+
 import java.util.Dictionary;
 import java.util.Hashtable;
 
@@ -40,7 +43,7 @@ public class Activator extends ResourceActivator<AbstractJDBCConnectionProvider,
 			@Override
 			protected TrackingResourceProviderFactory<AbstractJDBCConnectionProvider> getTrackingResourceManagerProviderFactory() {
 				return new ResourceTrackingJDBCConnectionProviderFactory(
-						new JDBCConnectionProviderFactoryImpl());
+						new JDBCConnectionProviderFactoryImpl(context));
 			}
 		};
 	}
@@ -53,8 +56,9 @@ public class Activator extends ResourceActivator<AbstractJDBCConnectionProvider,
 	@Override
 	protected Dictionary<String, Object> getServiceProperties() {
 		Dictionary<String, Object> props = new Hashtable<>();
-		props.put("osgi.local.enabled", Boolean.TRUE);
-		props.put("osgi.xa.enabled", Boolean.TRUE);
+		props.put(LOCAL_ENLISTMENT_ENABLED, Boolean.TRUE);
+		props.put(XA_ENLISTMENT_ENABLED, Boolean.TRUE);
+		props.put("osgi.recovery.enabled", Boolean.TRUE);
 		return props;
 	}
 
diff --git a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderFactoryImpl.java b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderFactoryImpl.java
index 34c3f86..7ece898 100644
--- a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderFactoryImpl.java
+++ b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderFactoryImpl.java
@@ -37,6 +37,7 @@ import org.apache.aries.tx.control.jdbc.common.impl.AbstractInternalJDBCConnecti
 import org.apache.aries.tx.control.jdbc.common.impl.AbstractJDBCConnectionProvider;
 import org.apache.aries.tx.control.jdbc.common.impl.DriverDataSource;
 import org.apache.aries.tx.control.jdbc.xa.connection.impl.XADataSourceMapper;
+import org.osgi.framework.BundleContext;
 import org.osgi.service.jdbc.DataSourceFactory;
 import org.osgi.service.transaction.control.TransactionException;
 import org.slf4j.Logger;
@@ -46,6 +47,12 @@ public class JDBCConnectionProviderFactoryImpl extends AbstractInternalJDBCConne
 
 	private static final Logger LOG = LoggerFactory.getLogger(ManagedServiceFactoryImpl.class);
 	
+	private final BundleContext context;
+	
+	public JDBCConnectionProviderFactoryImpl(BundleContext context) {
+		this.context = context;
+	}
+
 	@Override
 	public JDBCConnectionProviderImpl getProviderFor(DataSourceFactory dsf, Properties jdbcProperties,
 			Map<String, Object> resourceProviderProperties) {
@@ -73,7 +80,8 @@ public class JDBCConnectionProviderFactoryImpl extends AbstractInternalJDBCConne
 		DataSource toUse = poolIfNecessary(resourceProviderProperties, unpooled);
 		
 		return new JDBCConnectionProviderImpl(toUse, xaEnabled, localEnabled, 
-				getRecoveryId(resourceProviderProperties, xaEnabled));
+				getRecoveryId(resourceProviderProperties, xaEnabled), context,
+				resourceProviderProperties);
 	}
 
 	private String getRecoveryId(Map<String, Object> resourceProviderProps, boolean xaEnabled) {
@@ -112,7 +120,8 @@ public class JDBCConnectionProviderFactoryImpl extends AbstractInternalJDBCConne
 				new XADataSourceMapper(xaDS) : ds);
 
 		return new JDBCConnectionProviderImpl(toUse, xaEnabled, localEnabled, 
-				getRecoveryId(resourceProviderProperties, xaEnabled));
+				getRecoveryId(resourceProviderProperties, xaEnabled), context,
+				resourceProviderProperties);
 	}
 
 	@Override
@@ -128,7 +137,8 @@ public class JDBCConnectionProviderFactoryImpl extends AbstractInternalJDBCConne
 				new DriverDataSource(driver, jdbcProperties.getProperty(JDBC_URL), jdbcProperties));
 		
 		return new JDBCConnectionProviderImpl(toUse, xaEnabled, localEnabled, 
-				getRecoveryId(resourceProviderProperties, xaEnabled));
+				getRecoveryId(resourceProviderProperties, xaEnabled), context,
+				resourceProviderProperties);
 	}
 
 	@Override
@@ -142,7 +152,8 @@ public class JDBCConnectionProviderFactoryImpl extends AbstractInternalJDBCConne
 		DataSource unpooled = new XADataSourceMapper(ds);
 		
 		return new JDBCConnectionProviderImpl(poolIfNecessary(resourceProviderProperties, unpooled),
-				xaEnabled, localEnabled, getRecoveryId(resourceProviderProperties, xaEnabled));
+				xaEnabled, localEnabled, getRecoveryId(resourceProviderProperties, xaEnabled), context,
+				resourceProviderProperties);
 	}
 
 	private void checkEnlistment(boolean xaEnabled, boolean localEnabled, boolean isXA) {
diff --git a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderImpl.java b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderImpl.java
index 130ef6a..12706e4 100644
--- a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderImpl.java
+++ b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/JDBCConnectionProviderImpl.java
@@ -18,17 +18,28 @@
  */
 package org.apache.aries.tx.control.jdbc.xa.impl;
 
+import static org.apache.aries.tx.control.jdbc.common.impl.AbstractInternalJDBCConnectionProviderFactory.toBoolean;
+import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.XA_ENLISTMENT_ENABLED;
+
 import java.sql.Connection;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.sql.DataSource;
 
 import org.apache.aries.tx.control.jdbc.common.impl.AbstractJDBCConnectionProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.transaction.control.TransactionControl;
 import org.osgi.service.transaction.control.TransactionException;
+import org.osgi.service.transaction.control.recovery.RecoverableXAResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class JDBCConnectionProviderImpl extends AbstractJDBCConnectionProvider {
 
+	private static final Logger LOG = LoggerFactory.getLogger(JDBCConnectionProviderImpl.class);
+	
 	private final UUID			uuid	= UUID.randomUUID();
 
 	private final boolean xaEnabled;
@@ -37,18 +48,49 @@ public class JDBCConnectionProviderImpl extends AbstractJDBCConnectionProvider {
 	
 	private final String recoveryIdentifier;
 	
+	private final ServiceRegistration<RecoverableXAResource> reg;
+	
 	public JDBCConnectionProviderImpl(DataSource dataSource, boolean xaEnabled,
-			boolean localEnabled, String recoveryIdentifier) {
+			boolean localEnabled, String recoveryIdentifier, BundleContext ctx,
+			Map<String, Object> providerProperties) {
 		super(dataSource);
 		this.xaEnabled = xaEnabled;
 		this.localEnabled = localEnabled;
 		this.recoveryIdentifier = recoveryIdentifier;
+		
+		if(recoveryIdentifier != null) {
+			if(!toBoolean(providerProperties, XA_ENLISTMENT_ENABLED, true)) {
+				LOG.warn("A JDBCResourceProvider has been configured with a recovery identifier {} but it has also been configured not to use XA transactions. No recovery will be available.", recoveryIdentifier);
+				reg = null;
+			} else {
+				reg = ctx.registerService(RecoverableXAResource.class, 
+						new RecoverableXAResourceImpl(recoveryIdentifier, this, 
+								(String) providerProperties.get("recovery.user"),
+								(String) providerProperties.get(".recovery.password)")), 
+						null);
+			}
+		} else {
+			reg = null;
+		}
 	}
-
+	
 	@Override
 	public Connection getResource(TransactionControl txControl)
 			throws TransactionException {
 		return new XAEnabledTxContextBindingConnection(txControl, this, uuid,
 				xaEnabled, localEnabled, recoveryIdentifier);
 	}
+
+	@Override
+	public void close() {
+		if(reg != null) {
+			try {
+				reg.unregister();
+			} catch (IllegalStateException ise) {
+				LOG.debug("An exception occurred when unregistering the recovery service for {}", recoveryIdentifier);
+			}
+		}
+		super.close();
+	}
+	
 }
diff --git a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
index 1273ee5..d696355 100644
--- a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
+++ b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
@@ -19,7 +19,6 @@
 package org.apache.aries.tx.control.jdbc.xa.impl;
 
 import static java.util.Arrays.asList;
-import static org.apache.aries.tx.control.jdbc.common.impl.AbstractInternalJDBCConnectionProviderFactory.toBoolean;
 import static org.osgi.framework.Constants.OBJECTCLASS;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATABASE_NAME;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATASOURCE_NAME;
@@ -32,8 +31,6 @@ import static org.osgi.service.jdbc.DataSourceFactory.JDBC_SERVER_NAME;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_URL;
 import static org.osgi.service.jdbc.DataSourceFactory.JDBC_USER;
 import static org.osgi.service.jdbc.DataSourceFactory.OSGI_JDBC_DRIVER_CLASS;
-import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.OSGI_RECOVERY_IDENTIFIER;
-import static org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory.XA_ENLISTMENT_ENABLED;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -53,7 +50,6 @@ import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.jdbc.DataSourceFactory;
 import org.osgi.service.transaction.control.jdbc.JDBCConnectionProvider;
-import org.osgi.service.transaction.control.recovery.RecoverableXAResource;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
@@ -127,7 +123,6 @@ public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFacto
 
 		private DataSourceFactory activeDsf;
 		private ServiceRegistration<JDBCConnectionProvider> serviceReg;
-		private ServiceRegistration<RecoverableXAResource> recoveryReg;
 		private AbstractJDBCConnectionProvider provider;
 
 		public ManagedJDBCResourceProvider(BundleContext context, String pid, Properties jdbcProperties,
@@ -176,46 +171,28 @@ public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFacto
 			}
 
 			ServiceRegistration<JDBCConnectionProvider> reg = null;
-			ServiceRegistration<RecoverableXAResource> reg2 = null;
 			JDBCConnectionProviderImpl provider = null;
 			if (setDsf) {
 				try {
-					provider = new JDBCConnectionProviderFactoryImpl().getProviderFor(service,
+					provider = new JDBCConnectionProviderFactoryImpl(context).getProviderFor(service,
 							jdbcProperties, providerProperties);
-					String recoveryId = (String) providerProperties.get(OSGI_RECOVERY_IDENTIFIER);
-					if(recoveryId !=null) {
-						if(toBoolean(providerProperties, XA_ENLISTMENT_ENABLED, true)) {
-							LOG.warn("A JDBCResourceProvider has been configured with a recovery identifier {} but it has also been configured not to use XA transactions. No recovery will be available.", recoveryId);
-						} else {
-							reg2 = context.registerService(RecoverableXAResource.class, 
-									new RecoverableXAResourceImpl(recoveryId, provider, 
-											(String) providerProperties.get("recovery.user"),
-											(String) providerProperties.get(".recovery.password)")), 
-									getServiceProperties());
-						}
-					}
 					reg = context
 							.registerService(JDBCConnectionProvider.class, provider, getServiceProperties());
 
 					ServiceRegistration<JDBCConnectionProvider> oldReg;
-					ServiceRegistration<RecoverableXAResource> oldReg2;
 					AbstractJDBCConnectionProvider oldProvider;
 					synchronized (this) {
 						if(activeDsf == service) {
 							oldReg = serviceReg;
 							serviceReg = reg;
-							oldReg2 = recoveryReg;
-							recoveryReg = reg2;
 							oldProvider = this.provider;
 							this.provider = provider;
 						} else {
 							oldReg = reg;
-							oldReg2 = reg2;
 							oldProvider = provider;
 						}
 					}
 					safeUnregister(oldReg);
-					safeUnregister(oldReg2);
 					safeClose(oldProvider);
 				} catch (Exception e) {
 					LOG.error("An error occurred when creating the connection provider for {}.", pid, e);
@@ -226,7 +203,6 @@ public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFacto
 						}
 					}
 					safeUnregister(reg);
-					safeUnregister(reg2);
 					safeClose(provider);
 				}
 			}
@@ -270,22 +246,18 @@ public class ManagedServiceFactoryImpl extends ConfigurationDefinedResourceFacto
 		public void removedService(ServiceReference<DataSourceFactory> reference, DataSourceFactory service) {
 			boolean dsfLeft;
 			ServiceRegistration<JDBCConnectionProvider> oldReg = null;
-			ServiceRegistration<RecoverableXAResource> oldReg2 = null;
 			AbstractJDBCConnectionProvider oldProvider = null;
 			synchronized (this) {
 				dsfLeft = activeDsf == service;
 				if (dsfLeft) {
 					activeDsf = null;
 					oldReg = serviceReg;
-					oldReg2 = recoveryReg;
 					oldProvider = provider;
 					serviceReg = null;
-					recoveryReg = null;
 					provider = null;
 				}
 			}
 			safeUnregister(oldReg);
-			safeUnregister(oldReg2);
 			safeClose(oldProvider);
 
 			if (dsfLeft) {
diff --git a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/test/java/org/apache/aries/tx/control/jdbc/xa/impl/XAEnabledTxContextBindingConnectionTest.java b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/test/java/org/apache/aries/tx/control/jdbc/xa/impl/XAEnabledTxContextBindingConnectionTest.java
index bc86e2a..c94f724 100644
--- a/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/test/java/org/apache/aries/tx/control/jdbc/xa/impl/XAEnabledTxContextBindingConnectionTest.java
+++ b/tx-control-providers/jdbc/tx-control-provider-jdbc-xa/src/test/java/org/apache/aries/tx/control/jdbc/xa/impl/XAEnabledTxContextBindingConnectionTest.java
@@ -94,9 +94,9 @@ public class XAEnabledTxContextBindingConnectionTest {
 		Mockito.when(xaMock.getConnection()).thenReturn(rawConnection);
 		Mockito.when(xaMock.getXAResource()).thenReturn(xaResource);
 		
-		localProvider = new JDBCConnectionProviderImpl(dataSource, false, true, null);
+		localProvider = new JDBCConnectionProviderImpl(dataSource, false, true, null, null, null);
 		xaProvider = new JDBCConnectionProviderImpl(new XADataSourceMapper(xaDataSource), 
-				true, false, null);
+				true, false, null, null, null);
 		
 		localConn = new XAEnabledTxContextBindingConnection(control, localProvider, 
 				id, false, true, null);

-- 
To stop receiving notification emails like this one, please contact
timothyjward@apache.org.