Skip to content

Commit

Permalink
[WFLY-11166] Expose TransactionSynchronizationRegistry as a capability
Browse files Browse the repository at this point in the history
  • Loading branch information
bstansberry committed Nov 16, 2018
1 parent 797f8ed commit b06a46d
Show file tree
Hide file tree
Showing 17 changed files with 72 additions and 36 deletions.
Expand Up @@ -30,6 +30,8 @@
import java.util.Set;
import java.util.function.UnaryOperator;

import javax.transaction.TransactionSynchronizationRegistry;

import org.infinispan.transaction.LockingMode;
import org.jboss.as.clustering.controller.BinaryCapabilityNameResolver;
import org.jboss.as.clustering.controller.BinaryRequirementCapability;
Expand Down Expand Up @@ -125,6 +127,7 @@ public AttributeDefinition getDefinition() {

enum TransactionRequirement implements Requirement {
LOCAL_TRANSACTION_PROVIDER("org.wildfly.transactions.global-default-local-provider", Void.class),
TRANSACTION_SYNCHRONIZATION_REGISTRY("org.wildfly.transactions.transaction-synchronization-registry", TransactionSynchronizationRegistry.class),
XA_RESOURCE_RECOVERY_REGISTRY("org.wildfly.transactions.xa-resource-recovery-registry", XAResourceRecoveryRegistry.class);

private final String name;
Expand Down Expand Up @@ -284,6 +287,8 @@ public ManagementResourceRegistration register(ManagementResourceRegistration pa
// Add a requirement on the tm capability to the parent cache capability
.addResourceCapabilityReference(new TransactionResourceCapabilityReference(dependentCapability, TransactionRequirement.LOCAL_TRANSACTION_PROVIDER, EnumSet.of(TransactionMode.NONE, TransactionMode.BATCH)))
// Add a requirement on the XAResourceRecoveryRegistry capability to the parent cache capability
.addResourceCapabilityReference(new TransactionResourceCapabilityReference(dependentCapability, TransactionRequirement.TRANSACTION_SYNCHRONIZATION_REGISTRY, EnumSet.complementOf(EnumSet.of(TransactionMode.NON_XA))))
// Add a requirement on the XAResourceRecoveryRegistry capability to the parent cache capability
.addResourceCapabilityReference(new TransactionResourceCapabilityReference(dependentCapability, TransactionRequirement.XA_RESOURCE_RECOVERY_REGISTRY, EnumSet.complementOf(EnumSet.of(TransactionMode.FULL_XA))));
ResourceServiceHandler handler = new SimpleResourceServiceHandler(TransactionServiceConfigurator::new);
new SimpleResourceRegistration(descriptor, handler).register(registration);
Expand Down
Expand Up @@ -26,9 +26,9 @@
import static org.jboss.as.clustering.infinispan.subsystem.TransactionResourceDefinition.Attribute.MODE;
import static org.jboss.as.clustering.infinispan.subsystem.TransactionResourceDefinition.Attribute.STOP_TIMEOUT;
import static org.jboss.as.clustering.infinispan.subsystem.TransactionResourceDefinition.TransactionRequirement.LOCAL_TRANSACTION_PROVIDER;
import static org.jboss.as.clustering.infinispan.subsystem.TransactionResourceDefinition.TransactionRequirement.TRANSACTION_SYNCHRONIZATION_REGISTRY;

import java.util.EnumSet;
import java.util.function.Supplier;

import javax.transaction.TransactionSynchronizationRegistry;

Expand All @@ -43,12 +43,14 @@
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.txn.service.TxnServices;
import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceBuilder;
import org.wildfly.clustering.service.CompositeDependency;
import org.wildfly.clustering.service.Dependency;
import org.wildfly.clustering.service.ServiceConfigurator;
import org.wildfly.clustering.service.ServiceDependency;
import org.wildfly.clustering.service.ServiceSupplierDependency;
import org.wildfly.clustering.service.SupplierDependency;
import org.wildfly.transaction.client.ContextTransactionManager;

/**
Expand All @@ -60,20 +62,15 @@ public class TransactionServiceConfigurator extends ComponentServiceConfigurator
private volatile long timeout;
private volatile TransactionMode mode;
private volatile Dependency transactionDependency;
private volatile Supplier<TransactionSynchronizationRegistry> tsrSupplier;
private volatile SupplierDependency<TransactionSynchronizationRegistry> tsrDependency;

public TransactionServiceConfigurator(PathAddress address) {
super(CacheComponent.TRANSACTION, address);
}

@Override
public <T> ServiceBuilder<T> register(ServiceBuilder<T> builder) {
if (this.transactionDependency != null) {
this.transactionDependency.register(builder);
}
if (this.mode == TransactionMode.NON_XA) {
this.tsrSupplier = builder.requires(TxnServices.JBOSS_TXN_SYNCHRONIZATION_REGISTRY);
}
new CompositeDependency(this.transactionDependency, this.tsrDependency).register(builder);
return super.register(builder);
}

Expand All @@ -83,6 +80,7 @@ public ServiceConfigurator configure(OperationContext context, ModelNode model)
this.locking = ModelNodes.asEnum(LOCKING.resolveModelAttribute(context, model), LockingMode.class);
this.timeout = STOP_TIMEOUT.resolveModelAttribute(context, model).asLong();
this.transactionDependency = !EnumSet.of(TransactionMode.NONE, TransactionMode.BATCH).contains(this.mode) ? new ServiceDependency(context.getCapabilityServiceName(LOCAL_TRANSACTION_PROVIDER.getName(), null)) : null;
this.tsrDependency = this.mode == TransactionMode.NON_XA ? new ServiceSupplierDependency<>(context.getCapabilityServiceName(TRANSACTION_SYNCHRONIZATION_REGISTRY.getName(), null)) : null;
return this;
}

Expand All @@ -105,7 +103,7 @@ public TransactionConfiguration get() {
break;
}
case NON_XA: {
builder.transactionSynchronizationRegistryLookup(new TransactionSynchronizationRegistryProvider(this.tsrSupplier.get()));
builder.transactionSynchronizationRegistryLookup(new TransactionSynchronizationRegistryProvider(this.tsrDependency.get()));
// fall through
}
default: {
Expand Down
Expand Up @@ -25,6 +25,7 @@

import static org.jboss.as.connector.subsystems.jca.JcaSubsystemRootDefinition.TRANSACTION_INTEGRATION_CAPABILITY;
import static org.jboss.as.connector.util.ConnectorServices.LOCAL_TRANSACTION_PROVIDER_CAPABILITY;
import static org.jboss.as.connector.util.ConnectorServices.TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY;
import static org.jboss.as.connector.util.ConnectorServices.TRANSACTION_XA_RESOURCE_RECOVERY_REGISTRY_CAPABILITY;

import javax.transaction.TransactionSynchronizationRegistry;
Expand Down Expand Up @@ -80,7 +81,7 @@ protected void execute(DeploymentProcessorTarget processorTarget) {
// Ensure the local transaction provider is started
.addCapabilityRequirement(LOCAL_TRANSACTION_PROVIDER_CAPABILITY, Void.class)
.addCapabilityRequirement(TRANSACTION_XA_RESOURCE_RECOVERY_REGISTRY_CAPABILITY, XAResourceRecoveryRegistry.class, tiService.getRrInjector())
.addDependency(TxnServices.JBOSS_TXN_SYNCHRONIZATION_REGISTRY, TransactionSynchronizationRegistry.class, tiService.getTsrInjector())
.addCapabilityRequirement(TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY, TransactionSynchronizationRegistry.class, tiService.getTsrInjector())
.addDependency(TxnServices.JBOSS_TXN_USER_TRANSACTION_REGISTRY, org.jboss.tm.usertx.UserTransactionRegistry.class, tiService.getUtrInjector())
.addDependency(TxnServices.JBOSS_TXN_CONTEXT_XA_TERMINATOR, JBossContextXATerminator.class, tiService.getTerminatorInjector())
.setInitialMode(ServiceController.Mode.ACTIVE)
Expand Down
Expand Up @@ -267,6 +267,11 @@ public static void registerCapabilityServiceName(String capabilityName, ServiceN
*/
public static final String LOCAL_TRANSACTION_PROVIDER_CAPABILITY = "org.wildfly.transactions.global-default-local-provider";

/**
* The capability name for the transaction TransactionSynchronizationRegistry.
*/
public static final String TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY = "org.wildfly.transactions.transaction-synchronization-registry";

/**
* The capability name for the transaction XAResourceRecoveryRegistry.
*/
Expand Down
Expand Up @@ -9,12 +9,12 @@

import javax.transaction.TransactionSynchronizationRegistry;

import org.jboss.as.controller.ServiceNameFactory;
import org.jboss.as.ejb3.cache.Cache;
import org.jboss.as.ejb3.cache.CacheFactory;
import org.jboss.as.ejb3.cache.Contextual;
import org.jboss.as.ejb3.cache.Identifiable;
import org.jboss.as.ejb3.cache.StatefulObjectFactory;
import org.jboss.as.txn.service.TxnServices;
import org.jboss.msc.Service;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName;
Expand Down Expand Up @@ -50,7 +50,12 @@ public ServiceBuilder<?> build(ServiceTarget target) {
this.configurator.build(target).install();
ServiceBuilder<?> builder = target.addService(this.getServiceName());
this.factory = builder.requires(this.configurator.getServiceName());
this.tsr = builder.requires(TxnServices.JBOSS_TXN_SYNCHRONIZATION_REGISTRY);
// Ensure the local transaction synchronization registry is started before the cache
// This parsing isn't 100% ideal as it's somewhat 'internal' knowledge of the relationship between
// capability names and service names. But at this point that relationship really needs to become
// a contract anyway
ServiceName tsrServiceName = ServiceNameFactory.parseServiceName("org.wildfly.transactions.transaction-synchronization-registry");
this.tsr = builder.requires(tsrServiceName);
Consumer<CacheFactory<K, V>> factory = builder.provides(this.getServiceName());
Service service = Service.newInstance(factory, this);
return builder.setInstance(service);
Expand Down
Expand Up @@ -568,7 +568,7 @@ public void configureDependency(final ServiceBuilder<?> serviceBuilder, final EJ
// add dependency on the local transaction provider
serviceBuilder.requires(support.getCapabilityServiceName("org.wildfly.transactions.global-default-local-provider"));
// add dependency on TransactionSynchronizationRegistry
serviceBuilder.addDependency(TxnServices.JBOSS_TXN_SYNCHRONIZATION_REGISTRY);
serviceBuilder.requires(support.getCapabilityServiceName("org.wildfly.transactions.transaction-synchronization-registry"));
}
});

Expand Down
Expand Up @@ -36,7 +36,6 @@
import org.jboss.as.ejb3.timerservice.persistence.TimerPersistence;
import org.jboss.as.ejb3.timerservice.persistence.filestore.FileTimerPersistence;
import org.jboss.as.server.Services;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.dmr.ModelNode;
import org.jboss.modules.ModuleLoader;
import org.jboss.msc.service.ServiceBuilder;
Expand Down Expand Up @@ -70,7 +69,7 @@ protected void performRuntime(final OperationContext context, ModelNode operatio
sb.addDependency(Services.JBOSS_SERVICE_MODULE_LOADER, ModuleLoader.class, fileTimerPersistence.getModuleLoader());
sb.addDependency(PathManagerService.SERVICE_NAME, PathManager.class, fileTimerPersistence.getPathManager());
sb.requires(context.getCapabilityServiceName("org.wildfly.transactions.global-default-local-provider", null));
sb.addDependency(TransactionSynchronizationRegistryService.SERVICE_NAME, TransactionSynchronizationRegistry.class, fileTimerPersistence.getTransactionSynchronizationRegistry());
sb.addDependency(context.getCapabilityServiceName("org.wildfly.transactions.transaction-synchronization-registry", null), TransactionSynchronizationRegistry.class, fileTimerPersistence.getTransactionSynchronizationRegistry());
sb.install();
}

Expand Down
Expand Up @@ -36,8 +36,8 @@

import org.jboss.as.jpa.messages.JpaLogger;
import org.jboss.as.jpa.transaction.TransactionUtil;
import org.jboss.as.jpa.util.JPAServiceNames;
import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.wildfly.security.manager.WildFlySecurityManager;
import org.wildfly.transaction.client.ContextTransactionManager;

Expand Down Expand Up @@ -277,13 +277,13 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN
@Override
public Object run() {
transactionManager = ContextTransactionManager.getInstance();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(JPAServiceNames.TRANSACTION_SYNCHRONIZATION_REGISTRY_SERVICE).getValue();
return null;
}
});
} else {
transactionManager = ContextTransactionManager.getInstance();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(JPAServiceNames.TRANSACTION_SYNCHRONIZATION_REGISTRY_SERVICE).getValue();
}
}
}
Expand Up @@ -41,7 +41,6 @@
import org.jboss.as.jpa.transaction.TransactionUtil;
import org.jboss.as.jpa.util.JPAServiceNames;
import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.msc.service.ServiceContainer;
import org.jboss.msc.service.ServiceController;
import org.wildfly.transaction.client.ContextTransactionManager;
Expand Down Expand Up @@ -120,7 +119,7 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN
final ServiceController<?> controller = currentServiceContainer().getService(JPAServiceNames.getPUServiceName(puScopedName));
final PersistenceUnitServiceImpl persistenceUnitService = (PersistenceUnitServiceImpl) controller.getService();
transactionManager = ContextTransactionManager.getInstance();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) currentServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) currentServiceContainer().getService(JPAServiceNames.TRANSACTION_SYNCHRONIZATION_REGISTRY_SERVICE).getValue();

