From c15e3a7e2f2cd71a83ac78c52151f0d0912c9aa7 Mon Sep 17 00:00:00 2001 From: Josh Long Date: Wed, 20 Aug 2014 16:44:23 -0700 Subject: [PATCH] Add Atomikos and Bitronix JTA samples Add samples and integration tests for Atomikos and Bitronix JTA. See gh-947 --- spring-boot-samples/pom.xml | 2 + .../spring-boot-sample-jta-atomikos/pom.xml | 60 +++++++++++++++ .../main/java/sample/atomikos/Account.java | 43 +++++++++++ .../sample/atomikos/AccountRepository.java | 23 ++++++ .../java/sample/atomikos/AccountService.java | 47 ++++++++++++ .../main/java/sample/atomikos/Messages.java | 30 ++++++++ .../atomikos/SampleAtomikosApplication.java | 50 +++++++++++++ .../src/main/resources/application.properties | 5 ++ .../SampleAtomikosApplicationTests.java | 71 ++++++++++++++++++ .../spring-boot-sample-jta-bitronix/pom.xml | 61 ++++++++++++++++ .../main/java/sample/bitronix/Account.java | 43 +++++++++++ .../sample/bitronix/AccountRepository.java | 23 ++++++ .../java/sample/bitronix/AccountService.java | 47 ++++++++++++ .../main/java/sample/bitronix/Messages.java | 30 ++++++++ .../bitronix/SampleBitronixApplication.java | 50 +++++++++++++ .../src/main/resources/application.properties | 3 + .../SampleBitronixApplicationTests.java | 73 +++++++++++++++++++ 17 files changed, 661 insertions(+) create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Account.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountRepository.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountService.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Messages.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/SampleAtomikosApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/resources/application.properties create mode 100644 spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Account.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountRepository.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountService.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Messages.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/resources/application.properties create mode 100644 spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index e4cddbedf6..6bd30f875a 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -38,6 +38,8 @@ spring-boot-sample-hornetq spring-boot-sample-integration spring-boot-sample-jetty + spring-boot-sample-jta-atomikos + spring-boot-sample-jta-bitronix spring-boot-sample-liquibase spring-boot-sample-parent-context spring-boot-sample-profile diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/pom.xml b/spring-boot-samples/spring-boot-sample-jta-atomikos/pom.xml new file mode 100644 index 0000000000..bc7c05ce6d --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.2.0.BUILD-SNAPSHOT + + spring-boot-sample-jta-atomikos + Spring Boot Atomikos JTA Sample + Spring Boot Atomikos JTA Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework + spring-jms + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-jta-atomikos + + + org.springframework.boot + spring-boot-starter-hornetq + + + org.hornetq + hornetq-jms-server + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Account.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Account.java new file mode 100644 index 0000000000..d40c546003 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Account.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Account { + + @Id + @GeneratedValue + private Long id; + + private String username; + + Account() { + } + + public Account(String username) { + this.username = username; + } + + public String getUsername() { + return this.username; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountRepository.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountRepository.java new file mode 100644 index 0000000000..6b88cb4cb4 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccountRepository extends JpaRepository { + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountService.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountService.java new file mode 100644 index 0000000000..5f84d308f2 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/AccountService.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Service; + +@Service +@Transactional +public class AccountService { + + private final JmsTemplate jmsTemplate; + + private final AccountRepository accountRepository; + + @Autowired + public AccountService(JmsTemplate jmsTemplate, AccountRepository accountRepository) { + this.jmsTemplate = jmsTemplate; + this.accountRepository = accountRepository; + } + + public void createAccountAndNotify(String username) { + this.jmsTemplate.convertAndSend("accounts", username); + this.accountRepository.save(new Account(username)); + if ("error".equals(username)) { + throw new RuntimeException("Simulated error"); + } + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Messages.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Messages.java new file mode 100644 index 0000000000..d6f185f28b --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/Messages.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import org.springframework.jms.annotation.JmsListener; +import org.springframework.stereotype.Component; + +@Component +public class Messages { + + @JmsListener(destination = "accounts") + public void onMessage(String content) { + System.out.println("----> " + content); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/SampleAtomikosApplication.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/SampleAtomikosApplication.java new file mode 100644 index 0000000000..e0094a3e4a --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/java/sample/atomikos/SampleAtomikosApplication.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import java.io.Closeable; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +public class SampleAtomikosApplication { + + public static void main(String[] args) throws Exception { + ApplicationContext context = SpringApplication.run( + SampleAtomikosApplication.class, args); + AccountService service = context.getBean(AccountService.class); + AccountRepository repository = context.getBean(AccountRepository.class); + service.createAccountAndNotify("josh"); + System.out.println("Count is " + repository.count()); + try { + service.createAccountAndNotify("error"); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + System.out.println("Count is " + repository.count()); + Thread.sleep(100); + ((Closeable) context).close(); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/resources/application.properties new file mode 100644 index 0000000000..62806e0ea8 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.hornetq.mode=embedded +spring.hornetq.embedded.enabled=true +spring.hornetq.embedded.queues=accounts + +logging.level.com.atomikos=WARN diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java new file mode 100644 index 0000000000..3950c3dfa8 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.atomikos; + +import org.hamcrest.Matcher; +import org.hamcrest.core.SubstringMatcher; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.test.OutputCapture; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Basic integration tests for demo application. + * + * @author Phillip Webb + */ +public class SampleAtomikosApplicationTests { + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + @Test + public void testTransactionRollback() throws Exception { + SampleAtomikosApplication.main(new String[] {}); + String expected = ""; + expected += "----> josh\n"; + expected += "Count is 1\n"; + expected += "Simulated error\n"; + expected += "Count is 1\n"; + assertThat(this.outputCapture.toString(), containsString(expected)); + assertThat(this.outputCapture.toString(), containsStringOnce("---->")); + } + + private Matcher containsStringOnce(String s) { + return new SubstringMatcher(s) { + + @Override + protected String relationship() { + return "containing once"; + } + + @Override + protected boolean evalSubstringOf(String s) { + int i = 0; + while (s.contains(this.substring)) { + s = s.substring(s.indexOf(this.substring) + this.substring.length()); + i++; + } + return i == 1; + } + + }; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/pom.xml b/spring-boot-samples/spring-boot-sample-jta-bitronix/pom.xml new file mode 100644 index 0000000000..a88a235c53 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.2.0.BUILD-SNAPSHOT + + spring-boot-sample-jta-bitronix + Spring Boot Bitronix JTA Sample + Spring Boot Bitronix JTA Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework + spring-jms + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-jta-bitronix + + + org.springframework.boot + spring-boot-starter-hornetq + + + org.hornetq + hornetq-jms-server + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Account.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Account.java new file mode 100644 index 0000000000..183e4c595a --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Account.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Account { + + @Id + @GeneratedValue + private Long id; + + private String username; + + Account() { + } + + public Account(String username) { + this.username = username; + } + + public String getUsername() { + return this.username; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountRepository.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountRepository.java new file mode 100644 index 0000000000..53978fa7d0 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccountRepository extends JpaRepository { + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountService.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountService.java new file mode 100644 index 0000000000..752adf7611 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/AccountService.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Service; + +@Service +@Transactional +public class AccountService { + + private final JmsTemplate jmsTemplate; + + private final AccountRepository accountRepository; + + @Autowired + public AccountService(JmsTemplate jmsTemplate, AccountRepository accountRepository) { + this.jmsTemplate = jmsTemplate; + this.accountRepository = accountRepository; + } + + public void createAccountAndNotify(String username) { + this.jmsTemplate.convertAndSend("accounts", username); + this.accountRepository.save(new Account(username)); + if ("error".equals(username)) { + throw new RuntimeException("Simulated error"); + } + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Messages.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Messages.java new file mode 100644 index 0000000000..cdaddd76b6 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/Messages.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import org.springframework.jms.annotation.JmsListener; +import org.springframework.stereotype.Component; + +@Component +public class Messages { + + @JmsListener(destination = "accounts") + public void onMessage(String content) { + System.out.println("----> " + content); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java new file mode 100644 index 0000000000..62fb930224 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/java/sample/bitronix/SampleBitronixApplication.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import java.io.Closeable; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +public class SampleBitronixApplication { + + public static void main(String[] args) throws Exception { + ApplicationContext context = SpringApplication.run( + SampleBitronixApplication.class, args); + AccountService service = context.getBean(AccountService.class); + AccountRepository repository = context.getBean(AccountRepository.class); + service.createAccountAndNotify("josh"); + System.out.println("Count is " + repository.count()); + try { + service.createAccountAndNotify("error"); + } + catch (Exception ex) { + System.out.println(ex.getMessage()); + } + System.out.println("Count is " + repository.count()); + Thread.sleep(100); + ((Closeable) context).close(); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/resources/application.properties new file mode 100644 index 0000000000..ca501b18cc --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.hornetq.mode=embedded +spring.hornetq.embedded.enabled=true +spring.hornetq.embedded.queues=accounts diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java new file mode 100644 index 0000000000..096d1719e2 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.bitronix; + +import org.hamcrest.Matcher; +import org.hamcrest.core.SubstringMatcher; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.test.OutputCapture; + +import sample.bitronix.SampleBitronixApplication; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Basic integration tests for demo application. + * + * @author Phillip Webb + */ +public class SampleBitronixApplicationTests { + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + @Test + public void testTransactionRollback() throws Exception { + SampleBitronixApplication.main(new String[] {}); + String expected = ""; + expected += "----> josh\n"; + expected += "Count is 1\n"; + expected += "Simulated error\n"; + expected += "Count is 1\n"; + assertThat(this.outputCapture.toString(), containsString(expected)); + assertThat(this.outputCapture.toString(), containsStringOnce("---->")); + } + + private Matcher containsStringOnce(String s) { + return new SubstringMatcher(s) { + + @Override + protected String relationship() { + return "containing once"; + } + + @Override + protected boolean evalSubstringOf(String s) { + int i = 0; + while (s.contains(this.substring)) { + s = s.substring(s.indexOf(this.substring) + this.substring.length()); + i++; + } + return i == 1; + } + + }; + } + +}