├── .gitignore ├── LICENSE ├── README.md ├── connector ├── LICENSE ├── README.md ├── genericconnector-api │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ ├── BasicTransactionAssistanceFactory.java │ │ ├── CommitRollbackCallback.java │ │ ├── ExecuteCallback.java │ │ ├── TransactionAssistanceFactory.java │ │ └── TransactionAssistant.java ├── genericconnector-atomikos-api │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ ├── BasicTransactionAssistanceFactoryImpl.java │ │ │ └── TransactionConfigurator.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── BasicTransactionAssistanceFactoryImplTest.java ├── genericconnector-atomikos-impl │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ ├── AtomikosTransactionAssistantImpl.java │ │ │ └── RecoverableMSResource.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── AtomikosTransactionAssistantImplTest.java ├── genericconnector-bitronix-api │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ └── TransactionConfigurator.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── BitronixTransactionConfiguratorTest.java ├── genericconnector-bitronix-impl │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ ├── MicroserviceResourceFactory.java │ │ │ ├── MicroserviceResourceHolder.java │ │ │ └── MicroserviceResourceProducer.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── MicroserviceResourceProducerTest.java ├── genericconnector-impl │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ ├── AbstractTransactionAssistanceXAResource.java │ │ │ ├── GenericResourceAdapter.java │ │ │ ├── ManagedTransactionAssistance.java │ │ │ ├── ManagedTransactionAssistanceFactory.java │ │ │ ├── ManagedTransactionAssistanceMetaData.java │ │ │ ├── TransactionAssistanceFactoryImpl.java │ │ │ ├── TransactionAssistanceXAResource.java │ │ │ ├── TransactionAssistantImpl.java │ │ │ ├── UnderlyingConnection.java │ │ │ └── XidImpl.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ ├── GenericResourceAdapterTest.java │ │ └── MiniContainer.java ├── genericconnector-javase-common-api │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ch │ │ │ └── maxant │ │ │ └── generic_jca_adapter │ │ │ ├── MicroserviceXAResource.java │ │ │ └── UnderlyingConnectionImpl.java │ │ └── test │ │ └── java │ │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── MicroserviceXAResourceTest.java ├── genericconnector-parent │ ├── LICENSE │ ├── README.md │ └── pom.xml └── genericconnector-rar │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── pom.xml │ └── src │ └── main │ ├── docs │ ├── background.jpg │ ├── blog.html │ ├── blog2.html │ ├── connector-accessingEIS.gif │ ├── desert.css │ ├── doxy.css │ ├── facebook01.png │ ├── facebook02.png │ ├── facebook03.png │ ├── facebook04.png │ ├── presentation.ppt │ ├── prettify.css │ ├── run_prettify.js │ ├── sons-of-obsidian.css │ ├── sunburst.css │ ├── tagcrowd.png │ ├── worditout.jpg │ ├── worditout.png │ └── worditout.xcf │ └── java │ └── META-INF │ ├── MANIFEST.MF │ ├── __unused__ironjacamar.xml │ └── __unused__ra.xml └── demo ├── LICENSE ├── README.md ├── docker ├── Dockerfile_acquirer ├── Dockerfile_bookingsystem ├── Dockerfile_letter ├── Dockerfile_wildfly820 ├── README.md ├── genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT.war ├── genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT.war └── genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT.war ├── genericconnector-demo-common ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ └── resources │ └── wsdl │ ├── acquirerWebServiceWsdl.xml │ ├── bookingSystemWebServiceWsdl.xml │ └── letterWebServiceWsdl.xml ├── genericconnector-demo-javaee-client ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── jca_demo │ │ └── client │ │ ├── IntegrationLayer.java │ │ ├── ResourceServlet.java │ │ ├── SomeServiceThatBindsResourcesIntoTransaction.java │ │ ├── SomeServiceThatBindsResourcesIntoTransaction_JavaSE6.java │ │ ├── TransactionAssistanceSetup.java │ │ └── TransactionAssistanceSetup_JavaSE6.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── genericconnector-demo-javaee-ear ├── .gitignore ├── LICENSE ├── README.md └── pom.xml ├── genericconnector-demo-parent ├── LICENSE ├── README.md └── pom.xml ├── genericconnector-demo-springboot-atomikos ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── demo │ │ ├── BaseMain.java │ │ ├── Config.java │ │ └── DemoSpringBootServerAtomikos.java │ └── resources │ ├── application.properties │ └── log4j.properties ├── genericconnector-demo-springboot-bitronix ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── demo │ │ ├── BaseMain.java │ │ ├── Config.java │ │ └── DemoSpringBootServerBitronix.java │ └── resources │ ├── application.properties │ └── log4j.properties ├── genericconnector-demo-springboot-common ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── ch │ └── maxant │ └── generic_jca_adapter │ └── demo │ ├── Account.java │ ├── AppController.java │ ├── AppRepository.java │ └── AppService.java ├── genericconnector-demo-standalone-atomikos ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ ├── TestAtomikos.java │ │ └── demo │ │ └── Main.java │ └── resources │ └── log4j.properties ├── genericconnector-demo-standalone-bitronix ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── demo │ │ └── Main.java │ └── resources │ ├── bitronix-default-config.properties │ ├── bitronix-res.properties │ └── log4j.properties ├── genericconnector-demo-tomcat-atomikos ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── demo │ │ └── CreateUserServlet.java │ ├── resources │ └── META-INF │ │ └── context.xml │ └── webapp │ └── WEB-INF │ └── web.xml ├── genericconnector-demo-tomcat-bitronix ├── LICENSE ├── README.md ├── add-to-tomcat │ ├── bin │ │ ├── bitronix-default-config.properties │ │ ├── bitronix-res.properties │ │ └── log4j.properties │ └── conf │ │ └── server.xml-pieces.xml ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── generic_jca_adapter │ │ └── demo │ │ └── CreateUserServlet.java │ ├── resources │ └── META-INF │ │ └── context.xml │ └── webapp │ └── WEB-INF │ └── web.xml ├── genericconnector-demo-webservice-acquirer ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── jca_demo │ │ └── acquirer │ │ ├── AcquirerWebService.java │ │ └── LogView.java │ └── webapp │ └── WEB-INF │ └── web.xml ├── genericconnector-demo-webservice-bookingsystem ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── ch │ │ └── maxant │ │ └── jca_demo │ │ └── bookingsystem │ │ ├── BookingSystemWebService.java │ │ └── LogView.java │ └── webapp │ └── WEB-INF │ └── web.xml └── genericconnector-demo-webservice-letter ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main ├── java └── ch │ └── maxant │ └── jca_demo │ └── letterwriter │ ├── LetterWebService.java │ └── LogView.java └── webapp └── WEB-INF └── web.xml /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.class 2 | **/target 3 | **/build 4 | **/.settings 5 | **/.project 6 | **/.classpath 7 | btm1.tlog 8 | btm2.tlog 9 | tmlog*.log 10 | *.tm*.epoch 11 | exec*.txt 12 | 13 | -------------------------------------------------------------------------------- /connector/genericconnector-api/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /connector/genericconnector-api/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector API 2 | 3 | This module contains the interfaces which clients use. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-api/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-parent 9 | 10 | genericconnector-api 11 | jar 12 | 13 | 14 | -------------------------------------------------------------------------------- /connector/genericconnector-api/src/main/java/ch/maxant/generic_jca_adapter/BasicTransactionAssistanceFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.resource.ResourceException; 20 | 21 | /** 22 | * The resource injected into say a Servlet or EJB. Used to bind a call to a resource, e.g. a microservice, into 23 | * the active XA transaction. 24 | */ 25 | public interface BasicTransactionAssistanceFactory { 26 | 27 | /** 28 | * Get transaction assistant from factory so that a callback can be 29 | * bound into the transaction as well as recovery which is controlled 30 | * by the app server's transaction manager. 31 | * @exception ResourceException Thrown if an assistant can't be obtained 32 | */ 33 | TransactionAssistant getTransactionAssistant() throws ResourceException; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /connector/genericconnector-api/src/main/java/ch/maxant/generic_jca_adapter/CommitRollbackCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * WARNING: the implementation of this class must be thread safe, as multiple threads will call it concurrently! 23 | */ 24 | public interface CommitRollbackCallback extends Serializable { 25 | 26 | /** The container will call this function 27 | * to commit a transaction that was successful. 28 | * The implementation of this method should 29 | * call the EIS in order to commit 30 | * the transaction. */ 31 | void commit(String txid) throws Exception; 32 | 33 | /** The container will call this function 34 | * to rollback an unsuccessful transaction. 35 | * The implementation of this method should 36 | * call the EIS in order to rollback 37 | * the transaction. */ 38 | void rollback(String txid) throws Exception; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /connector/genericconnector-api/src/main/java/ch/maxant/generic_jca_adapter/ExecuteCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | 20 | /** 21 | * Client code should implement this interface in order to 22 | * bind a resource into an XA transaction. 23 | */ 24 | public interface ExecuteCallback { 25 | 26 | /** The container calls this method in order 27 | * to call a business method on the EIS, 28 | * within a global transaction. */ 29 | O execute(String txid) throws Exception; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /connector/genericconnector-api/src/main/java/ch/maxant/generic_jca_adapter/TransactionAssistant.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | 20 | /** 21 | * An interface capable of binding something into a transaction. 22 | * (The factory creates these.) */ 23 | public interface TransactionAssistant extends AutoCloseable { 24 | 25 | /** Submit some work (a function) to be bound into the 26 | * currently active transaction. */ 27 | O executeInActiveTransaction(ExecuteCallback tc) throws Exception; 28 | 29 | /** Call before completing the transaction in order 30 | * to free up resources used by the app server. */ 31 | @Override 32 | void close(); 33 | } -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-api/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Atomikos API 2 | 3 | This module contains the additional interfaces which clients use, when the transaction manager is Atomikos and the client code is running outside of a JCA compatible container, for example in a Java SE application, a simple Web Container or something like a Spring Boot application. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-api/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-parent 9 | 10 | genericconnector-atomikos-api 11 | jar 12 | 13 | 14 | ${project.groupId} 15 | genericconnector-api 16 | ${project.version} 17 | 18 | 19 | ${project.groupId} 20 | genericconnector-atomikos-impl 21 | ${project.version} 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-api/src/main/java/ch/maxant/generic_jca_adapter/BasicTransactionAssistanceFactoryImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.resource.ResourceException; 20 | import javax.transaction.Status; 21 | import javax.transaction.Transaction; 22 | 23 | import com.atomikos.icatch.jta.UserTransactionManager; 24 | 25 | /** Use this class to build a {@link TransactionAssistant}. Analagous to the factory 26 | * normally fetched from JNDI, but Atomikos doesn't appear to ship with an out-of-the-box 27 | * JNDI context like Bitronix does. For that reason, just instantiate one of these, in 28 | * order to create new TransactionAssistants. */ 29 | public class BasicTransactionAssistanceFactoryImpl implements BasicTransactionAssistanceFactory { 30 | 31 | private String jndiName; 32 | 33 | /** 34 | * @param jndiName the name of the resource that this factory represents, eg the name of the microservice which this factory is in charge of 35 | * committing, rolling back and recovering. 36 | */ 37 | public BasicTransactionAssistanceFactoryImpl(String jndiName) { 38 | this.jndiName = jndiName; 39 | } 40 | 41 | /** before calling this method, please ensure you have called {@link TransactionConfigurator#setup(String, CommitRollbackCallback)} */ 42 | @Override 43 | public TransactionAssistant getTransactionAssistant() throws ResourceException { 44 | //enlist a new resource into the transaction. it will be delisted, when its closed. 45 | final CommitRollbackCallback commitRollbackCallback = TransactionConfigurator.getCommitRollbackCallback(jndiName); 46 | MicroserviceXAResource ms = new MicroserviceXAResource(jndiName, commitRollbackCallback); 47 | UserTransactionManager utm = getTM(); 48 | try { 49 | if(utm.getStatus() == Status.STATUS_NO_TRANSACTION){ 50 | throw new ResourceException("no transaction found. please start one before getting the transaction assistant. status was: " + utm.getStatus()); 51 | } 52 | Transaction tx = utm.getTransaction(); 53 | tx.enlistResource(ms); 54 | return new AtomikosTransactionAssistantImpl(ms); 55 | } catch (Exception e) { 56 | throw new ResourceException("Unable to get transaction status", e); 57 | } 58 | } 59 | 60 | protected UserTransactionManager getTM() { 61 | return new UserTransactionManager(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-api/src/main/java/ch/maxant/generic_jca_adapter/TransactionConfigurator.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.File; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import com.atomikos.icatch.config.UserTransactionServiceImp; 24 | 25 | /** Class used to setup the {@link CommitRollbackCallback} to be used for the given unique JNDI name. */ 26 | public final class TransactionConfigurator { 27 | 28 | private TransactionConfigurator() {} 29 | 30 | private static Map resources = new HashMap(); 31 | 32 | /** one time configuration required for setting up a microservice in a transactional environment. */ 33 | public static void setup(String jndiName, final CommitRollbackCallback commitRollbackCallback){ 34 | UserTransactionServiceImp utsi = new UserTransactionServiceImp(); 35 | MicroserviceXAResource ms = new MicroserviceXAResource(jndiName, commitRollbackCallback); 36 | RecoverableMSResource resource = new RecoverableMSResource(ms); 37 | resources.put(jndiName, resource); 38 | utsi.registerResource(resource); 39 | } 40 | 41 | /** when your application shutsdown, you should unregister all services that were setup using {@link #setup(String, CommitRollbackHandler)} 42 | * or {@link #setup(String, CommitRollbackHandler, long, File)} */ 43 | public static void unregisterMicroserviceResourceFactory(String name) { 44 | UserTransactionServiceImp utsi = new UserTransactionServiceImp(); 45 | utsi.removeResource(resources.remove(name)); 46 | } 47 | 48 | /** @return the {@link CommitRollbackCallback} registered during setup, or null, if none found (eg never registered, or unregistered). */ 49 | static CommitRollbackCallback getCommitRollbackCallback(String jndiName){ 50 | RecoverableMSResource rr = resources.get(jndiName); 51 | if(rr != null){ 52 | return rr.getMicroserviceResource().getUnderlyingConnection(); 53 | } 54 | return null; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-api/src/test/java/ch/maxant/generic_jca_adapter/BasicTransactionAssistanceFactoryImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertNull; 21 | import static org.junit.Assert.fail; 22 | import static org.mockito.Mockito.mock; 23 | import static org.mockito.Mockito.verify; 24 | import static org.mockito.Mockito.when; 25 | 26 | import javax.resource.ResourceException; 27 | import javax.transaction.RollbackException; 28 | import javax.transaction.Status; 29 | import javax.transaction.SystemException; 30 | import javax.transaction.Transaction; 31 | import javax.transaction.xa.XAResource; 32 | 33 | import org.junit.Test; 34 | import org.mockito.ArgumentCaptor; 35 | 36 | import com.atomikos.icatch.jta.UserTransactionManager; 37 | 38 | public class BasicTransactionAssistanceFactoryImplTest { 39 | 40 | @Test 41 | public void testSuccessAll() throws ResourceException, IllegalStateException, RollbackException, SystemException { 42 | 43 | CommitRollbackCallback callback = new CommitRollbackCallback() { 44 | private static final long serialVersionUID = 1L; 45 | @Override 46 | public void rollback(String txid) throws Exception { 47 | } 48 | @Override 49 | public void commit(String txid) throws Exception { 50 | } 51 | }; 52 | final UserTransactionManager tm = mock(UserTransactionManager.class); 53 | when(tm.getStatus()).thenReturn(Status.STATUS_ACTIVE); 54 | Transaction tx = mock(Transaction.class); 55 | when(tm.getTransaction()).thenReturn(tx); 56 | 57 | //TEST 58 | TransactionConfigurator.setup("a", callback); 59 | 60 | BasicTransactionAssistanceFactory f = new BasicTransactionAssistanceFactoryImpl("a"){ 61 | @Override 62 | protected UserTransactionManager getTM() { 63 | return tm; 64 | } 65 | }; 66 | 67 | //TEST 68 | f.getTransactionAssistant(); 69 | 70 | //ensure its enlisted 71 | ArgumentCaptor c = ArgumentCaptor.forClass(XAResource.class); 72 | verify(tx).enlistResource(c.capture()); 73 | assertEquals(MicroserviceXAResource.class, c.getValue().getClass()); 74 | assertEquals("a", ((MicroserviceXAResource)c.getValue()).getJndiName()); 75 | 76 | TransactionConfigurator.unregisterMicroserviceResourceFactory("a"); 77 | 78 | assertNull(TransactionConfigurator.getCommitRollbackCallback("a")); 79 | } 80 | 81 | @Test 82 | public void testNoTX() throws ResourceException, IllegalStateException, RollbackException, SystemException { 83 | final UserTransactionManager tm = mock(UserTransactionManager.class); 84 | when(tm.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); 85 | 86 | BasicTransactionAssistanceFactory f = new BasicTransactionAssistanceFactoryImpl("a"){ 87 | @Override 88 | protected UserTransactionManager getTM() { 89 | return tm; 90 | } 91 | }; 92 | 93 | try{ 94 | //TEST 95 | f.getTransactionAssistant(); 96 | fail("no exception"); 97 | }catch(ResourceException e){ 98 | //OK, expected 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-impl/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Atomikos Implementation 2 | 3 | This module contains the additional implementation which clients must have on the classpath, when the transaction manager is Atomikos and the client code is running outside of a JCA compatible container, for example in a Java SE application, a simple Web Container or something like a Spring Boot application. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-impl/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | ch.maxant 7 | genericconnector-parent 8 | 2.1.1-SNAPSHOT 9 | ../genericconnector-parent 10 | 11 | genericconnector-atomikos-impl 12 | jar 13 | 14 | 15 | 16 | ch.maxant 17 | genericconnector-javase-common 18 | ${project.version} 19 | 20 | 21 | com.atomikos 22 | transactions-osgi 23 | 3.9.3 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-impl/src/main/java/ch/maxant/generic_jca_adapter/AtomikosTransactionAssistantImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.transaction.Status; 20 | import javax.transaction.Transaction; 21 | import javax.transaction.xa.XAResource; 22 | 23 | import com.atomikos.icatch.jta.UserTransactionManager; 24 | 25 | class AtomikosTransactionAssistantImpl implements TransactionAssistant { 26 | 27 | private MicroserviceXAResource ms; 28 | 29 | AtomikosTransactionAssistantImpl(MicroserviceXAResource ms) { 30 | this.ms = ms; 31 | } 32 | 33 | @Override 34 | public O executeInActiveTransaction(ExecuteCallback c) throws Exception { 35 | return ms.executeInActiveTransaction(c); 36 | } 37 | 38 | @Override 39 | public void close() { 40 | UserTransactionManager utm = getTransactionManager(); 41 | try { 42 | if(utm.getStatus() == Status.STATUS_NO_TRANSACTION){ 43 | throw new RuntimeException("no transaction found. please start one before getting the transaction assistant. status was: " + utm.getStatus()); 44 | } 45 | Transaction tx = utm.getTransaction(); 46 | tx.delistResource(ms, ms.getUnderlyingConnection().wasExecuteSuccessful() ? XAResource.TMSUCCESS : XAResource.TMFAIL); 47 | } catch (Exception e) { 48 | throw new RuntimeException("Unable to delist resource from transaction", e); 49 | } 50 | } 51 | 52 | protected UserTransactionManager getTransactionManager() { 53 | return new UserTransactionManager(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-impl/src/main/java/ch/maxant/generic_jca_adapter/RecoverableMSResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.transaction.xa.XAResource; 20 | 21 | import com.atomikos.datasource.ResourceException; 22 | import com.atomikos.datasource.xa.XATransactionalResource; 23 | 24 | class RecoverableMSResource extends XATransactionalResource { 25 | 26 | private MicroserviceXAResource ms; 27 | 28 | RecoverableMSResource(MicroserviceXAResource ms) { 29 | super(ms.getJndiName()); 30 | this.ms = ms; 31 | } 32 | 33 | @Override 34 | protected XAResource refreshXAConnection() throws ResourceException { 35 | return ms; 36 | } 37 | 38 | MicroserviceXAResource getMicroserviceResource() { 39 | return ms; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /connector/genericconnector-atomikos-impl/src/test/java/ch/maxant/generic_jca_adapter/AtomikosTransactionAssistantImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.fail; 21 | import static org.mockito.Matchers.eq; 22 | import static org.mockito.Mockito.mock; 23 | import static org.mockito.Mockito.times; 24 | import static org.mockito.Mockito.verify; 25 | import static org.mockito.Mockito.when; 26 | 27 | import java.util.concurrent.atomic.AtomicInteger; 28 | 29 | import javax.transaction.Transaction; 30 | import javax.transaction.xa.XAResource; 31 | import javax.transaction.xa.Xid; 32 | 33 | import org.junit.Test; 34 | 35 | import com.atomikos.icatch.jta.UserTransactionManager; 36 | 37 | public class AtomikosTransactionAssistantImplTest { 38 | 39 | @Test 40 | public void testCloseDelistsResource_Success() throws Exception { 41 | testCloseDelistsResource(XAResource.TMSUCCESS); 42 | } 43 | 44 | @Test 45 | public void testCloseDelistsResource_Fail() throws Exception { 46 | testCloseDelistsResource(XAResource.TMFAIL); 47 | } 48 | 49 | private void testCloseDelistsResource(final int result) throws Exception { 50 | final UserTransactionManager tm = mock(UserTransactionManager.class); 51 | final Transaction tx = mock(Transaction.class); 52 | when(tm.getTransaction()).thenReturn(tx); 53 | MicroserviceXAResource ms = getMs(); 54 | final AtomicInteger count = new AtomicInteger(); 55 | ms.start(getXid(), 0); 56 | AtomikosTransactionAssistantImpl impl = new AtomikosTransactionAssistantImpl(ms){ 57 | @Override 58 | protected UserTransactionManager getTransactionManager() { 59 | return tm; 60 | } 61 | }; 62 | 63 | try{ 64 | //TEST 65 | impl.executeInActiveTransaction(new ExecuteCallback() { 66 | @Override 67 | public Void execute(String txid) throws Exception { 68 | count.incrementAndGet(); 69 | if(result == XAResource.TMSUCCESS){ 70 | return null; //no exception => TMSUCCESS 71 | }else{ 72 | throw new Exception(); // => TMFAIL 73 | } 74 | } 75 | }); 76 | if(result == XAResource.TMFAIL) fail("no exception"); 77 | }catch(Exception e){ 78 | if(result == XAResource.TMSUCCESS) fail("exception not expected"); 79 | } 80 | 81 | //TEST 82 | impl.close(); 83 | 84 | assertEquals(1, count.get()); 85 | verify(tx, times(1)).delistResource(eq(ms), eq(result)); 86 | } 87 | 88 | private MicroserviceXAResource getMs() { 89 | MicroserviceXAResource ms = new MicroserviceXAResource("a", new CommitRollbackCallback() { 90 | private static final long serialVersionUID = 1L; 91 | @Override 92 | public void rollback(String txid) throws Exception { 93 | } 94 | @Override 95 | public void commit(String txid) throws Exception { 96 | } 97 | }); 98 | return ms; 99 | } 100 | 101 | private Xid getXid() { 102 | return new Xid() { 103 | @Override 104 | public byte[] getGlobalTransactionId() { 105 | return "gtxid".getBytes(); 106 | } 107 | @Override 108 | public int getFormatId() { 109 | return 1; 110 | } 111 | @Override 112 | public byte[] getBranchQualifier() { 113 | return "bq".getBytes(); 114 | } 115 | }; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-api/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Atomikos API 2 | 3 | This module contains the additional interfaces which clients use, when the transaction manager is Bitronix and the client code is running outside of a JCA compatible container, for example in a Java SE application, a simple Web Container or something like a Spring Boot application. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-api/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-parent 9 | 10 | genericconnector-bitronix-api 11 | jar 12 | 13 | 14 | ${project.groupId} 15 | genericconnector-api 16 | ${project.version} 17 | 18 | 19 | ${project.groupId} 20 | genericconnector-bitronix-impl 21 | ${project.version} 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-api/src/main/java/ch/maxant/generic_jca_adapter/TransactionConfigurator.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.File; 20 | 21 | public final class TransactionConfigurator { 22 | 23 | private TransactionConfigurator() {} 24 | 25 | /** one time configuration required for setting up a microservice in a transactional environment. */ 26 | public static void setup(final String jndiName, final CommitRollbackCallback commitRollbackCallback){ 27 | MicroserviceResourceProducer.registerMicroserviceResourceFactory(jndiName, new MicroserviceResourceFactory() { 28 | @Override 29 | public MicroserviceXAResource build() { 30 | MicroserviceXAResource msr = new MicroserviceXAResource(jndiName, new UnderlyingConnectionImpl() { 31 | private static final long serialVersionUID = 1L; 32 | @Override 33 | public void rollback(String txid) throws Exception { 34 | commitRollbackCallback.rollback(txid); 35 | } 36 | @Override 37 | public void commit(String txid) throws Exception { 38 | commitRollbackCallback.commit(txid); 39 | } 40 | }); 41 | return msr; 42 | } 43 | }); 44 | } 45 | 46 | /** when your application shutsdown, you should unregister all services that were setup using {@link #setup(String, CommitRollbackHandler)} 47 | * or {@link #setup(String, CommitRollbackHandler, long, File)} */ 48 | public static void unregisterMicroserviceResourceFactory(String name) { 49 | MicroserviceResourceProducer.unregisterMicroserviceResourceFactory(name); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-api/src/test/java/ch/maxant/generic_jca_adapter/BitronixTransactionConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import bitronix.tm.resource.ResourceRegistrar; 25 | 26 | public class BitronixTransactionConfiguratorTest { 27 | 28 | @Before 29 | public void setup(){ 30 | //clean up 31 | for(String name : ResourceRegistrar.getResourcesUniqueNames()){ 32 | MicroserviceResourceProducer.unregisterMicroserviceResourceFactory(name); 33 | } 34 | } 35 | 36 | @Test 37 | public void test() { 38 | assertEquals(0, MicroserviceResourceProducer.getProducers().size()); 39 | assertEquals(0, ResourceRegistrar.getResourcesUniqueNames().size()); 40 | 41 | //TEST 42 | TransactionConfigurator.setup("a", new CommitRollbackCallback() { 43 | private static final long serialVersionUID = 1L; 44 | @Override 45 | public void rollback(String txid) throws Exception { 46 | } 47 | @Override 48 | public void commit(String txid) throws Exception { 49 | } 50 | }); 51 | 52 | assertEquals(1, MicroserviceResourceProducer.getProducers().size()); 53 | assertEquals("a", MicroserviceResourceProducer.getProducers().keySet().iterator().next()); 54 | assertEquals(1, ResourceRegistrar.getResourcesUniqueNames().size()); 55 | 56 | 57 | //TEST 58 | TransactionConfigurator.unregisterMicroserviceResourceFactory("a"); 59 | 60 | assertEquals(0, MicroserviceResourceProducer.getProducers().size()); 61 | assertEquals(0, ResourceRegistrar.getResourcesUniqueNames().size()); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-impl/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Atomikos Implementation 2 | 3 | This module contains the additional implementation which clients must have on the classpath, when the transaction manager is Bitronix and the client code is running outside of a JCA compatible container, for example in a Java SE application, a simple Web Container or something like a Spring Boot application. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-impl/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | ch.maxant 7 | genericconnector-parent 8 | 2.1.1-SNAPSHOT 9 | ../genericconnector-parent 10 | 11 | genericconnector-bitronix-impl 12 | jar 13 | 14 | 15 | 16 | ch.maxant 17 | genericconnector-javase-common 18 | ${project.version} 19 | 20 | 21 | org.codehaus.btm 22 | btm 23 | 2.1.4 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-impl/src/main/java/ch/maxant/generic_jca_adapter/MicroserviceResourceFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | interface MicroserviceResourceFactory { 20 | 21 | MicroserviceXAResource build(); 22 | } 23 | -------------------------------------------------------------------------------- /connector/genericconnector-bitronix-impl/src/main/java/ch/maxant/generic_jca_adapter/MicroserviceResourceHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.util.Arrays; 20 | import java.util.Date; 21 | import java.util.List; 22 | 23 | import javax.transaction.xa.XAResource; 24 | 25 | import bitronix.tm.resource.common.AbstractXAResourceHolder; 26 | import bitronix.tm.resource.common.ResourceBean; 27 | import bitronix.tm.resource.common.XAResourceHolder; 28 | import bitronix.tm.resource.ehcache.EhCacheXAResourceHolder; 29 | 30 | /** based on {@link EhCacheXAResourceHolder} */ 31 | class MicroserviceResourceHolder extends AbstractXAResourceHolder { 32 | 33 | private final XAResource resource; 34 | private final ResourceBean bean; 35 | 36 | /** 37 | * Create a new MicroserviceResourceHolder for a particular XAResource 38 | * 39 | * @param resource 40 | * the required XAResource 41 | * @param bean 42 | * the required ResourceBean 43 | */ 44 | MicroserviceResourceHolder(XAResource resource, ResourceBean bean) { 45 | this.resource = resource; 46 | this.bean = bean; 47 | } 48 | 49 | /** 50 | * {@inheritDoc} 51 | */ 52 | @Override 53 | public XAResource getXAResource() { 54 | return resource; 55 | } 56 | 57 | /** 58 | * {@inheritDoc} 59 | */ 60 | @Override 61 | public ResourceBean getResourceBean() { 62 | return bean; 63 | } 64 | 65 | /** 66 | * {@inheritDoc} 67 | */ 68 | @Override 69 | public void close() throws Exception { 70 | throw new UnsupportedOperationException("MicroserviceResourceHolder cannot be used with an XAPool"); 71 | } 72 | 73 | /** 74 | * {@inheritDoc} 75 | */ 76 | @Override 77 | public Object getConnectionHandle() throws Exception { 78 | throw new UnsupportedOperationException("MicroserviceResourceHolder cannot be used with an XAPool"); 79 | } 80 | 81 | /** 82 | * {@inheritDoc} 83 | */ 84 | @Override 85 | public Date getLastReleaseDate() { 86 | throw new UnsupportedOperationException("MicroserviceResourceHolder cannot be used with an XAPool"); 87 | } 88 | 89 | /** 90 | * {@inheritDoc} 91 | */ 92 | @Override 93 | public List getXAResourceHolders() { 94 | return Arrays.asList((XAResourceHolder) this); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Implementation 2 | 3 | Module containing implementation classes of the resource adapter. Does not interest client code except that it must be on the classpath. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-parent 9 | 10 | genericconnector-impl 11 | jar 12 | 13 | 14 | 15 | ch.maxant 16 | genericconnector-api 17 | ${project.version} 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/GenericResourceAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import javax.resource.ResourceException; 25 | import javax.resource.spi.ActivationSpec; 26 | import javax.resource.spi.BootstrapContext; 27 | import javax.resource.spi.Connector; 28 | import javax.resource.spi.ResourceAdapter; 29 | import javax.resource.spi.ResourceAdapterInternalException; 30 | import javax.resource.spi.TransactionSupport.TransactionSupportLevel; 31 | import javax.resource.spi.endpoint.MessageEndpointFactory; 32 | import javax.transaction.xa.XAResource; 33 | 34 | import ch.maxant.generic_jca_adapter.TransactionAssistanceFactory.CommitRollbackRecoveryCallback; 35 | 36 | /** A resource adapter able to bind callbacks into XA */ 37 | @Connector(licenseRequired=true, transactionSupport = TransactionSupportLevel.XATransaction) 38 | public class GenericResourceAdapter implements ResourceAdapter { 39 | 40 | private final Logger log = Logger.getLogger(this.getClass().getName()); 41 | 42 | private Map commitRollbackRecoveryCallbacks = new HashMap(); 43 | 44 | @Override 45 | public void endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) throws ResourceException { 46 | log.log(Level.INFO, "activating endpoint"); 47 | } 48 | 49 | @Override 50 | public void endpointDeactivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) { 51 | log.log(Level.INFO, "deactivating endpoint"); 52 | } 53 | 54 | @Override 55 | public void start(BootstrapContext ctx) throws ResourceAdapterInternalException { 56 | log.log(Level.INFO, "starting resource adapter"); 57 | } 58 | 59 | @Override 60 | public void stop() { 61 | log.log(Level.INFO, "stopping resource adapter"); 62 | } 63 | 64 | @Override 65 | public XAResource[] getXAResources(ActivationSpec[] specs) throws ResourceException { 66 | log.log(Level.INFO, "getting xa resources"); 67 | //TODO never seen this method called by Jboss! therefore: 68 | throw new ResourceException("not supported - altho we can if its necessary..."); 69 | //TODO is returning one enough? 70 | //return new XAResource[]{new TransactionAssistanceXAResource(new ManagedTransactionAssistance())}; 71 | } 72 | 73 | @Override 74 | public int hashCode() { 75 | return 69; 76 | } 77 | 78 | @Override 79 | public boolean equals(Object obj) { 80 | if (this == obj) 81 | return true; 82 | if (obj == null) 83 | return false; 84 | if (getClass() != obj.getClass()) 85 | return false; 86 | return true; 87 | } 88 | 89 | /** client code can register a callback to enable commit, rollback and recovery */ 90 | synchronized void registerCommitRollbackRecovery(String managedConnectionFactoryId, CommitRollbackRecoveryCallback commitRollbackRecoveryCallback) { 91 | if(this.commitRollbackRecoveryCallbacks.containsKey(managedConnectionFactoryId)){ 92 | throw new IllegalStateException("Unable to register commit/rollback/recovery for managed connection factory with ID '" + managedConnectionFactoryId + "', because a callback has already been registered. Please unregister it first!"); 93 | } 94 | this.commitRollbackRecoveryCallbacks.put(managedConnectionFactoryId, commitRollbackRecoveryCallback); 95 | } 96 | 97 | /** client code can unregister the callback which was registered using {@link #registerCommitRollbackRecovery(String, CommitRollbackRecoveryCallback)} */ 98 | synchronized void unregisterCommitRollbackRecovery(String managedConnectionFactoryId){ 99 | this.commitRollbackRecoveryCallbacks.remove(managedConnectionFactoryId); 100 | } 101 | 102 | /** get the callback registered using {@link #registerCommitRollbackRecovery(String, CommitRollbackRecoveryCallback)} */ 103 | CommitRollbackRecoveryCallback getCommitRollbackRecoveryCallback(String managedConnectionFactoryId) { 104 | return commitRollbackRecoveryCallbacks.get(managedConnectionFactoryId); 105 | } 106 | } -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/ManagedTransactionAssistanceMetaData.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.resource.spi.ManagedConnectionMetaData; 20 | 21 | public class ManagedTransactionAssistanceMetaData implements ManagedConnectionMetaData { 22 | 23 | @Override public String getEISProductName() { return "maxant Generic Resource Adapter"; } 24 | 25 | @Override public String getEISProductVersion() { return "2.0"; } 26 | 27 | @Override public int getMaxConnections() { return 0; } 28 | 29 | @Override public String getUserName() { return null; } 30 | 31 | } -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/TransactionAssistanceFactoryImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.util.logging.Level; 20 | import java.util.logging.Logger; 21 | 22 | import javax.naming.Reference; 23 | import javax.resource.ResourceException; 24 | import javax.resource.spi.ConnectionManager; 25 | 26 | public class TransactionAssistanceFactoryImpl implements TransactionAssistanceFactory { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | private final Logger log = Logger.getLogger(this.getClass().getName()); 31 | 32 | private Reference reference; 33 | 34 | private ManagedTransactionAssistanceFactory mcf; 35 | 36 | private ConnectionManager cxManager; 37 | 38 | public TransactionAssistanceFactoryImpl(ManagedTransactionAssistanceFactory mcf, ConnectionManager cxManager) { 39 | this.mcf = mcf; 40 | this.cxManager = cxManager; 41 | } 42 | 43 | @Override 44 | public TransactionAssistant getTransactionAssistant() throws ResourceException { 45 | log.log(Level.INFO, "allocating connection"); 46 | return (TransactionAssistant) cxManager.allocateConnection(mcf, null); 47 | } 48 | 49 | @Override 50 | public void registerCommitRollbackRecovery( 51 | CommitRollbackRecoveryCallback commitRollbackRecoveryCallback) { 52 | ((GenericResourceAdapter)this.mcf.getResourceAdapter()).registerCommitRollbackRecovery(mcf.getId(), commitRollbackRecoveryCallback); 53 | } 54 | 55 | @Override 56 | public void unregisterCommitRollbackRecovery() { 57 | ((GenericResourceAdapter)this.mcf.getResourceAdapter()).unregisterCommitRollbackRecovery(mcf.getId()); 58 | } 59 | 60 | @Override 61 | public Reference getReference() { 62 | return reference; 63 | } 64 | 65 | @Override 66 | public void setReference(Reference reference) { 67 | this.reference = reference; 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/TransactionAssistanceXAResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.File; 20 | import java.util.logging.Level; 21 | 22 | import javax.resource.ResourceException; 23 | import javax.transaction.xa.XAException; 24 | import javax.transaction.xa.XAResource; 25 | 26 | /** 27 | * {@link XAResource} used by the transaction assistance JCA Adapter to bind callbacks 28 | * into transactions. Used by Java EE. 29 | */ 30 | public class TransactionAssistanceXAResource extends AbstractTransactionAssistanceXAResource { 31 | 32 | private static final long serialVersionUID = 1L; 33 | 34 | /** the resource related to this {@link XAResource} */ 35 | private ManagedTransactionAssistance conn; 36 | 37 | public TransactionAssistanceXAResource(ManagedTransactionAssistance conn) { 38 | this.conn = conn; 39 | } 40 | 41 | @Override 42 | protected long getMinAgeOfTransactionBeforeRelevantForRecovery() { 43 | return conn.getMinAgeOfTransactionBeforeRelevantForRecovery(); 44 | } 45 | 46 | @Override 47 | protected File getRecoveryStatePersistenceDirectory() { 48 | return conn.getRecoveryStatePersistenceDirectory(); 49 | } 50 | 51 | @Override 52 | protected boolean isHandleRecoveryInternally() { 53 | return conn.isHandleRecoveryInternally(); 54 | } 55 | 56 | @Override 57 | protected UnderlyingConnection getUnderlyingConnection() { 58 | return new UnderlyingConnection() { 59 | private static final long serialVersionUID = 1L; 60 | 61 | @Override 62 | public void rollback(String txid) throws Exception { 63 | conn.getCommitRollbackRecoveryCallback().rollback(txid); 64 | } 65 | 66 | @Override 67 | public void commit(String txid) throws Exception { 68 | conn.getCommitRollbackRecoveryCallback().commit(txid); 69 | } 70 | 71 | @Override 72 | public boolean wasExecuteSuccessful() { 73 | return conn.wasExecuteSuccessful(); 74 | } 75 | 76 | @Override 77 | public void setCurrentTxId(String txId) { 78 | conn.setCurrentTxId(txId); 79 | } 80 | 81 | @Override 82 | public String[] getTransactionsInNeedOfRecovery() { 83 | return conn.getCommitRollbackRecoveryCallback().getTransactionsInNeedOfRecovery(); 84 | } 85 | 86 | @Override 87 | public void cleanup() throws ResourceException { 88 | conn.cleanup(); 89 | } 90 | }; 91 | } 92 | 93 | @Override 94 | public boolean isSameRM(XAResource xares) throws XAException { 95 | log.log(Level.FINEST, "isSameRM " + xares); 96 | 97 | //TODO hmm not sure about this 98 | 99 | if(xares instanceof TransactionAssistanceXAResource){ 100 | TransactionAssistanceXAResource other = (TransactionAssistanceXAResource) xares; 101 | if(this.conn.getManagedConnectionFactoryId().equals(other.conn.getManagedConnectionFactoryId())){ 102 | return true; 103 | } 104 | } 105 | return false; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/TransactionAssistantImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | public class TransactionAssistantImpl implements TransactionAssistant { 20 | 21 | /** this implementation of hte TransactionAsssistant simply 22 | * delegates to this managed transaction assistance instance */ 23 | private ManagedTransactionAssistance mc; 24 | 25 | public TransactionAssistantImpl(ManagedTransactionAssistance mc) { 26 | this.mc = mc; 27 | } 28 | 29 | @Override 30 | public O executeInActiveTransaction(ExecuteCallback tc) throws Exception { 31 | return mc.execute(tc); 32 | } 33 | 34 | @Override 35 | public void close() { 36 | mc.close(this); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/UnderlyingConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import javax.resource.ResourceException; 20 | 21 | public interface UnderlyingConnection extends CommitRollbackCallback { 22 | 23 | void cleanup() throws ResourceException; 24 | 25 | boolean wasExecuteSuccessful(); 26 | 27 | /** only needs to be implemented when recovery is not handled internally */ 28 | String[] getTransactionsInNeedOfRecovery(); 29 | 30 | void setCurrentTxId(String s); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /connector/genericconnector-impl/src/main/java/ch/maxant/generic_jca_adapter/XidImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.ByteArrayInputStream; 20 | import java.io.ByteArrayOutputStream; 21 | import java.io.IOException; 22 | import java.io.ObjectInputStream; 23 | import java.io.ObjectOutputStream; 24 | import java.util.Base64; 25 | 26 | import javax.transaction.xa.Xid; 27 | 28 | /** An implementation of Xid transaction IDs which uses base 64 to 29 | make the IDs HTTP friendly - i.e. they can be transported across 30 | HTTP connections. */ 31 | public class XidImpl implements Xid { 32 | 33 | private byte[] gtid; 34 | private int fid; 35 | private byte[] bq; 36 | 37 | public XidImpl(byte[] gtid, int fid, byte[] bq) { 38 | this.gtid = gtid; 39 | this.fid = fid; 40 | this.bq = bq; 41 | } 42 | 43 | @Override 44 | public byte[] getBranchQualifier() { 45 | return bq; 46 | } 47 | 48 | @Override 49 | public int getFormatId() { 50 | return fid; 51 | } 52 | 53 | @Override 54 | public byte[] getGlobalTransactionId() { 55 | return gtid; 56 | } 57 | 58 | /** gets a log friendly / web service friendly version of the global transaction ID */ 59 | @Override 60 | public String toString(){ 61 | return asString(this); 62 | } 63 | 64 | /** gets a log friendly / web service friendly version (base 64) of the global transaction ID 65 | * @param xidImpl */ 66 | public static String asString(Xid xid){ 67 | try { 68 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 69 | ObjectOutputStream oos = new ObjectOutputStream(baos); 70 | oos.writeObject(new Object[]{xid.getBranchQualifier(), xid.getGlobalTransactionId(), xid.getFormatId()}); 71 | return Base64.getEncoder().encodeToString(baos.toByteArray()); 72 | } catch (IOException e) { 73 | throw new RuntimeException("Failed to marshal xid " + xid, e); 74 | } 75 | } 76 | 77 | /** @return Convert a (base 64 encoded) string into an Xid. */ 78 | public static Xid getXid(String base64) { 79 | try{ 80 | byte[] decoded = Base64.getDecoder().decode(base64); 81 | ByteArrayInputStream bais = new ByteArrayInputStream(decoded); 82 | ObjectInputStream ois = new ObjectInputStream(bais); 83 | Object[] o = (Object[]) ois.readObject(); 84 | byte[] branchQualifier = (byte[]) o[0]; 85 | byte[] gtid = (byte[]) o[1]; 86 | int formatId = (Integer) o[2]; 87 | 88 | return new XidImpl(gtid, formatId, branchQualifier); 89 | } catch (ClassNotFoundException e){ 90 | //should never ever happen 91 | throw new RuntimeException("Failed to unmarshal xid " + base64, e); 92 | } catch (IOException e) { 93 | //should never ever happen 94 | throw new RuntimeException("Failed to unmarshal xid " + base64, e); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /connector/genericconnector-javase-common-api/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector Java SE Common 2 | 3 | Contains classes common to Bitronix and Atomikos implementations. Must be on the classpath if running a Standalone, Tomcat, Jetty, Spring or Spring Boot application. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /connector/genericconnector-javase-common-api/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | ch.maxant 7 | genericconnector-parent 8 | 2.1.1-SNAPSHOT 9 | ../genericconnector-parent 10 | 11 | genericconnector-javase-common 12 | jar 13 | 14 | 15 | 16 | ch.maxant 17 | genericconnector-impl 18 | ${project.version} 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /connector/genericconnector-javase-common-api/src/main/java/ch/maxant/generic_jca_adapter/MicroserviceXAResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.File; 20 | import java.util.logging.Level; 21 | 22 | import javax.transaction.xa.XAException; 23 | import javax.transaction.xa.XAResource; 24 | 25 | /** the XA resource used by Java SE */ 26 | public class MicroserviceXAResource extends AbstractTransactionAssistanceXAResource { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | private final UnderlyingConnectionImpl underlyingConnection; 31 | 32 | /** how old do transactions have to be before we consider cleaning them up? 33 | * since recovery runs async, we need to be careful not to start recovering something thats still active! 34 | * TODO could we ask BTM for the active transactions, and skip those ones? */ 35 | private static long minAgeOfTransactionInMSBeforeRelevantForRecovery = 30000L; 36 | 37 | /** where should we store our information about transaction state? */ 38 | private static File recoveryStatePersistenceDirectory = new File("."); 39 | 40 | private String jndiName; 41 | 42 | MicroserviceXAResource(String jndiName, final CommitRollbackCallback commitRollbackCallback) { 43 | this.jndiName = jndiName; 44 | this.underlyingConnection = new UnderlyingConnectionImpl() { 45 | private static final long serialVersionUID = 1L; 46 | @Override 47 | public void rollback(String txid) throws Exception { 48 | commitRollbackCallback.rollback(txid); 49 | } 50 | @Override 51 | public void commit(String txid) throws Exception { 52 | commitRollbackCallback.commit(txid); 53 | } 54 | }; 55 | } 56 | 57 | @Override 58 | protected long getMinAgeOfTransactionBeforeRelevantForRecovery() { 59 | return minAgeOfTransactionInMSBeforeRelevantForRecovery; 60 | } 61 | 62 | @Override 63 | protected File getRecoveryStatePersistenceDirectory() { 64 | return recoveryStatePersistenceDirectory; 65 | } 66 | 67 | @Override 68 | protected UnderlyingConnection getUnderlyingConnection() { 69 | return underlyingConnection; 70 | } 71 | 72 | @Override 73 | public boolean isSameRM(XAResource xares) throws XAException { 74 | log.log(Level.FINEST, "isSameRM " + xares); 75 | 76 | if(xares instanceof MicroserviceXAResource){ 77 | MicroserviceXAResource other = (MicroserviceXAResource) xares; 78 | if(this.jndiName.equals(other.jndiName)){ 79 | return true; 80 | } 81 | } 82 | return false; 83 | // TODO hmm not sure about this 84 | } 85 | 86 | /** execute the given callback in the active transaction */ 87 | O executeInActiveTransaction(ExecuteCallback c) throws Exception { 88 | return underlyingConnection.execute(c, recoveryStatePersistenceDirectory); 89 | } 90 | 91 | /** setup the location of where recovery state is stored, and how old it must be before recovery is attempted. defaults are the working directory and 30 seconds. */ 92 | public static void configure(long minAgeOfTransactionInMSBeforeRelevantForRecovery, File recoveryStatePersistenceDirectory){ 93 | MicroserviceXAResource.minAgeOfTransactionInMSBeforeRelevantForRecovery = minAgeOfTransactionInMSBeforeRelevantForRecovery; 94 | MicroserviceXAResource.recoveryStatePersistenceDirectory = recoveryStatePersistenceDirectory; 95 | } 96 | 97 | String getJndiName() { 98 | return jndiName; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /connector/genericconnector-javase-common-api/src/main/java/ch/maxant/generic_jca_adapter/UnderlyingConnectionImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.io.Serializable; 22 | import java.nio.charset.StandardCharsets; 23 | import java.nio.file.Files; 24 | 25 | abstract class UnderlyingConnectionImpl implements UnderlyingConnection, Serializable { 26 | 27 | private static final long serialVersionUID = 1L; 28 | 29 | private Boolean wasExecuteSuccessful = null; 30 | private String currentTxId = null; 31 | 32 | /** Calls the callback to do some work bound into the transaction. 33 | * Tracks transaction state internally if necessary. */ 34 | protected O execute(ExecuteCallback c, File recoveryStatePersistenceDirectory) throws Exception { 35 | if(currentTxId == null) throw new IllegalStateException("XID not yet set - was transaction started?"); 36 | if(wasExecuteSuccessful != null) throw new IllegalStateException("not closed?"); 37 | 38 | persistTransactionState(recoveryStatePersistenceDirectory); 39 | 40 | try{ 41 | O o = c.execute(currentTxId); 42 | wasExecuteSuccessful = true; 43 | return o; 44 | }catch(Exception e) { 45 | wasExecuteSuccessful = false; 46 | throw e; 47 | } 48 | } 49 | 50 | private void persistTransactionState(File recoveryStatePersistenceDirectory) throws IOException { 51 | Files.write(File.createTempFile("exec.", ".txt", recoveryStatePersistenceDirectory).toPath(), currentTxId.getBytes(StandardCharsets.UTF_8)); 52 | } 53 | 54 | @Override 55 | public boolean wasExecuteSuccessful() { 56 | return wasExecuteSuccessful; 57 | } 58 | 59 | @Override 60 | public void cleanup() { 61 | currentTxId = null; 62 | wasExecuteSuccessful = null; 63 | } 64 | 65 | @Override 66 | public void setCurrentTxId(String txid) { 67 | this.currentTxId = txid; 68 | } 69 | 70 | @Override 71 | public String[] getTransactionsInNeedOfRecovery() { 72 | throw new UnsupportedOperationException("should never be called, because the MicroserviceXAResource handles this internally"); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /connector/genericconnector-parent/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector - parent 2 | 3 | This module simply contains the parent POM. 4 | 5 | Build using Maven, starting here, so that all contained modules are built. 6 | The result is the RAR built at `../genericconnector-rar/target/genericconnector-rar-.rar` as well individual JAR files in each module's target folder. 7 | 8 | ##License 9 | 10 | Copyright 2015 Ant Kutschera 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | Unless required by applicable law or agreed to in writing, software 19 | distributed under the License is distributed on an "AS IS" BASIS, 20 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | See the License for the specific language governing permissions and 22 | limitations under the License. 23 | 24 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/README.md: -------------------------------------------------------------------------------- 1 | # genericconnector RAR 2 | 3 | This module assembles the API and implementation, to build the RAR used by JCA compatible Java EE servers. Currently no configuration or deployment descriptor lives here (ra.xml, ironjacamar.xml, etc.) since 4 | it is necessary to override the deployment descriptor at assembly time. This is done by the person in the "deployer" role, for example by configuring the resource adapter in the JBoss `standalone.xml` configuration file. 5 | 6 | ##License 7 | 8 | Copyright 2015 Ant Kutschera 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-parent 9 | 10 | genericconnector-rar 11 | rar 12 | 13 | 14 | 15 | ch.maxant 16 | genericconnector-api 17 | ${project.version} 18 | 19 | 20 | ch.maxant 21 | genericconnector-impl 22 | ${project.version} 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-rar-plugin 30 | 2.4 31 | 32 | src/main/java 33 | true 34 | 37 | 38 | 39 | 40 | 41 | rar 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/background.jpg -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/connector-accessingEIS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/connector-accessingEIS.gif -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/desert.css: -------------------------------------------------------------------------------- 1 | /* desert scheme ported from vim to google prettify */ 2 | pre.prettyprint { display: block; background-color: #333 } 3 | pre .nocode { background-color: none; color: #000 } 4 | pre .str { color: #ffa0a0 } /* string - pink */ 5 | pre .kwd { color: #f0e68c; font-weight: bold } 6 | pre .com { color: #87ceeb } /* comment - skyblue */ 7 | pre .typ { color: #98fb98 } /* type - lightgreen */ 8 | pre .lit { color: #cd5c5c } /* literal - darkred */ 9 | pre .pun { color: #fff } /* punctuation */ 10 | pre .pln { color: #fff } /* plaintext */ 11 | pre .tag { color: #f0e68c; font-weight: bold } /* html/xml tag - lightyellow */ 12 | pre .atn { color: #bdb76b; font-weight: bold } /* attribute name - khaki */ 13 | pre .atv { color: #ffa0a0 } /* attribute value - pink */ 14 | pre .dec { color: #98fb98 } /* decimal - lightgreen */ 15 | 16 | /* Specify class=linenums on a pre to get line numbering */ 17 | ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE } /* IE indents via margin-left */ 18 | li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none } 19 | /* Alternate shading for lines */ 20 | li.L1,li.L3,li.L5,li.L7,li.L9 { } 21 | 22 | @media print { 23 | pre.prettyprint { background-color: none } 24 | pre .str, code .str { color: #060 } 25 | pre .kwd, code .kwd { color: #006; font-weight: bold } 26 | pre .com, code .com { color: #600; font-style: italic } 27 | pre .typ, code .typ { color: #404; font-weight: bold } 28 | pre .lit, code .lit { color: #044 } 29 | pre .pun, code .pun { color: #440 } 30 | pre .pln, code .pln { color: #000 } 31 | pre .tag, code .tag { color: #006; font-weight: bold } 32 | pre .atn, code .atn { color: #404 } 33 | pre .atv, code .atv { color: #060 } 34 | } 35 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/doxy.css: -------------------------------------------------------------------------------- 1 | /* Doxy pretty-printing styles. Used with prettify.js. */ 2 | 3 | pre .str, code .str { color: #fec243; } /* string - eggyolk gold */ 4 | pre .kwd, code .kwd { color: #8470FF; } /* keyword - light slate blue */ 5 | pre .com, code .com { color: #32cd32; font-style: italic; } /* comment - green */ 6 | pre .typ, code .typ { color: #6ecbcc; } /* type - turq green */ 7 | pre .lit, code .lit { color: #d06; } /* literal - cherry red */ 8 | pre .pun, code .pun { color: #8B8970; } /* punctuation - lemon chiffon4 */ 9 | pre .pln, code .pln { color: #f0f0f0; } /* plaintext - white */ 10 | pre .tag, code .tag { color: #9c9cff; } /* html/xml tag (bluey) */ 11 | pre .htm, code .htm { color: #dda0dd; } /* html tag light purply*/ 12 | pre .xsl, code .xsl { color: #d0a0d0; } /* xslt tag light purply*/ 13 | pre .atn, code .atn { color: #46eeee; font-weight: normal;} /* html/xml attribute name - lt turquoise */ 14 | pre .atv, code .atv { color: #EEB4B4; } /* html/xml attribute value - rosy brown2 */ 15 | pre .dec, code .dec { color: #3387CC; } /* decimal - blue */ 16 | 17 | a { 18 | text-decoration: none; 19 | } 20 | pre.prettyprint, code.prettyprint { 21 | font-family:'Droid Sans Mono','CPMono_v07 Bold','Droid Sans'; 22 | font-weight: bold; 23 | font-size: 9pt; 24 | background-color: #0f0f0f; 25 | -moz-border-radius: 8px; 26 | -webkit-border-radius: 8px; 27 | -o-border-radius: 8px; 28 | -ms-border-radius: 8px; 29 | -khtml-border-radius: 8px; 30 | border-radius: 8px; 31 | } /* background is black (well, just a tad less dark ) */ 32 | 33 | pre.prettyprint { 34 | width: 95%; 35 | margin: 1em auto; 36 | padding: 1em; 37 | white-space: pre-wrap; 38 | } 39 | 40 | pre.prettyprint a, code.prettyprint a { 41 | text-decoration:none; 42 | } 43 | /* Specify class=linenums on a pre to get line numbering; line numbers themselves are the same color as punctuation */ 44 | ol.linenums { margin-top: 0; margin-bottom: 0; color: #8B8970; } /* IE indents via margin-left */ 45 | li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none } 46 | /* Alternate shading for lines */ 47 | li.L1,li.L3,li.L5,li.L7,li.L9 { } 48 | 49 | /* print is mostly unchanged from default at present */ 50 | @media print { 51 | pre.prettyprint, code.prettyprint { background-color: #fff; } 52 | pre .str, code .str { color: #088; } 53 | pre .kwd, code .kwd { color: #006; font-weight: bold; } 54 | pre .com, code .com { color: #oc3; font-style: italic; } 55 | pre .typ, code .typ { color: #404; font-weight: bold; } 56 | pre .lit, code .lit { color: #044; } 57 | pre .pun, code .pun { color: #440; } 58 | pre .pln, code .pln { color: #000; } 59 | pre .tag, code .tag { color: #b66ff7; font-weight: bold; } 60 | pre .htm, code .htm { color: #606; font-weight: bold; } 61 | pre .xsl, code .xsl { color: #606; font-weight: bold; } 62 | pre .atn, code .atn { color: #c71585; font-weight: normal; } 63 | pre .atv, code .atv { color: #088; font-weight: normal; } 64 | } 65 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/facebook01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/facebook01.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/facebook02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/facebook02.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/facebook03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/facebook03.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/facebook04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/facebook04.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/presentation.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/presentation.ppt -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/sons-of-obsidian.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Derived from einaros's Sons of Obsidian theme at 3 | * http://studiostyl.es/schemes/son-of-obsidian by 4 | * Alex Ford of CodeTunnel: 5 | * http://CodeTunnel.com/blog/post/71/google-code-prettify-obsidian-theme 6 | */ 7 | 8 | .str 9 | { 10 | color: #EC7600; 11 | } 12 | .kwd 13 | { 14 | color: #93C763; 15 | } 16 | .com 17 | { 18 | color: #66747B; 19 | } 20 | .typ 21 | { 22 | color: #678CB1; 23 | } 24 | .lit 25 | { 26 | color: #FACD22; 27 | } 28 | .pun 29 | { 30 | color: #F1F2F3; 31 | } 32 | .pln 33 | { 34 | color: #F1F2F3; 35 | } 36 | .tag 37 | { 38 | color: #8AC763; 39 | } 40 | .atn 41 | { 42 | color: #E0E2E4; 43 | } 44 | .atv 45 | { 46 | color: #EC7600; 47 | } 48 | .dec 49 | { 50 | color: purple; 51 | } 52 | pre.prettyprint 53 | { 54 | border: 0px solid #888; 55 | } 56 | ol.linenums 57 | { 58 | margin-top: 0; 59 | margin-bottom: 0; 60 | } 61 | .prettyprint { 62 | background: #000; 63 | } 64 | li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 65 | { 66 | color: #555; 67 | list-style-type: decimal; 68 | } 69 | li.L1, li.L3, li.L5, li.L7, li.L9 { 70 | background: #111; 71 | } 72 | @media print 73 | { 74 | .str 75 | { 76 | color: #060; 77 | } 78 | .kwd 79 | { 80 | color: #006; 81 | font-weight: bold; 82 | } 83 | .com 84 | { 85 | color: #600; 86 | font-style: italic; 87 | } 88 | .typ 89 | { 90 | color: #404; 91 | font-weight: bold; 92 | } 93 | .lit 94 | { 95 | color: #044; 96 | } 97 | .pun 98 | { 99 | color: #440; 100 | } 101 | .pln 102 | { 103 | color: #000; 104 | } 105 | .tag 106 | { 107 | color: #006; 108 | font-weight: bold; 109 | } 110 | .atn 111 | { 112 | color: #404; 113 | } 114 | .atv 115 | { 116 | color: #060; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/sunburst.css: -------------------------------------------------------------------------------- 1 | /* Pretty printing styles. Used with prettify.js. */ 2 | /* Vim sunburst theme by David Leibovic */ 3 | 4 | pre .str, code .str { color: #65B042; } /* string - green */ 5 | pre .kwd, code .kwd { color: #E28964; } /* keyword - dark pink */ 6 | pre .com, code .com { color: #AEAEAE; font-style: italic; } /* comment - gray */ 7 | pre .typ, code .typ { color: #89bdff; } /* type - light blue */ 8 | pre .lit, code .lit { color: #3387CC; } /* literal - blue */ 9 | pre .pun, code .pun { color: #fff; } /* punctuation - white */ 10 | pre .pln, code .pln { color: #fff; } /* plaintext - white */ 11 | pre .tag, code .tag { color: #89bdff; } /* html/xml tag - light blue */ 12 | pre .atn, code .atn { color: #bdb76b; } /* html/xml attribute name - khaki */ 13 | pre .atv, code .atv { color: #65B042; } /* html/xml attribute value - green */ 14 | pre .dec, code .dec { color: #3387CC; } /* decimal - blue */ 15 | 16 | pre.prettyprint, code.prettyprint { 17 | background-color: #000; 18 | -moz-border-radius: 8px; 19 | -webkit-border-radius: 8px; 20 | -o-border-radius: 8px; 21 | -ms-border-radius: 8px; 22 | -khtml-border-radius: 8px; 23 | border-radius: 8px; 24 | } 25 | 26 | pre.prettyprint { 27 | width: 95%; 28 | margin: 1em auto; 29 | padding: 1em; 30 | white-space: pre-wrap; 31 | } 32 | 33 | 34 | /* Specify class=linenums on a pre to get line numbering */ 35 | ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */ 36 | li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none } 37 | /* Alternate shading for lines */ 38 | li.L1,li.L3,li.L5,li.L7,li.L9 { } 39 | 40 | @media print { 41 | pre .str, code .str { color: #060; } 42 | pre .kwd, code .kwd { color: #006; font-weight: bold; } 43 | pre .com, code .com { color: #600; font-style: italic; } 44 | pre .typ, code .typ { color: #404; font-weight: bold; } 45 | pre .lit, code .lit { color: #044; } 46 | pre .pun, code .pun { color: #440; } 47 | pre .pln, code .pln { color: #000; } 48 | pre .tag, code .tag { color: #006; font-weight: bold; } 49 | pre .atn, code .atn { color: #404; } 50 | pre .atv, code .atv { color: #060; } 51 | } 52 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/tagcrowd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/tagcrowd.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/worditout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/worditout.jpg -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/worditout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/worditout.png -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/docs/worditout.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/connector/genericconnector-rar/src/main/docs/worditout.xcf -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/java/META-INF/__unused__ironjacamar.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | crap 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | uname 31 | pword 32 | 33 | 34 | 35 | 36 | XATransaction 37 | -------------------------------------------------------------------------------- /connector/genericconnector-rar/src/main/java/META-INF/__unused__ra.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 22 | 23 | maxant Generic Resource Adapter 24 | maxant Generic Resource Adapter 25 | www.maxant.ch 26 | maxant Generic Resource Adapter 27 | 2.0 28 | 29 | 30 | 31 | 32 | ch.maxant.generic_jca_adapter.GenericResourceAdapter 33 | 34 | 35 | 36 | 37 | ch.maxant.generic_jca_adapter.ManagedTransactionAssistanceFactory 38 | 39 | 40 | ch.maxant.generic_jca_adapter.TransactionAssistanceFactory 41 | 42 | 43 | ch.maxant.generic_jca_adapter.TransactionAssistanceFactoryImpl 44 | 45 | 46 | ch.maxant.generic_jca_adapter.TransactionAssistant 47 | 48 | 49 | ch.maxant.generic_jca_adapter.TransactionAssistantImpl 50 | 51 | 52 | 53 | 54 | XATransaction 55 | 56 | 57 | false 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /demo/docker/Dockerfile_acquirer: -------------------------------------------------------------------------------- 1 | FROM maxant/fedora23_jdk18_wildfly820:latest 2 | MAINTAINER Ant Kutschera 3 | 4 | WORKDIR /opt/wildfly-8.2.0.Final/ 5 | 6 | ADD genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT.war ./standalone/deployments/ 7 | 8 | WORKDIR ./bin/ 9 | 10 | -------------------------------------------------------------------------------- /demo/docker/Dockerfile_bookingsystem: -------------------------------------------------------------------------------- 1 | FROM maxant/fedora23_jdk18_wildfly820:latest 2 | MAINTAINER Ant Kutschera 3 | 4 | WORKDIR /opt/wildfly-8.2.0.Final/ 5 | 6 | ADD genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT.war ./standalone/deployments/ 7 | 8 | WORKDIR ./bin/ 9 | 10 | -------------------------------------------------------------------------------- /demo/docker/Dockerfile_letter: -------------------------------------------------------------------------------- 1 | FROM maxant/fedora23_jdk18_wildfly820:latest 2 | MAINTAINER Ant Kutschera 3 | 4 | WORKDIR /opt/wildfly-8.2.0.Final/ 5 | 6 | ADD genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT.war ./standalone/deployments/ 7 | 8 | WORKDIR ./bin/ 9 | 10 | -------------------------------------------------------------------------------- /demo/docker/Dockerfile_wildfly820: -------------------------------------------------------------------------------- 1 | #build using: 2 | # docker build -f Dockerfile_wildfly820 -t maxant/fedora23_jdk18_wildfly820 . 3 | 4 | FROM maxant/fedora23_jdk18:latest 5 | MAINTAINER Ant Kutschera 6 | 7 | WORKDIR /opt/ 8 | ADD wildfly-8.2.0.Final.tar.gz . 9 | 10 | EXPOSE 8080 11 | 12 | WORKDIR ./wildfly-8.2.0.Final/bin/ 13 | 14 | CMD ./standalone.sh -b 0.0.0.0 15 | 16 | 17 | -------------------------------------------------------------------------------- /demo/docker/README.md: -------------------------------------------------------------------------------- 1 | Run the image: (might need su -c "setenforce 0" beforehand; see http://stackoverflow.com/questions/24288616/permission-denied-on-accessing-host-directory-in-docker) 2 | 3 | docker run -it -p 9081:8080 maxant/genericconnector_acquirer 4 | docker run -it -p 9082:8080 maxant/genericconnector_bookingsystem 5 | docker run -it -p 9083:8080 maxant/genericconnector_letter 6 | 7 | RUNNING ON MAXANT.CH: docker run -p.... & 8 | 9 | WSDL is at: 10 | 11 | - http://172.17.0.2:8080/genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT/AcquirerWebService?wsdl 12 | - http://localhost:9081/genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT/AcquirerWebService?wsdl 13 | 14 | 15 | - http://localhost:9082/genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT/BookingSystemWebService?wsdl 16 | 17 | - http://localhost:9083/genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT/LetterWebService?wsdl 18 | 19 | 20 | use `docker inspect | grep IPAddress` to see on which IP address its running 21 | 22 | 23 | build acquirer image using 24 | 25 | 26 | docker build -f Dockerfile_wildfly820 -t maxant/fedora23_jdk18_wildfly820 . 27 | 28 | docker build -f Dockerfile_acquirer -t maxant/genericconnector_acquirer . 29 | docker build -f Dockerfile_bookingsystem -t maxant/genericconnector_bookingsystem . 30 | docker build -f Dockerfile_letter -t maxant/genericconnector_letter . 31 | 32 | 33 | -------------------------------------------------------------------------------- /demo/docker/genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/demo/docker/genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT.war -------------------------------------------------------------------------------- /demo/docker/genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/demo/docker/genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT.war -------------------------------------------------------------------------------- /demo/docker/genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxant/genericconnector/7946689f6d511debe3618c6b54479b9d8d0a1638/demo/docker/genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT.war -------------------------------------------------------------------------------- /demo/genericconnector-demo-common/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Common 2 | 3 | This project contains generated code for the web service clients. Each demo uses these classes to make remote calls to the three web services which must be deployed in order for the demos to work. The web service client code is generated by `wsimport` when maven executes the `generate-sources` phase. **Note** that if you are using an IDE like Eclipse you may need to run that phase and then add `target/generated/cxf/` as a source folder. 4 | 5 | ##License 6 | 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-common 11 | jar 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | 21 | 22 | 23 | org.apache.cxf 24 | cxf-codegen-plugin 25 | 3.1.1 26 | 27 | 28 | generate-sources 29 | generate-sources 30 | 31 | ${project.build.directory}/generated/cxf 32 | ${basedir}/src/main/resources/wsdl 33 | 34 | *Wsdl.xml 35 | 36 | 37 | 38 | 39 | wsdl2java 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Java EE Client 2 | 3 | This module contains 5 main source files, as follows. 4 | 5 | `SomeServiceThatBindsResourcesIntoTransaction.java` => This file represents a service which binds multiple resources into a global transaction and shows how to call web services from your business code, using Java 8. 6 | 7 | `SomeServiceThatBindsResourcesIntoTransaction_JavaSE6.java` => This file represents a service which binds multiple resources into a global transaction and shows how to call web services from your business code, using Java 6. 8 | 9 | `TransactionAssistanceSetup.java` => This file shows how to register commit, rollback and recover callbacks, using Java 8. 10 | 11 | `TransactionAssistanceSetup_JavaSE6.java` => This file shows how to register commit, rollback and recover callbacks, using Java 6. 12 | 13 | `ResourceServlet.java` => This file is a simple servlet which calls the service which binds multiple resources into a single global transaction. It is used for testing. 14 | 15 | ##Tests from your browser: 16 | 17 | - http://localhost:8080/genericconnectordemo/ResourceServlet => positive test case with everything committed 18 | - http://localhost:8080/genericconnectordemo/ResourceServlet?refNum=FAILDB => foreign key constraint violation causes failure at end of process, everything is rolled back 19 | - http://localhost:8080/genericconnectordemo/ResourceServlet?refNum=FAILWSAcquirer => the acquirer fails during execution 20 | - http://localhost:8080/genericconnectordemo/ResourceServlet?refNum=FAILWSBookingSystem => the booking system fails during execution 21 | - http://localhost:8080/genericconnectordemo/ResourceServlet?refNum=FAILWSLetterWriter => the letter writer fails during execution 22 | 23 | ##Other tests: 24 | - Add a breakpoint during commit and undeploy the web services => eventually, when you redeploy the web services, the transactions will be commited. 25 | - Add a breakpoint during commit and kill the database. => the transactions in the web services are committed. After restarting the database, the transaction should be commit. Watch out on Mysql versions prior to 5.7! 26 | - Add a breakpoint during commit, and kill the server. After server restart, the web services become committed (wait 2 minutes for JBoss to run recovery!). Database also. 27 | 28 | ##Places to check for transaction state: 29 | 30 | - The database, in the `temp.person` and `temp.address` tables => one row is written per call to the servlet 31 | - In the folder jboss/standalone/data/bookingsystem-tx-object-store/ => either a file name exec...txt exists and the transaction is incomplete, or the file has been deleted. 32 | - In the folder jboss/standalone/data/letterwriter-tx-object-store/ => either a file name exec...txt exists and the transaction is incomplete, or the file has been deleted. 33 | - In the folder ~/temp/xa-transactions-state-acquirer/ => file named exectxt exists if transaction is incomplete; file named commit...txt exists if transaction was committed; file named rollback...txt exists if transaction was rolled back. 34 | 35 | ##License 36 | 37 | Copyright 2015 Ant Kutschera 38 | 39 | Licensed under the Apache License, Version 2.0 (the "License"); 40 | you may not use this file except in compliance with the License. 41 | You may obtain a copy of the License at 42 | 43 | http://www.apache.org/licenses/LICENSE-2.0 44 | 45 | Unless required by applicable law or agreed to in writing, software 46 | distributed under the License is distributed on an "AS IS" BASIS, 47 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | See the License for the specific language governing permissions and 49 | limitations under the License. 50 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-javaee-client 11 | war 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | ch.maxant 21 | genericconnector-api 22 | ${project.version} 23 | provided 24 | 25 | 26 | ch.maxant 27 | genericconnector-demo-common 28 | ${project.version} 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/java/ch/maxant/jca_demo/client/IntegrationLayer.java: -------------------------------------------------------------------------------- 1 | package ch.maxant.jca_demo.client; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | import java.util.Map; 6 | 7 | import javax.xml.ws.BindingProvider; 8 | 9 | import ch.maxant.jca_demo.acquirer.Acquirer; 10 | import ch.maxant.jca_demo.acquirer.AcquirerWebServiceService; 11 | import ch.maxant.jca_demo.bookingsystem.BookingSystem; 12 | import ch.maxant.jca_demo.bookingsystem.BookingSystemWebServiceService; 13 | import ch.maxant.jca_demo.letterwriter.LetterWebServiceService; 14 | import ch.maxant.jca_demo.letterwriter.LetterWriter; 15 | 16 | public final class IntegrationLayer { 17 | 18 | private IntegrationLayer() {} 19 | 20 | public static Acquirer getAcquirer() { 21 | //String baseUrl = "http://localhost:9081/genericconnector-demo-webservice-acquirer-2.1.1-SNAPSHOT/AcquirerWebService"; 22 | String baseUrl = "http://a.maxant.ch/AcquirerWebService"; 23 | try{ 24 | URL url = new URL(baseUrl + "?wsdl"); 25 | Acquirer svc = new AcquirerWebServiceService(url).getAcquirerPort(); 26 | Map ctx = ((BindingProvider)svc).getRequestContext(); 27 | ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, baseUrl); 28 | //ctx.put(BindingProvider.USERNAME_PROPERTY, "someUsername"); 29 | //ctx.put(BindingProvider.PASSWORD_PROPERTY, "somePassword"); 30 | return svc; 31 | }catch(MalformedURLException e){ 32 | throw new RuntimeException("cant instantiate webservice client", e); 33 | } 34 | } 35 | 36 | public static BookingSystem getBookingsystem() { 37 | //String baseUrl = "http://localhost:9082/genericconnector-demo-webservice-bookingsystem-2.1.1-SNAPSHOT/BookingSystemWebService"; 38 | String baseUrl = "http://b.maxant.ch/BookingSystemWebService"; 39 | try{ 40 | URL url = new URL(baseUrl + "?wsdl"); 41 | BookingSystem svc = new BookingSystemWebServiceService(url).getBookingSystemPort(); 42 | Map ctx = ((BindingProvider)svc).getRequestContext(); 43 | ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, baseUrl); 44 | //ctx.put(BindingProvider.USERNAME_PROPERTY, "someUsername"); 45 | //ctx.put(BindingProvider.PASSWORD_PROPERTY, "somePassword"); 46 | return svc; 47 | }catch(MalformedURLException e){ 48 | throw new RuntimeException("cant instantiate webservice client", e); 49 | } 50 | } 51 | 52 | public static LetterWriter getLetterwriter() { 53 | //String baseUrl = "http://localhost:9083/genericconnector-demo-webservice-letter-2.1.1-SNAPSHOT/LetterWebService"; 54 | String baseUrl = "http://l.maxant.ch/LetterWebService"; 55 | try{ 56 | URL url = new URL(baseUrl + "?wsdl"); 57 | LetterWriter svc = new LetterWebServiceService(url).getLetterWriterPort(); 58 | Map ctx = ((BindingProvider)svc).getRequestContext(); 59 | ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, baseUrl); 60 | //ctx.put(BindingProvider.USERNAME_PROPERTY, "someUsername"); 61 | //ctx.put(BindingProvider.PASSWORD_PROPERTY, "somePassword"); 62 | return svc; 63 | }catch(MalformedURLException e){ 64 | throw new RuntimeException("cant instantiate webservice client", e); 65 | } 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/java/ch/maxant/jca_demo/client/ResourceServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.jca_demo.client; 18 | 19 | import java.io.IOException; 20 | import java.util.logging.Level; 21 | import java.util.logging.Logger; 22 | 23 | import javax.ejb.EJB; 24 | import javax.servlet.ServletException; 25 | import javax.servlet.annotation.WebServlet; 26 | import javax.servlet.http.HttpServlet; 27 | import javax.servlet.http.HttpServletRequest; 28 | import javax.servlet.http.HttpServletResponse; 29 | 30 | @WebServlet("/ResourceServlet") 31 | public class ResourceServlet extends HttpServlet { 32 | 33 | private static final long serialVersionUID = 1L; 34 | 35 | private final Logger log = Logger.getLogger(this.getClass().getName()); 36 | 37 | @EJB private SomeServiceThatBindsResourcesIntoTransaction svc; 38 | 39 | @Override 40 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 41 | String refNum = request.getParameter("refNum"); 42 | if(refNum == null) refNum = "refNum"; 43 | try { 44 | String s = svc.doSomethingInvolvingSeveralResources(refNum); 45 | log.log(Level.INFO, "servlet got: " + s); 46 | response.getWriter().append(s); 47 | } catch (Exception e) { 48 | throw new ServletException(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/java/ch/maxant/jca_demo/client/TransactionAssistanceSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.jca_demo.client; 18 | 19 | 20 | import static ch.maxant.jca_demo.client.IntegrationLayer.getAcquirer; 21 | import static ch.maxant.jca_demo.client.IntegrationLayer.getBookingsystem; 22 | import static ch.maxant.jca_demo.client.IntegrationLayer.getLetterwriter; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.logging.Level; 27 | import java.util.logging.Logger; 28 | 29 | import javax.annotation.PostConstruct; 30 | import javax.annotation.PreDestroy; 31 | import javax.annotation.Resource; 32 | import javax.ejb.Singleton; 33 | import javax.ejb.Startup; 34 | 35 | import ch.maxant.generic_jca_adapter.TransactionAssistanceFactory; 36 | import ch.maxant.generic_jca_adapter.TransactionAssistanceFactory.CommitRollbackRecoveryCallback.Builder; 37 | 38 | @Startup 39 | @Singleton 40 | public class TransactionAssistanceSetup { 41 | 42 | private final Logger log = Logger.getLogger(this.getClass().getName()); 43 | 44 | @Resource(lookup = "java:/maxant/Acquirer") 45 | private TransactionAssistanceFactory acquirerFactory; 46 | 47 | @Resource(lookup = "java:/maxant/BookingSystem") 48 | private TransactionAssistanceFactory bookingFactory; 49 | 50 | @Resource(lookup = "java:/maxant/LetterWriter") 51 | private TransactionAssistanceFactory letterWriterFactory; 52 | 53 | @PostConstruct 54 | public void init() { 55 | log.log(Level.INFO, "Registering commit/rollback/recovery callbacks"); 56 | acquirerFactory 57 | .registerCommitRollbackRecovery(new Builder() 58 | .withCommit( txid -> { 59 | getAcquirer().bookReservation(txid); 60 | }) 61 | .withRollback( txid -> { 62 | getAcquirer().cancelReservation(txid); 63 | }) 64 | .withRecovery( () -> { 65 | try { 66 | List txids = getAcquirer().findUnfinishedTransactions(); 67 | txids = txids == null ? new ArrayList<>() : txids; 68 | return txids.toArray(new String[0]); 69 | } catch (Exception e) { 70 | log.log(Level.WARNING, "Failed to find transactions requiring recovery for acquirer!", e); 71 | return null; 72 | } 73 | }).build()); 74 | 75 | bookingFactory 76 | .registerCommitRollbackRecovery(new Builder() 77 | .withCommit( txid -> { 78 | getBookingsystem().bookTickets(txid); 79 | }) 80 | .withRollback( txid -> { 81 | getBookingsystem().cancelTickets(txid); 82 | }) 83 | //no recovery required, since the resource adapter has been configured to handle this internally 84 | .build()); 85 | 86 | letterWriterFactory 87 | .registerCommitRollbackRecovery(new Builder() 88 | .withCommit( txid -> { 89 | //noop, since execution was already a commit 90 | }) 91 | .withRollback( txid -> { 92 | getLetterwriter().cancelLetter(txid); 93 | }) 94 | //no recovery required, since the resource adapter has been configured to handle this internally 95 | .build()); 96 | 97 | } 98 | 99 | @PreDestroy 100 | public void shutdown(){ 101 | log.log(Level.INFO, "Unregistering commit/rollback/recovery callbacks"); 102 | acquirerFactory.unregisterCommitRollbackRecovery(); 103 | bookingFactory.unregisterCommitRollbackRecovery(); 104 | letterWriterFactory.unregisterCommitRollbackRecovery(); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/java/ch/maxant/jca_demo/client/TransactionAssistanceSetup_JavaSE6.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.jca_demo.client; 18 | 19 | import javax.annotation.PostConstruct; 20 | import javax.annotation.PreDestroy; 21 | import javax.annotation.Resource; 22 | import javax.ejb.Singleton; 23 | import javax.ejb.Startup; 24 | 25 | import ch.maxant.generic_jca_adapter.TransactionAssistanceFactory; 26 | 27 | /** A Java 6 compatible implementation */ 28 | @Startup 29 | @Singleton 30 | public class TransactionAssistanceSetup_JavaSE6 { 31 | 32 | @Resource(lookup = "java:/maxant/Acquirer") 33 | private TransactionAssistanceFactory acquirerFactory; 34 | 35 | @Resource(lookup = "java:/maxant/BookingSystem") 36 | private TransactionAssistanceFactory bookingFactory; 37 | 38 | @Resource(lookup = "java:/maxant/LetterWriter") 39 | private TransactionAssistanceFactory letterWriterFactory; 40 | 41 | @PostConstruct 42 | public void init() { 43 | /* cannot register callbacks twice - either Java SE 6 or 8! See TransactionAssistanceSetup 44 | acquirerFactory.registerCommitRollbackRecovery(new CommitRollbackRecoveryCallback(){ 45 | @Override 46 | public String[] getTransactionsInNeedOfRecovery() { 47 | try { 48 | List txids = new AcquirerWebServiceService().getAcquirerPort().findUnfinishedTransactions(); 49 | txids = txids == null ? new ArrayList<>() : txids; 50 | return txids.toArray(new String[0]); 51 | } catch (Exception e) { 52 | log.log(Level.WARNING, "Failed to find transactions requiring recovery for acquirer!", e); 53 | return null; 54 | } 55 | } 56 | 57 | @Override 58 | public void commit(String txid) throws Exception { 59 | new AcquirerWebServiceService() 60 | .getAcquirerPort().bookReservation(txid); 61 | } 62 | 63 | @Override 64 | public void rollback(String txid) throws Exception { 65 | new AcquirerWebServiceService() 66 | .getAcquirerPort().cancelReservation(txid); 67 | } 68 | 69 | }); 70 | 71 | bookingFactory.registerCommitRollbackRecovery(new CommitRollbackRecoveryCallback(){ 72 | 73 | @Override 74 | public String[] getTransactionsInNeedOfRecovery() { 75 | //no recovery required, since the resource adapter has been configured to handle this internally 76 | return null; 77 | } 78 | 79 | @Override 80 | public void commit(String txid) throws Exception { 81 | new BookingSystemWebServiceService() 82 | .getBookingSystemPort().bookTickets(txid); 83 | } 84 | 85 | @Override 86 | public void rollback(String txid) throws Exception { 87 | new BookingSystemWebServiceService() 88 | .getBookingSystemPort().cancelTickets(txid); 89 | } 90 | }); 91 | 92 | letterWriterFactory.registerCommitRollbackRecovery(new CommitRollbackRecoveryCallback(){ 93 | @Override 94 | public String[] getTransactionsInNeedOfRecovery() { 95 | //no recovery required, since the resource adapter has been configured to handle this internally 96 | return null; 97 | } 98 | 99 | @Override 100 | public void commit(String txid) throws Exception { 101 | //noop, since execution was already a commit 102 | } 103 | 104 | @Override 105 | public void rollback(String txid) throws Exception { 106 | new LetterWebServiceService().getLetterWriterPort() 107 | .cancelLetter(txid); 108 | } 109 | }); 110 | 111 | */ 112 | } 113 | 114 | @PreDestroy 115 | public void shutdown(){ 116 | acquirerFactory.unregisterCommitRollbackRecovery(); 117 | bookingFactory.unregisterCommitRollbackRecovery(); 118 | letterWriterFactory.unregisterCommitRollbackRecovery(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-client/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="javax.naming.Context"%> 2 | <%@page import="javax.naming.NameClassPair"%> 3 | <%@page import="javax.naming.NamingEnumeration"%> 4 | <%@page import="javax.naming.InitialContext"%> 5 | <% 6 | /* 7 | Copyright 2015 Ant Kutschera 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | String name = request.getParameter("name"); 23 | if(name == null){ 24 | name = "java:/"; 25 | } 26 | %> 27 | 28 |

JNDI

29 |
30 | Name: 31 | 32 |
33 | 34 | <% 35 | InitialContext ic = new InitialContext(); 36 | try{ 37 | NamingEnumeration o = ic.list(name); 38 | while(o.hasMoreElements()){ 39 | Object o2 = o.next(); 40 | if(o2 instanceof Context){ 41 | Context c = (Context)o2; 42 | %><%=c.getNameInNamespace()%> (<%=o2%>)
<% 43 | }else{ 44 | %><%=o2%>
<% 45 | } 46 | } 47 | }catch(Exception e){ 48 | e.printStackTrace(); 49 | %>Error: <%=e%>
<% 50 | } 51 | %> 52 | 53 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-ear/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-ear/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Java EE EAR 2 | 3 | This module builds the demo EAR file which can be deployed to the application server. 4 | 5 | See the blog article for more information. 6 | 7 | This EAR's POM file can be used as a template, to see how to integrate the resource adapter into your project. 8 | 9 | #Notes 10 | - Deployment in Eclipse: doesn't seem to work properly anymore, getting NPE or CDNFE during deployment. Try deploying the EAR that maven builds manually, and ensure that standalone.xml has the correct path name to the RAR, including version numbers etc. Seems to be a problem with the deployment of the exploded JARs inside the RAR? 20150926, Wildfly 8.2. 11 | - When testing a crash in JBoss, Chrome might automatically retry loading the page, so that can cause extra transactions that you might not be expecting. Additionally, it can take two minutes to clean up pending recoveries, so give it time! Interestingly you can attempt do delete all rows in the DB during a pending recovery and the DB hangs, waiting for the relevant row locks to be made available. Check "XA RECOVER;" => sure enough, you will see some pending transactions. Given time, these will be cleaned up the next time JBoss runs recovery. 12 | - JBoss might report that it cannot find a suitable resource for recovery, say if there is a pending recovery at startup, but don't worry, that message appears to be logged before the resource adapters are started up. 13 | 14 | ##License 15 | 16 | Copyright 2015 Ant Kutschera 17 | 18 | Licensed under the Apache License, Version 2.0 (the "License"); 19 | you may not use this file except in compliance with the License. 20 | You may obtain a copy of the License at 21 | 22 | http://www.apache.org/licenses/LICENSE-2.0 23 | 24 | Unless required by applicable law or agreed to in writing, software 25 | distributed under the License is distributed on an "AS IS" BASIS, 26 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | See the License for the specific language governing permissions and 28 | limitations under the License. 29 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-javaee-ear/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-javaee-ear 11 | ear 12 | 13 | 14 | ch.maxant 15 | genericconnector-demo-javaee-client 16 | ${project.version} 17 | war 18 | 19 | 20 | ch.maxant 21 | genericconnector-rar 22 | ${project.version} 23 | rar 24 | 25 | 26 | 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-ear-plugin 31 | 2.10.1 32 | 33 | 34 | 35 | ch.maxant 36 | genericconnector-demo-javaee-client 37 | genericconnectordemo 38 | 39 | 40 | ch.maxant 41 | genericconnector-rar 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-parent/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Parent 2 | 3 | This module can be used to build all the demo applications. 4 | 5 | The EAR is built as `genericconnector-demo-ear/target/genericconnector-demo-javaee-ear-.ear` 6 | 7 | Standalone applications are built as JARs in the respective target folders. 8 | 9 | ##License 10 | 11 | Copyright 2015 Ant Kutschera 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-parent/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | ch.maxant 5 | genericconnector-demo-parent 6 | 2.1.1-SNAPSHOT 7 | pom 8 | http://blog.maxant.co.uk/pebble/2015/08/04/1438716480000.html 9 | 10 | 11 | 12 | Apache License, Version 2.0 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | repo 15 | 16 | 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 4.11 22 | 23 | 24 | 25 | ../genericconnector-demo-webservice-letter 26 | ../genericconnector-demo-webservice-acquirer 27 | ../genericconnector-demo-webservice-bookingsystem 28 | ../genericconnector-demo-common 29 | ../genericconnector-demo-javaee-client 30 | ../genericconnector-demo-javaee-ear 31 | ../genericconnector-demo-springboot-atomikos 32 | ../genericconnector-demo-springboot-bitronix 33 | ../genericconnector-demo-springboot-common 34 | ../genericconnector-demo-standalone-atomikos 35 | ../genericconnector-demo-standalone-bitronix 36 | ../genericconnector-demo-tomcat-bitronix 37 | ../genericconnector-demo-tomcat-atomikos 38 | 39 | 40 | 41 | 42 | junit 43 | junit 44 | ${junit.version} 45 | test 46 | 47 | 48 | org.jboss.spec 49 | jboss-javaee-all-7.0 50 | 1.0.3.Final 51 | provided 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-compiler-plugin 60 | 3.3 61 | 62 | 1.8 63 | 1.8 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ant 72 | Ant Kutschera 73 | ant.kutschera@gmail.com 74 | 75 | 76 | 77 | 78 | Ant Kutschera 79 | http://blog.maxant.co.uk/pebble/ 80 | 81 | 82 | https://github.com/maxant/genericconnector.git 83 | 84 | 85 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Spring Boot Demo with Atomikos 2 | 3 | Note: this project depends on code found in the `../genericconnector-demo-springboot-common` project. 4 | 5 | This project contains the following classes: 6 | 7 | - `BaseMain` - an abstract class which the main application inherits from. This class setups up the commit/rollback callback for two services which the application calls. It deregisters the callbacks during shutdown. 8 | - `Config` - This class creates the `BasicTransactionAssistanceFactory` which is injected into the service which calls the two back-end services. See `../genericconnector-demo-springboot-common/src/.../AppService.java` to see how they are injected. This class is a standard Spring configuration factory bean but you could equally define this bean in Spring's standard XML configuration. 9 | - `DemoSpringBootServerAtomikos` - This class contains the main method to start the application. It is based on https://spring.io/guides/gs/rest-service/ and https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jta-bitronix and once you run this main class, you can test the application by calling either http://localhost:8191/createUser?username=ant for a successful case or http://localhost:8191/createUser?username=john for a failure case. 10 | 11 | ##Notes 12 | 13 | - Watch out, transaction logs end up in maven repo, e.g. `/shared/local-maven-repo/org/springframework/boot/spring-boot/1.2.6.RELEASE/transaction-logs/tmlog-1.log` - if during development you change lots of stuff and tx logs are no longer compatible, delete them before restarting the app, to avoid lots of error messages in the logs. 14 | - If commit/rollback fails because the backend service temporarily goes down then Atomikos will keep trying but won't respond to the client with a success until it can complete the transaction. This is different from JBoss and Bitronix. Atomikos will eventually respond with an Exception: `com.atomikos.icatch.HeurHazardException`. 15 | - SpringData, Atomikos and Mysql might not work nicely - according to Atomikos this is a problem with Mysql. According to Mysql this calling `XA START JOIN` is not legal. 16 | 17 | WARN c.a.datasource.xa.XAResourceTransaction : XAResource.start ( ...txid... , XAResource.TMJOIN ) on resource dataSource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection@114f3b08 18 | WARN c.a.datasource.xa.XAResourceTransaction : XA resource 'dataSource': resume for XID '...txid...' raised -5: invalid arguments were given for the XA operation 19 | ... 20 | com.mysql.jdbc.jdbc2.optional.MysqlXAException: XAER_INVAL: Invalid arguments (or unsupported command) 21 | 22 | ##License 23 | 24 | Copyright 2015 Ant Kutschera 25 | 26 | Licensed under the Apache License, Version 2.0 (the "License"); 27 | you may not use this file except in compliance with the License. 28 | You may obtain a copy of the License at 29 | 30 | http://www.apache.org/licenses/LICENSE-2.0 31 | 32 | Unless required by applicable law or agreed to in writing, software 33 | distributed under the License is distributed on an "AS IS" BASIS, 34 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | See the License for the specific language governing permissions and 36 | limitations under the License. 37 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.springframework.boot 6 | spring-boot-starter-parent 7 | 1.2.6.RELEASE 8 | 9 | ch.maxant 10 | genericconnector-demo-springboot-atomikos 11 | 2.1.1-SNAPSHOT 12 | jar 13 | http://blog.maxant.co.uk/pebble/2015/08/04/1438716480000.html 14 | 15 | 16 | 17 | Apache License, Version 2.0 18 | http://www.apache.org/licenses/LICENSE-2.0 19 | repo 20 | 21 | 22 | 23 | UTF-8 24 | UTF-8 25 | 26 | 27 | 28 | junit 29 | junit 30 | test 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-jta-atomikos 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-web 43 | 44 | 45 | org.jboss.spec 46 | jboss-javaee-all-7.0 47 | 1.0.3.Final 48 | provided 49 | 50 | 51 | ch.maxant 52 | genericconnector-atomikos-api 53 | ${project.version} 54 | 55 | 56 | ch.maxant 57 | genericconnector-demo-springboot-common 58 | ${project.version} 59 | 60 | 61 | org.slf4j 62 | slf4j-log4j12 63 | 64 | 65 | org.hibernate 66 | hibernate-validator 67 | 68 | 69 | mysql 70 | mysql-connector-java 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-maven-plugin 79 | 80 | 81 | org.apache.maven.plugins 82 | maven-compiler-plugin 83 | 3.3 84 | 85 | 1.8 86 | 1.8 87 | 88 | 89 | 90 | 91 | 92 | 93 | ant 94 | Ant Kutschera 95 | ant.kutschera@gmail.com 96 | 97 | 98 | 99 | 100 | Ant Kutschera 101 | http://blog.maxant.co.uk/pebble/ 102 | 103 | 104 | https://github.com/maxant/genericconnector.git 105 | 106 | 107 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/src/main/java/ch/maxant/generic_jca_adapter/demo/BaseMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import javax.naming.NamingException; 20 | 21 | import ch.maxant.generic_jca_adapter.TransactionConfigurator; 22 | import ch.maxant.generic_jca_adapter.CommitRollbackCallback; 23 | import ch.maxant.jca_demo.bookingsystem.BookingSystemWebServiceService; 24 | import ch.maxant.jca_demo.letterwriter.LetterWebServiceService; 25 | 26 | public abstract class BaseMain { 27 | 28 | protected static void setupCommitRollbackHandlerForMicroserviceWhichIsCalled() throws NamingException { 29 | {//setup microservices that we want to call within a transaction 30 | 31 | CommitRollbackCallback bookingCommitRollbackCallback = new CommitRollbackCallback() { 32 | private static final long serialVersionUID = 1L; 33 | @Override 34 | public void rollback(String txid) throws Exception { 35 | new BookingSystemWebServiceService().getBookingSystemPort().cancelTickets(txid); 36 | } 37 | @Override 38 | public void commit(String txid) throws Exception { 39 | new BookingSystemWebServiceService().getBookingSystemPort().bookTickets(txid); 40 | } 41 | }; 42 | TransactionConfigurator.setup("xa/bookingService", bookingCommitRollbackCallback); 43 | 44 | CommitRollbackCallback letterCommitRollbackCallback = new CommitRollbackCallback() { 45 | private static final long serialVersionUID = 1L; 46 | @Override 47 | public void rollback(String txid) throws Exception { 48 | //compensate by cancelling the letter 49 | new LetterWebServiceService().getLetterWriterPort().cancelLetter(txid); 50 | } 51 | @Override 52 | public void commit(String txid) throws Exception { 53 | //nothing to do, this service autocommits. 54 | } 55 | }; 56 | TransactionConfigurator.setup("xa/letterService", letterCommitRollbackCallback); 57 | } 58 | 59 | //when app shutsdown, we want to deregister the microservice from bitronix's singleton transaction manager. 60 | //this is important in say tomcat, where applications can be installed/uninstalled, but bitronix's lifecycle 61 | //depends on the server, not individual applications. 62 | Runtime.getRuntime().addShutdownHook(new Thread(){ 63 | @Override 64 | public void run() { 65 | //shutdown 66 | TransactionConfigurator.unregisterMicroserviceResourceFactory("xa/bookingService"); 67 | TransactionConfigurator.unregisterMicroserviceResourceFactory("xa/letterService"); 68 | } 69 | }); 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/src/main/java/ch/maxant/generic_jca_adapter/demo/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import javax.naming.NamingException; 20 | 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | import ch.maxant.generic_jca_adapter.BasicTransactionAssistanceFactory; 25 | import ch.maxant.generic_jca_adapter.BasicTransactionAssistanceFactoryImpl; 26 | 27 | @Configuration 28 | public class Config { 29 | 30 | @Bean(name="xa/bookingService") 31 | public BasicTransactionAssistanceFactory bookingServiceFactory() throws NamingException { 32 | BasicTransactionAssistanceFactory microserviceFactory = new BasicTransactionAssistanceFactoryImpl("xa/bookingService"); 33 | return microserviceFactory; 34 | } 35 | 36 | @Bean(name="xa/letterService") 37 | public BasicTransactionAssistanceFactory letterServiceFactory() throws NamingException { 38 | BasicTransactionAssistanceFactory microserviceFactory = new BasicTransactionAssistanceFactoryImpl("xa/letterService"); 39 | return microserviceFactory; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/src/main/java/ch/maxant/generic_jca_adapter/demo/DemoSpringBootServerAtomikos.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | /** 23 | * demo of a spring boot application which publishes an endpoint 24 | *(see {@link AppController}) and listens for requests. 25 | * 26 | * see also: 27 | * https://spring.io/guides/gs/rest-service/ 28 | * https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java 29 | * 30 | * test like this: http://localhost:8191/createUser?username=ant 31 | */ 32 | @SpringBootApplication 33 | public class DemoSpringBootServerAtomikos extends BaseMain { 34 | 35 | public static void main(String[] args) throws Exception { 36 | setupCommitRollbackHandlerForMicroserviceWhichIsCalled(); 37 | 38 | //run the application 39 | SpringApplication.run(DemoSpringBootServerAtomikos.class, args); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/temp?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 2 | spring.datasource.username=root 3 | spring.datasource.password=password 4 | spring.datasource.xa.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 5 | 6 | #avoid problems with hibernate writing lowercase table names into sql 7 | spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy 8 | 9 | server.port=8191 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-atomikos/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Ignore Weld-Reflection warnings during tests. Most of them are knwon issues. 5 | log4j.logger.org.jboss.weld.Reflection=ERROR 6 | 7 | # Direct log messages to stdout 8 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 9 | log4j.appender.stdout.Target=System.out 10 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}:%L] %m%n 12 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Spring Boot Demo with Bitronix 2 | 3 | Note: this project depends on code found in the `../genericconnector-demo-springboot-common` project. 4 | 5 | This project contains the following classes: 6 | 7 | - `BaseMain` - an abstract class which the main application inherits from. This class setups up the commit/rollback callback for two services which the application calls. It deregisters the callbacks during shutdown. 8 | - `Config` - This class creates the `BasicTransactionAssistanceFactory` which is injected into the service which calls the two back-end services. See `../genericconnector-demo-springboot-common/src/.../AppService.java` to see how they are injected. Because we need one instance of the factory per microservice we are calling, we use the bean's name as the qualifier. This class is a standard Spring configuration factory bean but you could equally define this bean in Spring's standard XML configuration. 9 | - `DemoSpringBootServerBitronix` - This class contains the main method to start the application. It is based on https://spring.io/guides/gs/rest-service/ and https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jta-bitronix and once you run this main class, you can test the application by calling either http://localhost:8191/createUser?username=ant for a successful case or http://localhost:8191/createUser?username=john for a failure case. 10 | 11 | 12 | ##Notes 13 | 14 | - Watch out, transaction logs end up in maven repo, e.g. `/shared/local-maven-repo/org/springframework/boot/spring-boot/1.2.6.RELEASE/transaction-logs/tmlog-1.log` - if during development you change lots of stuff and tx logs are no longer compatible, delete them before restarting the app, to avoid lots of error messages in the logs. 15 | - https://github.com/bitronix/btm/issues/53 - If a back-end service goes down between the execution stage and the commit / rollback, then the commit / rollback will not be reattempted until either the transaction manager is restarted, or randomly a transaction is in progress at the time of recovery. 16 | 17 | ##License 18 | 19 | Copyright 2015 Ant Kutschera 20 | 21 | Licensed under the Apache License, Version 2.0 (the "License"); 22 | you may not use this file except in compliance with the License. 23 | You may obtain a copy of the License at 24 | 25 | http://www.apache.org/licenses/LICENSE-2.0 26 | 27 | Unless required by applicable law or agreed to in writing, software 28 | distributed under the License is distributed on an "AS IS" BASIS, 29 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | See the License for the specific language governing permissions and 31 | limitations under the License. 32 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.springframework.boot 6 | spring-boot-starter-parent 7 | 1.2.6.RELEASE 8 | 9 | ch.maxant 10 | genericconnector-demo-springboot-bitronix 11 | 2.1.1-SNAPSHOT 12 | jar 13 | http://blog.maxant.co.uk/pebble/2015/08/04/1438716480000.html 14 | 15 | 16 | 17 | Apache License, Version 2.0 18 | http://www.apache.org/licenses/LICENSE-2.0 19 | repo 20 | 21 | 22 | 23 | UTF-8 24 | UTF-8 25 | 26 | 27 | 28 | junit 29 | junit 30 | test 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-jta-bitronix 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-web 43 | 44 | 45 | org.jboss.spec 46 | jboss-javaee-all-7.0 47 | 1.0.3.Final 48 | provided 49 | 50 | 51 | ch.maxant 52 | genericconnector-bitronix-api 53 | ${project.version} 54 | 55 | 56 | ch.maxant 57 | genericconnector-demo-springboot-common 58 | ${project.version} 59 | 60 | 61 | org.slf4j 62 | slf4j-log4j12 63 | 64 | 65 | org.hibernate 66 | hibernate-validator 67 | 68 | 69 | mysql 70 | mysql-connector-java 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-maven-plugin 79 | 80 | 81 | org.apache.maven.plugins 82 | maven-compiler-plugin 83 | 3.3 84 | 85 | 1.8 86 | 1.8 87 | 88 | 89 | 90 | 91 | 92 | 93 | ant 94 | Ant Kutschera 95 | ant.kutschera@gmail.com 96 | 97 | 98 | 99 | 100 | Ant Kutschera 101 | http://blog.maxant.co.uk/pebble/ 102 | 103 | 104 | https://github.com/maxant/genericconnector.git 105 | 106 | 107 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/src/main/java/ch/maxant/generic_jca_adapter/demo/BaseMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import ch.maxant.generic_jca_adapter.TransactionConfigurator; 20 | import ch.maxant.generic_jca_adapter.CommitRollbackCallback; 21 | import ch.maxant.jca_demo.bookingsystem.BookingSystemWebServiceService; 22 | import ch.maxant.jca_demo.letterwriter.LetterWebServiceService; 23 | 24 | public abstract class BaseMain { 25 | 26 | protected static void setupCommitRollbackHandlerForMicroserviceWhichIsCalled() { 27 | {//setup microservice that we want to call within a transaction 28 | CommitRollbackCallback bookingCommitRollbackCallback = new CommitRollbackCallback() { 29 | private static final long serialVersionUID = 1L; 30 | @Override 31 | public void rollback(String txid) throws Exception { 32 | new BookingSystemWebServiceService().getBookingSystemPort().cancelTickets(txid); 33 | } 34 | @Override 35 | public void commit(String txid) throws Exception { 36 | new BookingSystemWebServiceService().getBookingSystemPort().bookTickets(txid); 37 | } 38 | }; 39 | TransactionConfigurator.setup("xa/bookingService", bookingCommitRollbackCallback); 40 | 41 | CommitRollbackCallback letterCommitRollbackCallback = new CommitRollbackCallback() { 42 | private static final long serialVersionUID = 1L; 43 | @Override 44 | public void rollback(String txid) throws Exception { 45 | //compensate by cancelling the letter 46 | new LetterWebServiceService().getLetterWriterPort().cancelLetter(txid); 47 | } 48 | @Override 49 | public void commit(String txid) throws Exception { 50 | //nothing to do, this service autocommits. 51 | } 52 | }; 53 | TransactionConfigurator.setup("xa/letterService", letterCommitRollbackCallback); 54 | } 55 | 56 | //when app shutsdown, we want to deregister the microservice from bitronix's singleton transaction manager. 57 | //this is important in say tomcat, where applications can be installed/uninstalled, but bitronix's lifecycle 58 | //depends on the server, not individual applications. 59 | Runtime.getRuntime().addShutdownHook(new Thread(){ 60 | @Override 61 | public void run() { 62 | //shutdown 63 | TransactionConfigurator.unregisterMicroserviceResourceFactory("xa/bookingService"); 64 | TransactionConfigurator.unregisterMicroserviceResourceFactory("xa/letterService"); 65 | } 66 | }); 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/src/main/java/ch/maxant/generic_jca_adapter/demo/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import javax.naming.Context; 20 | import javax.naming.NamingException; 21 | 22 | import org.springframework.context.annotation.Bean; 23 | import org.springframework.context.annotation.Configuration; 24 | 25 | import bitronix.tm.jndi.BitronixContext; 26 | import ch.maxant.generic_jca_adapter.BasicTransactionAssistanceFactory; 27 | 28 | @Configuration 29 | public class Config { 30 | 31 | @Bean(name="xa/bookingService") 32 | public BasicTransactionAssistanceFactory bookingSystemFactory() throws NamingException { 33 | Context ctx = new BitronixContext(); 34 | BasicTransactionAssistanceFactory microserviceFactory = (BasicTransactionAssistanceFactory) ctx.lookup("xa/bookingService"); 35 | return microserviceFactory; 36 | } 37 | 38 | @Bean(name="xa/letterService") 39 | public BasicTransactionAssistanceFactory letterServiceFactory() throws NamingException { 40 | Context ctx = new BitronixContext(); 41 | BasicTransactionAssistanceFactory microserviceFactory = (BasicTransactionAssistanceFactory) ctx.lookup("xa/letterService"); 42 | return microserviceFactory; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/src/main/java/ch/maxant/generic_jca_adapter/demo/DemoSpringBootServerBitronix.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter.demo; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | /** 23 | * demo of a spring boot application which publishes an endpoint 24 | *(see {@link AppController}) and listens for requests. 25 | * 26 | * see also: 27 | * https://spring.io/guides/gs/rest-service/ 28 | * https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java 29 | * 30 | * test like this: http://localhost:8191/createUser?username=ant 31 | */ 32 | @SpringBootApplication 33 | public class DemoSpringBootServerBitronix extends BaseMain { 34 | 35 | public static void main(String[] args) throws Exception { 36 | setupCommitRollbackHandlerForMicroserviceWhichIsCalled(); 37 | 38 | //run the application 39 | SpringApplication.run(DemoSpringBootServerBitronix.class, args); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/temp?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 2 | spring.datasource.username=root 3 | spring.datasource.password=password 4 | spring.datasource.xa.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 5 | 6 | #avoid problems with hibernate writing lowercase table names into sql 7 | spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy 8 | 9 | server.port=8191 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-bitronix/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Ignore Weld-Reflection warnings during tests. Most of them are knwon issues. 5 | log4j.logger.org.jboss.weld.Reflection=ERROR 6 | 7 | # Direct log messages to stdout 8 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 9 | log4j.appender.stdout.Target=System.out 10 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}:%L] %m%n 12 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Spring Boot Demo Common 2 | 3 | This project contains code common to the Atomikos and Bitronix Spring Boot demo applications. 4 | 5 | It contains the following classes: 6 | 7 | - `Account` - A JPA Entity class representing the `account` table in the database. 8 | - `AppController` - A REST controller which receives `GET` requests at `http://localhost:8191/createUser?username=john`. This controller passes the call on to the `AppService` described below. 9 | - `AppRepository` - A Spring Data Repository for saving Account entities. 10 | - `AppService` - A Spring service which is transactional due to the class annotation which has `BasicTransactionAssistanceFactory` instances injected for binding two microservice calls (one to the letter service and one to the booking service) into the transaction. This service first writes to the database and then calls the two services. The Spring container then commits when the method exists. If the username "john" is sent to the service, it will throw a new exception at the end, and the transaction manager will automatically call the rollback methods on the two services (as well as rollback the database insert). The two `BasicTransactionAssistanceFactory`s are created in the `Config` class, which is Atomikos/Bitronix specific. See them under `../genericconnector-demo-springboot-atomikos` / `../genericconnector-demo-springboot-bitronix` respectively. The database connection is configured in the `application.properties` file also located in the above named projects. 11 | 12 | See also: 13 | 14 | - http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html 15 | - https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-jta-bitronix 16 | - https://github.com/spring-projects/spring-boot/tree/master/spring-boot-starters/spring-boot-starter-jta-bitronix 17 | 18 | ##License 19 | 20 | Copyright 2015 Ant Kutschera 21 | 22 | Licensed under the Apache License, Version 2.0 (the "License"); 23 | you may not use this file except in compliance with the License. 24 | You may obtain a copy of the License at 25 | 26 | http://www.apache.org/licenses/LICENSE-2.0 27 | 28 | Unless required by applicable law or agreed to in writing, software 29 | distributed under the License is distributed on an "AS IS" BASIS, 30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | See the License for the specific language governing permissions and 32 | limitations under the License. 33 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-springboot-common 11 | jar 12 | 13 | 1.2.6.RELEASE 14 | 15 | 16 | 17 | org.jboss.spec 18 | jboss-javaee-all-7.0 19 | 1.0.3.Final 20 | provided 21 | 22 | 23 | ch.maxant 24 | genericconnector-api 25 | ${project.version} 26 | provided 27 | 28 | 29 | ch.maxant 30 | genericconnector-demo-common 31 | ${project.version} 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-jpa 36 | provided 37 | ${springboot.version} 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-web 42 | provided 43 | ${springboot.version} 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/src/main/java/ch/maxant/generic_jca_adapter/demo/Account.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package ch.maxant.generic_jca_adapter.demo; 17 | 18 | import javax.persistence.Column; 19 | import javax.persistence.Entity; 20 | import javax.persistence.Id; 21 | import javax.persistence.Table; 22 | 23 | @Entity 24 | @Table(name="person") 25 | public class Account { 26 | 27 | @Id 28 | private Integer id; 29 | 30 | @Column 31 | private String name; 32 | 33 | public Integer getId() { 34 | return id; 35 | } 36 | 37 | public void setId(Integer id) { 38 | this.id = id; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/src/main/java/ch/maxant/generic_jca_adapter/demo/AppController.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package ch.maxant.generic_jca_adapter.demo; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RequestParam; 21 | import org.springframework.web.bind.annotation.RestController; 22 | 23 | /** 24 | * a rest controller which calls thru to a service running inside a transaction. 25 | * call like this: http://localhost:8191/createUser?username=john 26 | */ 27 | @RestController 28 | public class AppController { 29 | 30 | @Autowired 31 | AppService appService; 32 | 33 | @RequestMapping("/createUser") 34 | public String createUser(@RequestParam(value="username") String username) throws Exception { 35 | return appService.doSomethingWithAGlobalTransactionAndARemoteMicroservice(username); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/src/main/java/ch/maxant/generic_jca_adapter/demo/AppRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package ch.maxant.generic_jca_adapter.demo; 17 | 18 | import org.springframework.data.jpa.repository.JpaRepository; 19 | 20 | public interface AppRepository extends JpaRepository { 21 | } 22 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-springboot-common/src/main/java/ch/maxant/generic_jca_adapter/demo/AppService.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | based on https://raw.githubusercontent.com/spring-projects/spring-boot/master/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountService.java 17 | */ 18 | 19 | package ch.maxant.generic_jca_adapter.demo; 20 | 21 | import javax.transaction.Transactional; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Qualifier; 25 | import org.springframework.stereotype.Service; 26 | 27 | import ch.maxant.generic_jca_adapter.BasicTransactionAssistanceFactory; 28 | import ch.maxant.generic_jca_adapter.TransactionAssistant; 29 | import ch.maxant.jca_demo.bookingsystem.BookingSystem; 30 | import ch.maxant.jca_demo.bookingsystem.BookingSystemWebServiceService; 31 | import ch.maxant.jca_demo.letterwriter.LetterWebServiceService; 32 | import ch.maxant.jca_demo.letterwriter.LetterWriter; 33 | 34 | @Service 35 | @Transactional 36 | public class AppService { 37 | 38 | @Autowired 39 | private AppRepository appRepository; 40 | 41 | @Autowired @Qualifier("xa/bookingService") 42 | BasicTransactionAssistanceFactory bookingServiceFactory; 43 | 44 | @Autowired @Qualifier("xa/letterService") 45 | BasicTransactionAssistanceFactory letterServiceFactory; 46 | 47 | public String doSomethingWithAGlobalTransactionAndARemoteMicroservice(String username) throws Exception { 48 | 49 | {//write to local database 50 | Account acct = new Account(); 51 | acct.setName(username); 52 | acct.setId(5000); 53 | //TODO not working in Atomikos with Mysql: 54 | // this.appRepository.save(acct); 55 | } 56 | 57 | String msResponse = null; 58 | 59 | //call microservice #1 60 | try(TransactionAssistant transactionAssistant = bookingServiceFactory.getTransactionAssistant()){ 61 | msResponse = transactionAssistant.executeInActiveTransaction(txid->{ 62 | final BookingSystem service = new BookingSystemWebServiceService().getBookingSystemPort(); 63 | return service.reserveTickets(txid, username); 64 | }); 65 | } 66 | 67 | //call microservice #2 68 | try(TransactionAssistant transactionAssistant = letterServiceFactory.getTransactionAssistant()){ 69 | msResponse = transactionAssistant.executeInActiveTransaction(txid->{ 70 | final LetterWriter service = new LetterWebServiceService().getLetterWriterPort(); 71 | return service.writeLetter(txid, username); 72 | }); 73 | } 74 | 75 | //simulate exception to cause rollback 76 | if ("john".equals(username)) { 77 | throw new RuntimeException("Simulated error"); 78 | } 79 | 80 | return msResponse; 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-atomikos/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Standalone Demo with Atomikos 2 | 3 | This is a demo of a standalone application which uses Atomikos as its Transaction Manager. 4 | 5 | This project contains the following classes: 6 | 7 | - `TestAtomikos` - An example of how to use Atomikos. It is not intended that you write your applications like this - use JCA+EJB or Spring instead! There is way too much boilerplate code here. Based on examples found at the Atomikos website. 8 | - `Main` - similar to the above class, but also calls web services. As per usual, the first step is to setup commit and rollback callbacks and the second step is to use the `BasicTransactionAssistanceFactory` to wrap the call to the back end service and bind it into the active transaction. This class does not use JNDI, rather creates a new instance of the `BasicTransactionAssistanceFactoryImpl` which takes care of ensuring that the `TransactionAssistant` which it returns is enlisted into the transaction and delisted when that object is closed. The registration of the commit/rollback callback is handled by the class named `TransactionConfigurator`. Note how you have to explicitly handle the transaction here by starting and committing it / rolling it back - that is why we recommend using EJB or Spring instead. 9 | 10 | ##License 11 | 12 | Copyright 2015 Ant Kutschera 13 | 14 | Licensed under the Apache License, Version 2.0 (the "License"); 15 | you may not use this file except in compliance with the License. 16 | You may obtain a copy of the License at 17 | 18 | http://www.apache.org/licenses/LICENSE-2.0 19 | 20 | Unless required by applicable law or agreed to in writing, software 21 | distributed under the License is distributed on an "AS IS" BASIS, 22 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | See the License for the specific language governing permissions and 24 | limitations under the License. 25 | 26 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-atomikos/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-standalone-atomikos 11 | jar 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | ch.maxant 21 | genericconnector-atomikos-api 22 | ${project.version} 23 | 24 | 25 | ch.maxant 26 | genericconnector-demo-common 27 | ${project.version} 28 | 29 | 30 | org.slf4j 31 | slf4j-api 32 | 1.7.12 33 | 34 | 35 | log4j 36 | log4j 37 | 1.2.17 38 | 39 | 40 | mysql 41 | mysql-connector-java 42 | 5.1.36 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-atomikos/src/main/java/ch/maxant/generic_jca_adapter/TestAtomikos.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.generic_jca_adapter; 18 | 19 | import java.sql.Connection; 20 | import java.sql.PreparedStatement; 21 | 22 | import javax.sql.XAConnection; 23 | import javax.transaction.Transaction; 24 | import javax.transaction.xa.XAResource; 25 | 26 | import com.atomikos.datasource.xa.jdbc.JdbcTransactionalResource; 27 | import com.atomikos.icatch.config.UserTransactionServiceImp; 28 | import com.atomikos.icatch.jta.UserTransactionManager; 29 | import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; 30 | 31 | /** 32 | * Working out how to use Atomikos, before building {@link Main}. 33 | * It is not intended that you write your applications like this - use JCA+EJB or Spring instead! 34 | * There is way too much boilerplate code here. 35 | * Based on examples found at the Atomikos website. 36 | */ 37 | public class TestAtomikos { 38 | 39 | public static void main(String[] args) throws Exception { 40 | 41 | MicroserviceXAResource ms = new MicroserviceXAResource("xa/ms1", new UnderlyingConnectionImpl() { 42 | private static final long serialVersionUID = 1L; 43 | @Override 44 | public void rollback(String txid) throws Exception { 45 | System.out.println(); //TODO 46 | } 47 | @Override 48 | public void commit(String txid) throws Exception { 49 | System.out.println(); //TODO 50 | } 51 | }); 52 | 53 | MysqlXADataSource mysql = new MysqlXADataSource(); 54 | mysql.setUser("root"); 55 | mysql.setPassword("password"); 56 | mysql.setUrl("jdbc:mysql://localhost:3306/temp?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"); 57 | JdbcTransactionalResource mysqlResource = new JdbcTransactionalResource("jdbc/mysql", mysql); 58 | 59 | UserTransactionServiceImp utsi = new UserTransactionServiceImp(); 60 | 61 | utsi.registerResource(mysqlResource); 62 | 63 | utsi.registerResource(new RecoverableMSResource(ms)); 64 | 65 | utsi.init(); 66 | 67 | UserTransactionManager utm = new UserTransactionManager(); 68 | 69 | utm.begin(); 70 | 71 | Transaction tx = utm.getTransaction(); 72 | 73 | tx.enlistResource(ms); 74 | 75 | XAConnection xamysql = mysql.getXAConnection(); 76 | XAResource db = xamysql.getXAResource(); 77 | tx.enlistResource(db); 78 | 79 | String username = "ant"; 80 | 81 | //call microservice 82 | String result = ms.executeInActiveTransaction(new ExecuteCallback() { 83 | @Override 84 | public String execute(String txid) throws Exception { 85 | return "executing " + txid; 86 | } 87 | }); 88 | System.out.println(result); 89 | 90 | //call db 91 | try(Connection connection = xamysql.getConnection()){ 92 | try(PreparedStatement stmt = connection.prepareStatement("insert into person(id, name) select max(id)+1, ? from person")){ 93 | stmt.setString(1, username); 94 | stmt.executeUpdate(); 95 | } 96 | } 97 | 98 | if(true){ 99 | tx.delistResource(ms, XAResource.TMSUCCESS); 100 | tx.delistResource(db, XAResource.TMSUCCESS); 101 | utm.commit(); 102 | }else{ 103 | tx.delistResource(ms, XAResource.TMFAIL); 104 | tx.delistResource(db, XAResource.TMFAIL); 105 | utm.rollback(); 106 | } 107 | 108 | utsi.shutdown(false); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-atomikos/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}:%L] %m%n 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-bitronix/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Standalone Demo with Bitronix 2 | 3 | This is a demo of a standalone application which uses Bitronix as its Transaction Manager. 4 | 5 | This project contains the following classes: 6 | 7 | - `Main` - An example of calling a database and some back end SOAP services. As per usual, the first step is to setup commit and rollback callbacks and the second step is to use the `BasicTransactionAssistanceFactory` to wrap the call to the back end service and bind it into the active transaction. This class uses JNDI since Bitronix comes with a simple JNDI implementation and puts all resources which are configured via its `bitronix-res.properties` file or its API into the JNDI tree. The `BasicTransactionAssistanceFactory` takes care of ensuring that the `TransactionAssistant` which it returns is enlisted into the transaction and delisted when that object is closed. The registration of the commit/rollback callback is handled by the class named `TransactionConfigurator`. Note how you have to explicitly handle the transaction here by starting and committing it / rolling it back - that is why we recommend using EJB or Spring instead. 8 | 9 | ##License 10 | 11 | Copyright 2015 Ant Kutschera 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | 25 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-bitronix/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-standalone-bitronix 11 | jar 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | ch.maxant 21 | genericconnector-bitronix-api 22 | ${project.version} 23 | 24 | 25 | ch.maxant 26 | genericconnector-demo-common 27 | ${project.version} 28 | 29 | 30 | org.slf4j 31 | slf4j-log4j12 32 | 1.7.12 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | 5.1.36 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-bitronix/src/main/resources/bitronix-default-config.properties: -------------------------------------------------------------------------------- 1 | bitronix.tm.resource.configuration=./src/main/resources/bitronix-res.properties 2 | 3 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-bitronix/src/main/resources/bitronix-res.properties: -------------------------------------------------------------------------------- 1 | bitronix.tm.resource.bind=true 2 | 3 | resource.ds1.className=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 4 | resource.ds1.uniqueName=jdbc/mysql1 5 | resource.ds1.minPoolSize=5 6 | resource.ds1.maxPoolSize=50 7 | resource.ds1.acquisitionTimeout=30 8 | resource.ds1.testQuery=select 1 from dual 9 | resource.ds1.deferConnectionRelease=true 10 | resource.ds1.driverProperties.user=root 11 | resource.ds1.driverProperties.password=password 12 | resource.ds1.driverProperties.URL=jdbc:mysql://localhost:3306/temp?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 13 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-standalone-bitronix/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}:%L] %m%n 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-atomikos/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Standalone Demo with Tomcat + Atomikos 2 | 3 | This is a demo of a standard Servlet 3.0 application which can be deployed to Tomcat (or Jetty), which uses Atomikos as its Transaction Manager. 4 | 5 | This project contains: 6 | 7 | - A class named `CreateUserServlet` - a standard Servlet implementation which can be called via the URL `http://localhost:8081/genericconnector-demo-tomcat-atomikos/sale?account=ant`. Pass it the account "john" to invoke a failure at the end of the transaction shortly before it is committed. The `doGet` method handles requests to the URL. This example has to manage the transaction manually by fetching the user transaction from JNDI. It can do that because the file named `context.xml` (which is Tomcat specific) puts the User Transaction into the JNDI tree. As with other examples, two web services are called within the transaction. The commit / rollback callback is registered when the servlet context is initialized via the `contextInitialized` method. Note that this method also starts up the Atomikos transaction manager - normally this would NOT be done like this, rather you would startup Atomikos just once for the entire server rather than each application. That requires different configuration and more details can be found at http://www.atomikos.com/Documentation/Tomcat7Integration35. Basically it involves using a Tomcat lifecycle listener to startup the transaction manager when the server starts, and involves putting the relevant libraries in the right places so that the server can find them during startup. 8 | 9 | ##Notes 10 | - If you deploy to Tomcat from inside Eclipse, then you may need to put the contents of the context.xml into the `Servers/Tomcat/server.xml`. 11 | 12 | ##License 13 | 14 | Copyright 2015 Ant Kutschera 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | Unless required by applicable law or agreed to in writing, software 23 | distributed under the License is distributed on an "AS IS" BASIS, 24 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | See the License for the specific language governing permissions and 26 | limitations under the License. 27 | 28 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-atomikos/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-tomcat-atomikos 11 | war 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | ch.maxant 21 | genericconnector-atomikos-api 22 | ${project.version} 23 | 24 | 25 | ch.maxant 26 | genericconnector-demo-common 27 | ${project.version} 28 | 29 | 30 | org.slf4j 31 | slf4j-log4j12 32 | 1.7.12 33 | 34 | 35 | 36 | 37 | com.atomikos 38 | transactions-osgi 39 | 3.9.3 40 | 41 | 42 | javax.transaction 43 | jta 44 | 1.1 45 | 46 | 47 | mysql 48 | mysql-connector-java 49 | 5.1.36 50 | 51 | 52 | org.slf4j 53 | slf4j-log4j12 54 | 1.7.12 55 | 56 | 57 | org.slf4j 58 | slf4j-api 59 | 1.7.12 60 | 61 | 62 | log4j 63 | log4j 64 | 1.2.17 65 | 66 | 67 | org.jboss.spec.javax.resource 68 | jboss-connector-api_1.6_spec 69 | 1.0.1.Final 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-atomikos/src/main/resources/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-atomikos/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | index.html 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Standalone Demo with Tomcat + Bitronix 2 | 3 | This is a demo of a standard Servlet 3.0 application which can be deployed to Tomcat (or Jetty), which uses Bitronix as its Transaction Manager. 4 | 5 | This project contains: 6 | 7 | - A class named `CreateUserServlet` - a standard Servlet implementation which can be called via the URL `http://localhost:8081/genericconnector-demo-tomcat-bitronix/sale?account=ant`. Pass it the account "john" to invoke a failure at the end of the transaction shortly before it is committed. The `doGet` method handles requests to the URL. This example has to manage the transaction manually by fetching the user transaction from JNDI. It can do that because the file named `context.xml` (which is Tomcat specific) puts the User Transaction into the JNDI tree. As with other examples, two web services are called within the transaction. The commit / rollback callback is registered when the servlet context is initialized via the `contextInitialized` method. Note that this method also starts up the Bitronix transaction manager - normally this would NOT be done like this, rather you would startup Bitronix just once for the entire server rather than each application. That requires different configuration and more details can be found at https://github.com/bitronix/btm. Basically it involves using a Tomcat lifecycle listener (`bitronix.tm.integration.tomcat55.BTMLifecycleListener`) to startup the transaction manager when the server starts, and involves putting the relevant libraries in the right places so that the server can find them during startup. 8 | - A folder named `add-to-tomcat` - contains Bitronix configuration files which must be available to the JVM which looks for a default file named `bitronix-default-config.properties` in the working directory. The location of that file can be overriden using a system property, for example `-Dbitronix.tm.configuration="../config/bitronix-default-config.properties` - see the Bitronix webiste for more information. Further information about configuring Tomcat can be found at http://bitronix-transaction-manager.10986.n7.nabble.com/tomcat-7-0-26-and-bitronix-td1155.html. 9 | 10 | ##Notes 11 | - If you deploy to Tomcat from inside Eclipse, then you may need to put the contents of the context.xml into the `Servers/Tomcat/server.xml`. 12 | 13 | ##License 14 | 15 | Copyright 2015 Ant Kutschera 16 | 17 | Licensed under the Apache License, Version 2.0 (the "License"); 18 | you may not use this file except in compliance with the License. 19 | You may obtain a copy of the License at 20 | 21 | http://www.apache.org/licenses/LICENSE-2.0 22 | 23 | Unless required by applicable law or agreed to in writing, software 24 | distributed under the License is distributed on an "AS IS" BASIS, 25 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | See the License for the specific language governing permissions and 27 | limitations under the License. 28 | 29 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/add-to-tomcat/bin/bitronix-default-config.properties: -------------------------------------------------------------------------------- 1 | bitronix.tm.resource.configuration=./bitronix-res.properties 2 | 3 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/add-to-tomcat/bin/bitronix-res.properties: -------------------------------------------------------------------------------- 1 | bitronix.tm.resource.bind=true 2 | 3 | resource.ds1.className=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 4 | resource.ds1.uniqueName=jdbc/mysql1 5 | resource.ds1.minPoolSize=5 6 | resource.ds1.maxPoolSize=50 7 | resource.ds1.acquisitionTimeout=30 8 | resource.ds1.testQuery=select 1 from dual 9 | resource.ds1.deferConnectionRelease=true 10 | resource.ds1.driverProperties.user=root 11 | resource.ds1.driverProperties.password=password 12 | resource.ds1.driverProperties.URL=jdbc:mysql://localhost:3306/temp?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 13 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/add-to-tomcat/bin/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}:%L] %m%n 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/add-to-tomcat/conf/server.xml-pieces.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-tomcat-bitronix 11 | war 12 | 13 | 14 | org.jboss.spec 15 | jboss-javaee-all-7.0 16 | 1.0.3.Final 17 | provided 18 | 19 | 20 | ch.maxant 21 | genericconnector-bitronix-api 22 | ${project.version} 23 | 24 | 25 | ch.maxant 26 | genericconnector-demo-common 27 | ${project.version} 28 | 29 | 30 | org.slf4j 31 | slf4j-log4j12 32 | 1.7.12 33 | 34 | 35 | 36 | 37 | org.codehaus.btm 38 | btm 39 | 2.1.4 40 | 41 | 42 | javax.transaction 43 | jta 44 | 1.1 45 | 46 | 47 | mysql 48 | mysql-connector-java 49 | 5.1.36 50 | 51 | 52 | org.slf4j 53 | slf4j-log4j12 54 | 1.7.12 55 | 56 | 57 | org.slf4j 58 | slf4j-api 59 | 1.7.12 60 | 61 | 62 | log4j 63 | log4j 64 | 1.2.17 65 | 66 | 67 | org.jboss.spec.javax.resource 68 | jboss-connector-api_1.6_spec 69 | 1.0.1.Final 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/src/main/resources/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-tomcat-bitronix/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | index.html 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-acquirer/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Acquirer Webservice 2 | 3 | This module contains a web service representing the acquirer in the blog article. 4 | 5 | The web service supports execution, commit, rollback and recovery. 6 | 7 | It must be deployed to `http://localhost:8080/genericconnector-demo-webservice-acquirer/AcquirerWebService` in order for the demo applications to work. 8 | 9 | ##License 10 | 11 | Copyright 2015 Ant Kutschera 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | 25 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-acquirer/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-webservice-acquirer 11 | war 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-war-plugin 17 | 2.6 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-acquirer/src/main/java/ch/maxant/jca_demo/acquirer/LogView.java: -------------------------------------------------------------------------------- 1 | package ch.maxant.jca_demo.acquirer; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.annotation.WebServlet; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | @WebServlet("/LogView") 12 | public class LogView extends HttpServlet { 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Override 16 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 | response.getWriter().append("

Acquirer

") 18 | .append("") 19 | .append("") 20 | .append("") 21 | .append("") 22 | .append("
executions").append(String.valueOf(AcquirerWebService.CALLS_EXECUTE.get())).append("
commits").append(String.valueOf(AcquirerWebService.CALLS_COMMIT.get())).append("
rollbacks").append(String.valueOf(AcquirerWebService.CALLS_ROLLBACK.get())).append("
recovery").append(String.valueOf(AcquirerWebService.CALLS_RECOVER.get())).append("
"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-acquirer/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Booking System Webservice 2 | 3 | This module contains a web service representing the booking system in the blog article. 4 | 5 | The web service supports execution, commit and rollback. 6 | 7 | It must be deployed to `http://localhost:8080/genericconnector-demo-webservice-bookingsystem/BookingSystemWebService` in order for the demo applications to work. 8 | 9 | ##License 10 | 11 | Copyright 2015 Ant Kutschera 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | 25 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-webservice-bookingsystem 11 | war 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-war-plugin 17 | 2.6 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/src/main/java/ch/maxant/jca_demo/bookingsystem/BookingSystemWebService.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.jca_demo.bookingsystem; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import javax.jws.WebParam; 25 | import javax.jws.WebService; 26 | 27 | @WebService(name="BookingSystem") 28 | public class BookingSystemWebService { 29 | 30 | public static final AtomicInteger CALLS_EXECUTE = new AtomicInteger(); 31 | public static final AtomicInteger CALLS_COMMIT = new AtomicInteger(); 32 | public static final AtomicInteger CALLS_ROLLBACK = new AtomicInteger(); 33 | 34 | public BookingSystemWebService(){ 35 | } 36 | 37 | private final Logger log = Logger.getLogger(this.getClass().getName()); 38 | 39 | public String reserveTickets(@WebParam(name="txid") String txid, @WebParam(name="referenceNumber") String referenceNumber) throws Exception { 40 | CALLS_EXECUTE.incrementAndGet(); 41 | log.log(Level.INFO, "EXECUTE: booking tickets with reference number " + referenceNumber + " for TXID " + txid); 42 | if("FAILWSBookingSystem".equals(referenceNumber)){ 43 | throw new Exception("failed for test purposes"); 44 | }else{ 45 | //TODO write persistently! 46 | return "RESERVED tickets: " + referenceNumber; 47 | } 48 | } 49 | 50 | public void bookTickets(@WebParam(name="txId") String txId) throws IOException{ 51 | CALLS_COMMIT.incrementAndGet(); 52 | 53 | //TODO write persistently! 54 | 55 | log.log(Level.INFO, "BOOK tickets: " + txId); 56 | } 57 | 58 | public void cancelTickets(@WebParam(name="txId") String txId) throws IOException { 59 | CALLS_ROLLBACK.incrementAndGet(); 60 | 61 | //TODO write persistently! 62 | 63 | log.log(Level.INFO, "CANCEL tickets: " + txId); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/src/main/java/ch/maxant/jca_demo/bookingsystem/LogView.java: -------------------------------------------------------------------------------- 1 | package ch.maxant.jca_demo.bookingsystem; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.annotation.WebServlet; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | @WebServlet("/LogView") 12 | public class LogView extends HttpServlet { 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Override 16 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 | response.getWriter().append("

Booking System

") 18 | .append("") 19 | .append("") 20 | .append("") 21 | .append("
executions").append(String.valueOf(BookingSystemWebService.CALLS_EXECUTE.get())).append("
commits").append(String.valueOf(BookingSystemWebService.CALLS_COMMIT.get())).append("
rollbacks").append(String.valueOf(BookingSystemWebService.CALLS_ROLLBACK.get())).append("
"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-bookingsystem/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/README.md: -------------------------------------------------------------------------------- 1 | #genericconnector Demo - Letter Webservice 2 | 3 | This module contains a web service representing the letter writing service in the blog article. 4 | 5 | The web service supports only execution and rollback. 6 | 7 | It must be deployed to `http://localhost:8080/genericconnector-demo-webservice-letter/LetterWebService` in order for the demo applications to work. 8 | 9 | ##License 10 | 11 | Copyright 2015 Ant Kutschera 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | 25 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ch.maxant 6 | genericconnector-demo-parent 7 | 2.1.1-SNAPSHOT 8 | ../genericconnector-demo-parent 9 | 10 | genericconnector-demo-webservice-letter 11 | war 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-war-plugin 17 | 2.6 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/src/main/java/ch/maxant/jca_demo/letterwriter/LetterWebService.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Ant Kutschera 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | */ 17 | package ch.maxant.jca_demo.letterwriter; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import javax.jws.WebParam; 25 | import javax.jws.WebService; 26 | 27 | @WebService(name="LetterWriter") 28 | public class LetterWebService { 29 | 30 | private final Logger log = Logger.getLogger(this.getClass().getName()); 31 | 32 | public static final AtomicInteger CALLS_EXECUTE = new AtomicInteger(); 33 | public static final AtomicInteger CALLS_ROLLBACK = new AtomicInteger(); 34 | 35 | public String writeLetter(@WebParam(name="txid") String txid, @WebParam(name="referenceNumber") String referenceNumber) throws Exception { 36 | CALLS_EXECUTE.incrementAndGet(); 37 | 38 | log.log(Level.INFO, "SEND LETTER: " + referenceNumber + " for TXID " + txid); 39 | if("FAILWSLetterWriter".equals(referenceNumber)){ 40 | throw new Exception("failed for test purposes"); 41 | }else{ 42 | return "will write letter at close of business: " + referenceNumber; 43 | } 44 | } 45 | 46 | public void cancelLetter(@WebParam(name="txId") String txId) throws IOException{ 47 | CALLS_ROLLBACK.incrementAndGet(); 48 | 49 | log.log(Level.INFO, "ROLLBACK LETTER: " + txId); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/src/main/java/ch/maxant/jca_demo/letterwriter/LogView.java: -------------------------------------------------------------------------------- 1 | package ch.maxant.jca_demo.letterwriter; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.annotation.WebServlet; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | @WebServlet("/LogView") 12 | public class LogView extends HttpServlet { 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Override 16 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 | response.getWriter().append("

Letter Writer

") 18 | .append("") 19 | .append("") 20 | .append("
executions incl. commit").append(String.valueOf(LetterWebService.CALLS_EXECUTE.get())).append("
rollbacks").append(String.valueOf(LetterWebService.CALLS_ROLLBACK.get())).append("
"); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /demo/genericconnector-demo-webservice-letter/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | --------------------------------------------------------------------------------