emf = persistenceUnitService.getEntityManagerFactory();
}
Expand Down
Expand Up @@ -46,12 +46,12 @@
import org.jboss.as.jpa.messages.JpaLogger;
import org.jboss.as.jpa.service.JPAService;
import org.jboss.as.jpa.service.PersistenceUnitServiceImpl;
import org.jboss.as.jpa.util.JPAServiceNames;
import org.jboss.as.naming.ManagedReference;
import org.jboss.as.naming.ManagedReferenceFactory;
import org.jboss.as.naming.ValueManagedReference;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName;
Expand Down Expand Up @@ -155,7 +155,7 @@ public ManagedReference getReference() {
boolean standardEntityManager = ENTITY_MANAGER_CLASS.equals(injectionTypeName);
//TODO: change all this to use injections
//this is currntly safe, as there is a DUP dependency on the TSR
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) serviceRegistry.getRequiredService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) serviceRegistry.getRequiredService(JPAServiceNames.TRANSACTION_SYNCHRONIZATION_REGISTRY_SERVICE).getValue();
TransactionManager transactionManager = ContextTransactionManager.getInstance();
if (type.equals(PersistenceContextType.TRANSACTION)) {
entityManager = new TransactionScopedEntityManager(unitName, properties, emf, synchronizationType, tsr, transactionManager);
Expand Down
Expand Up @@ -41,7 +41,6 @@
import org.jboss.as.server.deployment.JPADeploymentMarker;
import org.jboss.as.server.deployment.SubDeploymentMarker;
import org.jboss.as.server.deployment.module.ResourceRoot;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.metadata.parser.util.NoopXMLResolver;
import org.jboss.vfs.VirtualFile;
import org.jipijapa.plugin.spi.PersistenceUnitMetadata;
Expand Down Expand Up @@ -96,7 +95,7 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro

CapabilityServiceSupport capabilitySupport = phaseContext.getDeploymentUnit().getAttachment(Attachments.CAPABILITY_SERVICE_SUPPORT);
phaseContext.addDeploymentDependency(capabilitySupport.getCapabilityServiceName(JPAServiceNames.LOCAL_TRANSACTION_PROVIDER_CAPABILITY), JpaAttachments.LOCAL_TRANSACTION_PROVIDER);
phaseContext.addDeploymentDependency(TransactionSynchronizationRegistryService.SERVICE_NAME, JpaAttachments.TRANSACTION_SYNCHRONIZATION_REGISTRY);
phaseContext.addDeploymentDependency(capabilitySupport.getCapabilityServiceName(JPAServiceNames.TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY), JpaAttachments.TRANSACTION_SYNCHRONIZATION_REGISTRY);
}

