CXF-8079 Update to introduce the wsat transaction example
diff --git a/distribution/src/main/release/samples/ws_transaction/README.md b/distribution/src/main/release/samples/ws_transaction/README.md
new file mode 100644
index 0000000..795c144
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/README.md
@@ -0,0 +1,40 @@
+CXF Web Service Transaction Demo
+================================
+This demo shows how to use the JTA->WSAT->JTA bridge in the two differnet web services by using the apache-cxf, spring-boot and narayana.
+
+Buiding and running the demo
+----------------------------
+
+From the base directory of this sample you should use maven to build it
+```
+mvn clean install
+```
+
+And open the console to launch the first web service FirstServiceAT
+```
+cd ws_first
+mvn spring-boot:run
+```
+open another console to launch the second web service SecondServiceAT
+```
+cd ws_second
+mvn spring-boot:run
+```
+
+Now you need to run the demo
+```
+cd client
+mvn test -Ptest
+```
+
+JTA->WSAT bridge in the client side
+================
+It can wrap the local transaction and create a bridge between the JTA and WSAT transaction.
+From the client side, we use the *JaxWSTxOutboundBridgeHandler* to create a mapping of the JTA and Subordinate WSAT
+also the *EnabledWSTXHandler* to propagate the WSAT transaction in the SOAP message headers.
+
+WSAT->JTA bridge in the server side
+================
+From the server side, we use the *JaxWSSubordinateHeaderContextProcessor* to import the Subordinate WSAT transaction from the outside
+and the *JaxWSHeaderContextProcessor* to resume the WSAT transaction and the *OptionalJaxWSTxInboundBridgeHandler* to create the bridge
+the WSAT and JTA.
diff --git a/distribution/src/main/release/samples/ws_transaction/client/pom.xml b/distribution/src/main/release/samples/ws_transaction/client/pom.xml
new file mode 100644
index 0000000..2ba4ba1
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/pom.xml
@@ -0,0 +1,38 @@
+<?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>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>ws_transaction</artifactId>
+ <version>3.3.2-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>spring-boot-sample-ws-cxf-client</artifactId>
+ <name>Spring Boot CXF Web Client</name>
+ <description>Spring Boot CXF Web Client</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>spring-boot-sample-ws-cxf-first-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>spring-boot-sample-ws-cxf-second-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/BridgeFromJTATest.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/BridgeFromJTATest.java
new file mode 100644
index 0000000..79049df
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/BridgeFromJTATest.java
@@ -0,0 +1,109 @@
+/**
+ * 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 sample.ws.service;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.transaction.UserTransaction;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = SampleWsApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
+public class BridgeFromJTATest {
+
+ @Autowired
+ private UserTransaction ut;
+
+ private FirstServiceAT firstClient;
+ private SecondServiceAT secondClient;
+
+
+ @Before
+ public void setUp() throws Exception {
+ firstClient = FirstClient.newInstance();
+ secondClient = SecondClient.newInstance();
+ }
+
+ @After
+ public void teardownTest() throws Exception {
+ rollbackIfActive(ut);
+ try {
+ ut.begin();
+ firstClient.resetCounter();
+ secondClient.resetCounter();
+ ut.commit();
+ } finally {
+ rollbackIfActive(ut);
+ }
+ }
+
+
+ @Test
+ public void testCommit() throws Exception {
+ ut.begin();
+ firstClient.incrementCounter(1);
+ secondClient.incrementCounter(1);
+ ut.commit();
+
+ ut.begin();
+ int counter1 = firstClient.getCounter();
+ int counter2 = secondClient.getCounter();
+ ut.commit();
+
+ Assert.assertEquals(1, counter1);
+ Assert.assertEquals(1, counter2);
+ }
+
+ @Test
+ public void testClientDrivenRollback() throws Exception {
+ ut.begin();
+ firstClient.incrementCounter(1);
+ secondClient.incrementCounter(1);
+ ut.rollback();
+
+ ut.begin();
+ int counter1 = firstClient.getCounter();
+ int counter2 = secondClient.getCounter();
+ ut.commit();
+
+ Assert.assertEquals(0, counter1);
+ Assert.assertEquals(0, counter2);
+ }
+
+
+ /**
+ * Utility method for rolling back a transaction if it is currently active.
+ *
+ * @param ut The User Business Activity to cancel.
+ */
+ private void rollbackIfActive(UserTransaction ut) {
+ try {
+ ut.rollback();
+ } catch (Throwable th2) {
+ // do nothing, not active
+ }
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/FirstClient.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/FirstClient.java
new file mode 100644
index 0000000..557faec
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/FirstClient.java
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import com.arjuna.mw.wst11.client.EnabledWSTXHandler;
+import org.jboss.jbossts.txbridge.outbound.JaxWSTxOutboundBridgeHandler;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Service;
+import javax.xml.ws.handler.Handler;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+public class FirstClient {
+ public static FirstServiceAT newInstance() throws Exception {
+ URL wsdlLocation = new URL("http://localhost:8081/Service/FirstServiceAT?wsdl");
+ QName serviceName = new QName("http://service.ws.sample", "FirstServiceATService");
+ QName portName = new QName("http://service.ws.sample", "FirstServiceAT");
+
+ Service service = Service.create(wsdlLocation, serviceName);
+ FirstServiceAT client = service.getPort(portName, FirstServiceAT.class);
+
+ List<Handler> handlerChain = new ArrayList<>();
+ JaxWSTxOutboundBridgeHandler txOutboundBridgeHandler = new JaxWSTxOutboundBridgeHandler();
+ EnabledWSTXHandler wstxHandler = new EnabledWSTXHandler();
+
+ handlerChain.add(txOutboundBridgeHandler);
+ handlerChain.add(wstxHandler);
+
+ ((BindingProvider)client).getBinding().setHandlerChain(handlerChain);
+
+ return client;
+ }
+
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SampleWsApplication.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SampleWsApplication.java
new file mode 100644
index 0000000..8ee5578
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SampleWsApplication.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+
+@SpringBootApplication
+public class SampleWsApplication {
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SecondClient.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SecondClient.java
new file mode 100644
index 0000000..e945431
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/SecondClient.java
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import com.arjuna.mw.wst11.client.EnabledWSTXHandler;
+import org.jboss.jbossts.txbridge.outbound.JaxWSTxOutboundBridgeHandler;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Service;
+import javax.xml.ws.handler.Handler;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+public class SecondClient {
+ public static SecondServiceAT newInstance() throws Exception {
+ URL wsdlLocation = new URL("http://localhost:8082/Service/SecondServiceAT?wsdl");
+ QName serviceName = new QName("http://service.ws.sample", "SecondServiceATService");
+ QName portName = new QName("http://service.ws.sample", "SecondServiceAT");
+
+ Service service = Service.create(wsdlLocation, serviceName);
+ SecondServiceAT client = service.getPort(portName, SecondServiceAT.class);
+
+
+ List<Handler> handlerChain = new ArrayList<>();
+ JaxWSTxOutboundBridgeHandler txOutboundBridgeHandler = new JaxWSTxOutboundBridgeHandler();
+ EnabledWSTXHandler wstxHandler = new EnabledWSTXHandler();
+
+ handlerChain.add(txOutboundBridgeHandler);
+ handlerChain.add(wstxHandler);
+
+ ((BindingProvider)client).getBinding().setHandlerChain(handlerChain);
+
+ return client;
+ }
+
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/WebServiceConfig.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/WebServiceConfig.java
new file mode 100644
index 0000000..eb4fe76
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/WebServiceConfig.java
@@ -0,0 +1,51 @@
+/**
+ * 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 sample.ws.service;
+
+import com.arjuna.webservices11.wsat.sei.CoordinatorPortTypeImpl;
+import com.arjuna.webservices11.wscoor.sei.RegistrationPortTypeImpl;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.xml.ws.Endpoint;
+
+@Configuration
+public class WebServiceConfig {
+
+ @Autowired
+ private Bus bus;
+
+ @Bean
+ public Endpoint registration() {
+ EndpointImpl endpoint = new EndpointImpl(bus, new RegistrationPortTypeImpl());
+ endpoint.publish("/ws-c11/RegistrationService");
+ return endpoint;
+ }
+
+ @Bean
+ public Endpoint coordinator() {
+ EndpointImpl endpoint = new EndpointImpl(bus, new CoordinatorPortTypeImpl());
+ endpoint.publish("/ws-t11-coordinator/CoordinatorService");
+ return endpoint;
+
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/XTSConfig.java b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/XTSConfig.java
new file mode 100644
index 0000000..5a5aa66
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/java/sample/ws/service/XTSConfig.java
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import org.jboss.jbossts.XTSService;
+import org.jboss.jbossts.txbridge.outbound.OutboundBridgeRecoveryManager;
+import org.jboss.jbossts.xts.environment.XTSEnvironmentBean;
+import org.jboss.jbossts.xts.environment.XTSPropertyManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+@Configuration
+public class XTSConfig {
+ @Bean(name = "xtsService", initMethod = "start", destroyMethod = "stop")
+ public XTSService xtsService() {
+
+ XTSEnvironmentBean xtsEnvironmentBean = XTSPropertyManager.getXTSEnvironmentBean();
+ //xtsEnvironmentBean.setXtsInitialisations();
+
+ XTSService service = new XTSService();
+ return service;
+ }
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @DependsOn({"xtsService"})
+ public OutboundBridgeRecoveryManager outboundBridgeRecoveryManager() {
+ return new OutboundBridgeRecoveryManager();
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/client/src/test/resources/application.properties b/distribution/src/main/release/samples/ws_transaction/client/src/test/resources/application.properties
new file mode 100644
index 0000000..e7592bf
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/client/src/test/resources/application.properties
@@ -0,0 +1,2 @@
+narayana.log-dir=./target/narayana/
+cxf.path=/
diff --git a/distribution/src/main/release/samples/ws_transaction/pom.xml b/distribution/src/main/release/samples/ws_transaction/pom.xml
new file mode 100644
index 0000000..82f89c0
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<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>
+ <artifactId>ws_transaction</artifactId>
+ <name>Spring Boot CXF Web Services Transaction Sample</name>
+ <description>Spring Boot CXF Web Services Transaction Sample</description>
+ <parent>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>cxf-samples</artifactId>
+ <version>3.3.3-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <properties>
+ <spring.boot.version>2.1.3.RELEASE</spring.boot.version>
+ <cxf.version>${project.version}</cxf.version>
+ <narayana.spring.boot.version>2.1.0</narayana.spring.boot.version>
+ <narayana.version>5.9.0.Final</narayana.version>
+ <version.org.jboss.ws>1.0.2.Final</version.org.jboss.ws>
+ <jbossws-cxf.version>5.2.4.Final</jbossws-cxf.version>
+ </properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <!-- Import dependency management from Spring Boot -->
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring.boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-features-logging</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
+ <version>${cxf.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>me.snowdrop</groupId>
+ <artifactId>narayana-spring-boot-starter</artifactId>
+ <version>${narayana.spring.boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.narayana.xts</groupId>
+ <artifactId>jbossxts</artifactId>
+ <version>${narayana.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.narayana</groupId>
+ <artifactId>jbosstxbridge</artifactId>
+ <version>${narayana.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.ws</groupId>
+ <artifactId>jbossws-api</artifactId>
+ <version>${version.org.jboss.ws}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.ws.cxf</groupId>
+ <artifactId>jbossws-cxf-client</artifactId>
+ <version>${jbossws-cxf.version}</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-jpa</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>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web-services</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <modules>
+ <module>ws_first</module>
+ <module>ws_second</module>
+ <module>client</module>
+ </modules>
+ <profiles>
+ <profile>
+ <id>test</id>
+ <properties>
+ <maven.test.skip>false</maven.test.skip>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/pom.xml b/distribution/src/main/release/samples/ws_transaction/ws_first/pom.xml
new file mode 100644
index 0000000..7d3a050
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/pom.xml
@@ -0,0 +1,31 @@
+<?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>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>ws_transaction</artifactId>
+ <version>3.3.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>spring-boot-sample-ws-cxf-first-service</artifactId>
+ <name>Spring Boot CXF First Web Services</name>
+ <description>Spring Boot CXF First Web Services</description>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.boot.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/SampleWsApplication.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/SampleWsApplication.java
new file mode 100644
index 0000000..1abe821
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/SampleWsApplication.java
@@ -0,0 +1,30 @@
+/**
+ * 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 sample.ws;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+@SpringBootApplication
+public class SampleWsApplication {
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(SampleWsApplication.class, args);
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/WebServiceConfig.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/WebServiceConfig.java
new file mode 100644
index 0000000..dc89a03
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/WebServiceConfig.java
@@ -0,0 +1,55 @@
+/**
+ * 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 sample.ws;
+
+import javax.xml.ws.Endpoint;
+
+import com.arjuna.webservices11.wsat.sei.ParticipantPortTypeImpl;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.EndpointImpl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import sample.ws.service.FirstServiceATImpl;
+
+@Configuration
+public class WebServiceConfig {
+
+ @Autowired
+ private Bus bus;
+
+ @Autowired
+ private FirstServiceATImpl impl;
+
+ @Bean
+ public Endpoint endpoint() {
+ EndpointImpl endpoint = new EndpointImpl(bus, impl);
+ endpoint.publish("/Service/FirstServiceAT");
+ return endpoint;
+ }
+
+ @Bean
+ public Endpoint participant() {
+ EndpointImpl endpoint = new EndpointImpl(bus, new ParticipantPortTypeImpl());
+ endpoint.publish("/ws-t11-participant/ParticipantService");
+ return endpoint;
+ }
+
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/XTSConfig.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/XTSConfig.java
new file mode 100644
index 0000000..7bde8b8
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/XTSConfig.java
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws;
+
+import org.jboss.jbossts.XTSService;
+import org.jboss.jbossts.txbridge.inbound.InboundBridgeRecoveryManager;
+import org.jboss.jbossts.xts.environment.WSCEnvironmentBean;
+import org.jboss.jbossts.xts.environment.XTSEnvironmentBean;
+import org.jboss.jbossts.xts.environment.XTSPropertyManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+@Configuration
+public class XTSConfig {
+ @Value( "${server.port}" )
+ private int port;
+
+ @Bean(name = "xtsService", initMethod = "start", destroyMethod = "stop")
+ public XTSService xtsService() {
+ WSCEnvironmentBean wscEnvironmentBean = XTSPropertyManager.getWSCEnvironmentBean();
+ wscEnvironmentBean.setBindPort11(port);
+
+ XTSService service = new XTSService();
+ return service;
+ }
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @DependsOn({"xtsService"})
+ public InboundBridgeRecoveryManager inboundBridgeRecoveryManager() {
+ return new InboundBridgeRecoveryManager();
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounter.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounter.java
new file mode 100644
index 0000000..a1b8c97
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounter.java
@@ -0,0 +1,65 @@
+/**
+ * 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 sample.ws.service;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+@Entity
+@Table(name = "t_counter")
+public class FirstCounter implements Serializable {
+
+ private int id;
+ private int counter;
+
+ public FirstCounter() {
+ }
+
+ public FirstCounter(int id, int initialCounterValue) {
+ this.id = id;
+ this.counter = initialCounterValue;
+ }
+
+ @Id
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getCounter() {
+ return counter;
+ }
+
+ public void setCounter(int counter) {
+ this.counter = counter;
+ }
+
+ public void incrementCounter(int howMany) {
+ setCounter(getCounter() + howMany);
+ }
+}
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounterRepository.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounterRepository.java
new file mode 100644
index 0000000..24deea4
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstCounterRepository.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+public interface FirstCounterRepository extends CrudRepository<FirstCounter, Integer> {
+
+}
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceAT.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceAT.java
new file mode 100644
index 0000000..74e66ec
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceAT.java
@@ -0,0 +1,51 @@
+/**
+ * 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 sample.ws.service;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+@WebService(name = "FirstServiceAT", targetNamespace = "http://service.ws.sample/")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface FirstServiceAT {
+
+ /**
+ * Create a new booking
+ */
+ @WebMethod
+ public void incrementCounter(int numSeats);
+
+ /**
+ * obtain the number of existing bookings
+ *
+ * @return the number of current bookings
+ */
+ @WebMethod
+ public int getCounter();
+
+ /**
+ * Reset the booking count to zero
+ */
+ @WebMethod
+ public void resetCounter();
+
+}
+
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceATImpl.java b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceATImpl.java
new file mode 100644
index 0000000..7de1bd8
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/java/sample/ws/service/FirstServiceATImpl.java
@@ -0,0 +1,88 @@
+/**
+ * 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 sample.ws.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.jws.HandlerChain;
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.transaction.Transactional;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+@Service
+@WebService(serviceName = "FirstServiceATService", portName = "FirstServiceAT", name = "FirstServiceAT", targetNamespace = "http://service.ws.sample")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+@HandlerChain(file = "/wstx_handlers.xml")
+@Transactional(Transactional.TxType.MANDATORY) // default is REQUIRED
+public class FirstServiceATImpl implements FirstServiceAT {
+
+ private static final Integer ENTITY_ID = 1;
+
+ private static final Logger LOG = Logger.getLogger(FirstServiceATImpl.class.getName());
+
+ @Autowired
+ private FirstCounterRepository service;
+
+ /**
+ * Incriment the first counter. This is done by updating the counter within a JTA transaction. The JTA transaction
+ * was automatically bridged from the WS-AT transaction.
+ */
+ @WebMethod
+ public void incrementCounter(int num) {
+
+ LOG.info("[SERVICE] First service invoked to increment the counter by '" + num + "'");
+
+ // invoke the backend business logic:
+ LOG.info("[SERVICE] Using the JPA Entity Manager to update the counter within a JTA transaction");
+
+ FirstCounter counter = lookupCounterEntity();
+ counter.incrementCounter(num);
+ service.save(counter);
+ }
+
+ @WebMethod
+ public int getCounter() {
+ LOG.info("[SERVICE] getCounter() invoked");
+ FirstCounter counter = lookupCounterEntity();
+
+ return counter.getCounter();
+ }
+
+ @WebMethod
+ public void resetCounter() {
+ FirstCounter counter = lookupCounterEntity();
+ counter.setCounter(0);
+ service.save(counter);
+ }
+
+ private FirstCounter lookupCounterEntity() {
+ Optional<FirstCounter> counter = service.findById(ENTITY_ID);
+ if (counter.isPresent()) {
+ return counter.get();
+ } else {
+ FirstCounter first = new FirstCounter(ENTITY_ID, 0);
+ service.save(first);
+ return first;
+ }
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/application.properties b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/application.properties
new file mode 100644
index 0000000..921cc2f
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+server.port=8081
+
+spring.datasource.url=jdbc:h2:file:./target/first
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.open-in-view=true
+spring.data.jpa.repositories.bootstrap-mode=default
+
+narayana.log-dir=./target/narayana/
+
+cxf.path=/
+
+logging.level.org.hibernate.SQL=debug
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/wstx_handlers.xml b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/wstx_handlers.xml
new file mode 100644
index 0000000..2f565dd
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_first/src/main/resources/wstx_handlers.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<handler-chains xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
+ <handler-chain>
+ <handler>
+ <handler-name>BridgeHandler</handler-name>
+ <handler-class>org.jboss.jbossts.txbridge.inbound.OptionalJaxWSTxInboundBridgeHandler</handler-class>
+ </handler>
+ <handler>
+ <handler-name>WSTXHandler</handler-name>
+ <handler-class>com.arjuna.mw.wst11.service.JaxWSHeaderContextProcessor</handler-class>
+ </handler>
+ <handler>
+ <handler-name>SubordinateHandler</handler-name>
+ <handler-class>com.arjuna.mw.wst11.service.JaxWSSubordinateHeaderContextProcessor</handler-class>
+ </handler>
+ </handler-chain>
+</handler-chains>
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/pom.xml b/distribution/src/main/release/samples/ws_transaction/ws_second/pom.xml
new file mode 100644
index 0000000..f6b4df1
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/pom.xml
@@ -0,0 +1,31 @@
+<?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>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>ws_transaction</artifactId>
+ <version>3.3.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>spring-boot-sample-ws-cxf-second-service</artifactId>
+ <name>Spring Boot CXF Second Web Services</name>
+ <description>Spring Boot CXF Second Web Services</description>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.boot.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/SampleWsApplication.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/SampleWsApplication.java
new file mode 100644
index 0000000..1abe821
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/SampleWsApplication.java
@@ -0,0 +1,30 @@
+/**
+ * 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 sample.ws;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+@SpringBootApplication
+public class SampleWsApplication {
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(SampleWsApplication.class, args);
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/WebServiceConfig.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/WebServiceConfig.java
new file mode 100644
index 0000000..4f7be18
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/WebServiceConfig.java
@@ -0,0 +1,54 @@
+/**
+ * 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 sample.ws;
+
+import javax.xml.ws.Endpoint;
+
+import com.arjuna.webservices11.wsat.sei.ParticipantPortTypeImpl;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.EndpointImpl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import sample.ws.service.SecondServiceATImpl;
+
+@Configuration
+public class WebServiceConfig {
+
+ @Autowired
+ private Bus bus;
+
+ @Autowired
+ private SecondServiceATImpl impl;
+
+ @Bean
+ public Endpoint endpoint() {
+ EndpointImpl endpoint = new EndpointImpl(bus, impl);
+ endpoint.publish("/Service/SecondServiceAT");
+ return endpoint;
+ }
+
+ @Bean
+ public Endpoint participant() {
+ EndpointImpl endpoint = new EndpointImpl(bus, new ParticipantPortTypeImpl());
+ endpoint.publish("/ws-t11-participant/ParticipantService");
+ return endpoint;
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/XTSConfig.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/XTSConfig.java
new file mode 100644
index 0000000..abd6078
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/XTSConfig.java
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws;
+
+import org.jboss.jbossts.XTSService;
+import org.jboss.jbossts.txbridge.inbound.InboundBridgeRecoveryManager;
+import org.jboss.jbossts.xts.environment.WSCEnvironmentBean;
+import org.jboss.jbossts.xts.environment.XTSEnvironmentBean;
+import org.jboss.jbossts.xts.environment.XTSPropertyManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+@Configuration
+public class XTSConfig {
+ @Value( "${server.port}" )
+ private int port;
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ public XTSService xtsService() {
+ WSCEnvironmentBean wscEnvironmentBean = XTSPropertyManager.getWSCEnvironmentBean();
+ wscEnvironmentBean.setBindPort11(port);
+
+ XTSService service = new XTSService();
+ return service;
+ }
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @DependsOn({"xtsService"})
+ public InboundBridgeRecoveryManager inboundBridgeRecoveryManager() {
+ return new InboundBridgeRecoveryManager();
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounter.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounter.java
new file mode 100644
index 0000000..3f0ad31
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounter.java
@@ -0,0 +1,65 @@
+/**
+ * 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 sample.ws.service;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+@Entity
+@Table(name = "t_counter")
+public class SecondCounter implements Serializable {
+
+ private int id;
+ private int counter;
+
+ public SecondCounter() {
+ }
+
+ public SecondCounter(int id, int initialCounterValue) {
+ this.id = id;
+ this.counter = initialCounterValue;
+ }
+
+ @Id
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getCounter() {
+ return counter;
+ }
+
+ public void setCounter(int counter) {
+ this.counter = counter;
+ }
+
+ public void incrementCounter(int howMany) {
+ setCounter(getCounter() + howMany);
+ }
+}
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounterRepository.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounterRepository.java
new file mode 100644
index 0000000..cd0c5ad
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondCounterRepository.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2019, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package sample.ws.service;
+
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * @author <a href="mailto:zfeng@redhat.com">Zheng Feng</a>
+ */
+public interface SecondCounterRepository extends CrudRepository<SecondCounter, Integer> {
+
+}
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceAT.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceAT.java
new file mode 100644
index 0000000..e81e5e6
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceAT.java
@@ -0,0 +1,51 @@
+/**
+ * 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 sample.ws.service;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+@WebService(name = "SecondServiceAT", targetNamespace = "http://service.ws.sample/")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+public interface SecondServiceAT {
+
+ /**
+ * Create a new booking
+ */
+ @WebMethod
+ public void incrementCounter(int numSeats);
+
+ /**
+ * obtain the number of existing bookings
+ *
+ * @return the number of current bookings
+ */
+ @WebMethod
+ public int getCounter();
+
+ /**
+ * Reset the booking count to zero
+ */
+ @WebMethod
+ public void resetCounter();
+
+}
+
+
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceATImpl.java b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceATImpl.java
new file mode 100644
index 0000000..8a2a275
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/java/sample/ws/service/SecondServiceATImpl.java
@@ -0,0 +1,88 @@
+/**
+ * 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 sample.ws.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.jws.HandlerChain;
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.transaction.Transactional;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+@Service
+@WebService(serviceName = "SecondServiceATService", portName = "SecondServiceAT", name = "SecondServiceAT", targetNamespace = "http://service.ws.sample")
+@SOAPBinding(style = SOAPBinding.Style.RPC)
+@HandlerChain(file = "/wstx_handlers.xml")
+@Transactional(Transactional.TxType.MANDATORY) // default is REQUIRED
+public class SecondServiceATImpl implements SecondServiceAT {
+
+ private static final Integer ENTITY_ID = 1;
+
+ private static final Logger LOG = Logger.getLogger(SecondServiceATImpl.class.getName());
+
+ @Autowired
+ private SecondCounterRepository service;
+
+ /**
+ * Incriment the first counter. This is done by updating the counter within a JTA transaction. The JTA transaction
+ * was automatically bridged from the WS-AT transaction.
+ */
+ @WebMethod
+ public void incrementCounter(int num) {
+
+ LOG.info("[SERVICE] Second service invoked to increment the counter by '" + num + "'");
+
+ // invoke the backend business logic:
+ LOG.info("[SERVICE] Using the JPA Entity Manager to update the counter within a JTA transaction");
+
+ SecondCounter counter = lookupCounterEntity();
+ counter.incrementCounter(num);
+ service.save(counter);
+ }
+
+ @WebMethod
+ public int getCounter() {
+ LOG.info("[SERVICE] getCounter() invoked");
+ SecondCounter counter = lookupCounterEntity();
+
+ return counter.getCounter();
+ }
+
+ @WebMethod
+ public void resetCounter() {
+ SecondCounter counter = lookupCounterEntity();
+ counter.setCounter(0);
+ service.save(counter);
+ }
+
+ private SecondCounter lookupCounterEntity() {
+ Optional<SecondCounter> counter = service.findById(ENTITY_ID);
+ if (counter.isPresent()) {
+ return counter.get();
+ } else {
+ SecondCounter second = new SecondCounter(ENTITY_ID, 0);
+ service.save(second);
+ return second;
+ }
+ }
+}
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/application.properties b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/application.properties
new file mode 100644
index 0000000..167cee8
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+server.port=8082
+
+spring.datasource.url=jdbc:h2:file:./target/second
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.open-in-view=true
+spring.data.jpa.repositories.bootstrap-mode=default
+
+narayana.log-dir=./target/narayana/
+
+cxf.path=/
+
+logging.level.org.hibernate.SQL=debug
diff --git a/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/wstx_handlers.xml b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/wstx_handlers.xml
new file mode 100644
index 0000000..2f565dd
--- /dev/null
+++ b/distribution/src/main/release/samples/ws_transaction/ws_second/src/main/resources/wstx_handlers.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<handler-chains xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
+ <handler-chain>
+ <handler>
+ <handler-name>BridgeHandler</handler-name>
+ <handler-class>org.jboss.jbossts.txbridge.inbound.OptionalJaxWSTxInboundBridgeHandler</handler-class>
+ </handler>
+ <handler>
+ <handler-name>WSTXHandler</handler-name>
+ <handler-class>com.arjuna.mw.wst11.service.JaxWSHeaderContextProcessor</handler-class>
+ </handler>
+ <handler>
+ <handler-name>SubordinateHandler</handler-name>
+ <handler-class>com.arjuna.mw.wst11.service.JaxWSSubordinateHeaderContextProcessor</handler-class>
+ </handler>
+ </handler-chain>
+</handler-chains>