Skip to content

Commit

Permalink
Add Narayana JTA support
Browse files Browse the repository at this point in the history
Add support for JBoss Narayana.

Fixes spring-projectsgh-5552
  • Loading branch information
Gytis Trikleris authored and philwebb committed Apr 7, 2016
1 parent 1b146f8 commit a2adc5a
Show file tree
Hide file tree
Showing 35 changed files with 2,186 additions and 1 deletion.
10 changes: 10 additions & 0 deletions spring-boot-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,16 @@
<artifactId>jooq</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>jta</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jts</groupId>
<artifactId>narayana-jts-integration</artifactId>
<optional>true</optional>
</dependency>
<!-- Annotation processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
ActiveMQAutoConfiguration.class, HornetQAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
@Import({ JndiJtaConfiguration.class, BitronixJtaConfiguration.class,
AtomikosJtaConfiguration.class })
AtomikosJtaConfiguration.class, NarayanaJtaConfiguration.class })
@EnableConfigurationProperties(JtaProperties.class)
public class JtaAutoConfiguration {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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.springframework.boot.autoconfigure.transaction.jta;

import javax.jms.Message;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import com.arjuna.ats.jbossatx.jta.RecoveryManagerService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.jta.XAConnectionFactoryWrapper;
import org.springframework.boot.jta.XADataSourceWrapper;
import org.springframework.boot.jta.narayana.NarayanaBeanFactoryPostProcessor;
import org.springframework.boot.jta.narayana.NarayanaConfigurationBean;
import org.springframework.boot.jta.narayana.NarayanaProperties;
import org.springframework.boot.jta.narayana.NarayanaRecoveryManagerBean;
import org.springframework.boot.jta.narayana.NarayanaXAConnectionFactoryWrapper;
import org.springframework.boot.jta.narayana.NarayanaXADataSourceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;

/**
* JTA Configuration for <a href="http://narayana.io/">Narayana</a>.
*
* @author <a href="mailto:[email protected]">Gytis Trikleris</a>
*/
@Configuration
@ConditionalOnClass({ JtaTransactionManager.class, com.arjuna.ats.jta.UserTransaction.class })
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public class NarayanaJtaConfiguration {

@Autowired
private JtaProperties jtaProperties;

@Bean
@ConditionalOnMissingBean
public NarayanaProperties narayanaProperties() {
return new NarayanaProperties();
}

@Bean
@ConditionalOnMissingBean
public NarayanaConfigurationBean narayanaConfigurationBean(NarayanaProperties narayanaProperties) {
if (this.jtaProperties.getLogDir() != null) {
narayanaProperties.setLogDir(this.jtaProperties.getLogDir());
}

if (this.jtaProperties.getTransactionManagerId() != null) {
narayanaProperties.setTransactionManagerId(this.jtaProperties.getTransactionManagerId());
}

return new NarayanaConfigurationBean(narayanaProperties);
}

@Bean
@DependsOn("narayanaConfigurationBean")
@ConditionalOnMissingBean
public UserTransaction narayanaUserTransaction() {
return com.arjuna.ats.jta.UserTransaction.userTransaction();
}

@Bean
@DependsOn("narayanaConfigurationBean")
@ConditionalOnMissingBean
public TransactionManager narayanaTransactionManager() {
return com.arjuna.ats.jta.TransactionManager.transactionManager();
}

@Bean
@DependsOn("narayanaConfigurationBean")
public RecoveryManagerService narayanaRecoveryManagerService() {
return new RecoveryManagerService();
}

@Bean
public NarayanaRecoveryManagerBean narayanaRecoveryManagerBean(RecoveryManagerService recoveryManagerService) {
return new NarayanaRecoveryManagerBean(recoveryManagerService);
}

@Bean
public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) {
return new JtaTransactionManager(userTransaction, transactionManager);
}

@Bean
@ConditionalOnMissingBean(XADataSourceWrapper.class)
public XADataSourceWrapper xaDataSourceWrapper(NarayanaRecoveryManagerBean narayanaRecoveryManagerBean,
NarayanaProperties narayanaProperties) {
return new NarayanaXADataSourceWrapper(narayanaRecoveryManagerBean, narayanaProperties);
}

@Bean
@ConditionalOnMissingBean
public static NarayanaBeanFactoryPostProcessor narayanaBeanFactoryPostProcessor() {
return new NarayanaBeanFactoryPostProcessor();
}

@Configuration
@ConditionalOnClass(Message.class)
static class NarayanaJtaJmsConfiguration {

@Bean
@ConditionalOnMissingBean(XAConnectionFactoryWrapper.class)
public NarayanaXAConnectionFactoryWrapper xaConnectionFactoryWrapper(TransactionManager transactionManager,
NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, NarayanaProperties narayanaProperties) {
return new NarayanaXAConnectionFactoryWrapper(transactionManager, narayanaRecoveryManagerBean, narayanaProperties);
}

}

}
32 changes: 32 additions & 0 deletions spring-boot-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@
<webjars-hal-browser.version>9f96c74</webjars-hal-browser.version>
<webjars-locator.version>0.30</webjars-locator.version>
<wsdl4j.version>1.6.3</wsdl4j.version>
<narayana.version>5.3.2.Final</narayana.version>
<jboss-transaction-spi.version>7.3.0.Final</jboss-transaction-spi.version>
</properties>
<prerequisites>
<maven>3.2.1</maven>
Expand Down Expand Up @@ -399,6 +401,11 @@
<artifactId>spring-boot-starter-jta-bitronix</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-narayana</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
Expand Down Expand Up @@ -2212,6 +2219,31 @@
<artifactId>wsdl4j</artifactId>
<version>${wsdl4j.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>jta</artifactId>
<version>${narayana.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>jdbc</artifactId>
<version>${narayana.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>jms</artifactId>
<version>${narayana.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.narayana.jts</groupId>
<artifactId>narayana-jts-integration</artifactId>
<version>${narayana.version}</version>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss-transaction-spi</artifactId>
<version>${jboss-transaction-spi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,19 @@ content into your application; rather pick only the properties that you need.
spring.jta.bitronix.properties.skip-corrupted-logs=false # Skip corrupted transactions log entries.
spring.jta.bitronix.properties.warn-about-zero-resource-transaction=true # Log a warning for transactions executed without a single enlisted resource.
# NARAYANA
spring.jta.narayana.one-phase-commit=true # Enable or disable one phase commit optimisation
spring.jta.narayana.default-timeout=60 # Set default transaction timeout in seconds
spring.jta.narayana.periodic-recovery-period=120 # Set interval in which periodic recovery scans are performed in seconds
spring.jta.narayana.recovery-backoff-period=10 # Set back off period between first and second phases of the recovery scan in seconds
spring.jta.narayana.xa-resource-orphan-filters=com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter,com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter # List of XAResourceOrphanFilter implementations
spring.jta.narayana.recovery-modules=com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule,com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule # List of RecoveryModule implementations
spring.jta.narayana.expiry-scanners=com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner # List of ExpiryScanner implementations
spring.jta.narayana.recovery-db-user= # Database username to be used by recovery manager
spring.jta.narayana.recovery-db-pass= # Database password to be used by recovery manager
spring.jta.narayana.recovery-jms-user= # JMS username to be used by recovery manager
spring.jta.narayana.recovery-jms-pass= # JMS password to be used by recovery manager
# EMBEDDED MONGODB ({sc-spring-boot-autoconfigure}/mongo/embedded/EmbeddedMongoProperties.{sc-ext}[EmbeddedMongoProperties])
spring.mongodb.embedded.features=SYNC_DELAY # Comma-separated list of features to enable.
spring.mongodb.embedded.version=2.6.10 # Version of Mongo to use.
Expand Down
1 change: 1 addition & 0 deletions spring-boot-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<module>spring-boot-sample-jpa</module>
<module>spring-boot-sample-jta-atomikos</module>
<module>spring-boot-sample-jta-bitronix</module>
<module>spring-boot-sample-jta-narayana</module>
<module>spring-boot-sample-jta-jndi</module>
<module>spring-boot-sample-liquibase</module>
<module>spring-boot-sample-logback</module>
Expand Down
57 changes: 57 additions & 0 deletions spring-boot-samples/spring-boot-sample-jta-narayana/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>spring-boot-samples</artifactId>
<groupId>org.springframework.boot</groupId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-jta-narayana</artifactId>
<name>Spring Boot Narayana JTA Sample</name>
<description>Spring Boot Narayana JTA Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-narayana</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-jms-server</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed 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 sample.narayana;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Account {

@Id
@GeneratedValue
private Long id;

private String username;

Account() {
}

public Account(String username) {
this.username = username;
}

public String getUsername() {
return this.username;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed 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 sample.narayana;

import org.springframework.data.jpa.repository.JpaRepository;

public interface AccountRepository extends JpaRepository<Account, Long> {

}
Loading

0 comments on commit a2adc5a

Please sign in to comment.