@Override
Expand Down
Expand Up @@ -22,6 +22,7 @@

package org.jboss.as.jpa.util;

import org.jboss.as.controller.ServiceNameFactory;
import org.jboss.msc.service.ServiceName;

/**
Expand All @@ -48,8 +49,19 @@ public static ServiceName getJPAServiceName() {
/**
* Name of the capability that ensures a local provider of transactions is present.
* Once its service is started, calls to the getInstance() methods of ContextTransactionManager,
* ContextTransactionSynchronizationRegistry and LocalUserTransaction can be made knowing
* that the global default TM, TSR and UT will be from that provider.
* and LocalUserTransaction can be made knowing that the global default TM and UT will be from that provider.
*/
public static final String LOCAL_TRANSACTION_PROVIDER_CAPABILITY = "org.wildfly.transactions.global-default-local-provider";

/**
* Name of the capability that ensures a local provider of transactions is present.
* Once its service is started, calls to the getInstance() methods of ContextTransactionManager,
* and LocalUserTransaction can be made knowing that the global default TM and UT will be from that provider.
*/
public static final String TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY = "org.wildfly.transactions.transaction-synchronization-registry";

// This parsing isn't 100% ideal as it's somewhat 'internal' knowledge of the relationship between
// capability names and service names. But at this point that relationship really needs to become
// a contract anyway
public static final ServiceName TRANSACTION_SYNCHRONIZATION_REGISTRY_SERVICE = ServiceNameFactory.parseServiceName(TRANSACTION_SYNCHRONIZATION_REGISTRY_CAPABILITY);
}

0 comments on commit b06a46d

Please sign in to comment.