Skip to content

Commit c15e3a7

Browse files
Josh Longphilwebb
authored andcommitted
Add Atomikos and Bitronix JTA samples
Add samples and integration tests for Atomikos and Bitronix JTA. See spring-projectsgh-947
1 parent e116092 commit c15e3a7

File tree

17 files changed

+661
-0
lines changed

17 files changed

+661
-0
lines changed

spring-boot-samples/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
<module>spring-boot-sample-hornetq</module>
3939
<module>spring-boot-sample-integration</module>
4040
<module>spring-boot-sample-jetty</module>
41+
<module>spring-boot-sample-jta-atomikos</module>
42+
<module>spring-boot-sample-jta-bitronix</module>
4143
<module>spring-boot-sample-liquibase</module>
4244
<module>spring-boot-sample-parent-context</module>
4345
<module>spring-boot-sample-profile</module>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<!-- Your own application should inherit from spring-boot-starter-parent -->
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-samples</artifactId>
8+
<version>1.2.0.BUILD-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>spring-boot-sample-jta-atomikos</artifactId>
11+
<name>Spring Boot Atomikos JTA Sample</name>
12+
<description>Spring Boot Atomikos JTA Sample</description>
13+
<url>http://projects.spring.io/spring-boot/</url>
14+
<organization>
15+
<name>Pivotal Software, Inc.</name>
16+
<url>http://www.spring.io</url>
17+
</organization>
18+
<properties>
19+
<main.basedir>${basedir}/../..</main.basedir>
20+
</properties>
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.springframework</groupId>
24+
<artifactId>spring-jms</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.springframework.boot</groupId>
28+
<artifactId>spring-boot-starter-data-jpa</artifactId>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.springframework.boot</groupId>
32+
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.springframework.boot</groupId>
36+
<artifactId>spring-boot-starter-hornetq</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.hornetq</groupId>
40+
<artifactId>hornetq-jms-server</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>com.h2database</groupId>
44+
<artifactId>h2</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.springframework.boot</groupId>
48+
<artifactId>spring-boot-starter-test</artifactId>
49+
<scope>test</scope>
50+
</dependency>
51+
</dependencies>
52+
<build>
53+
<plugins>
54+
<plugin>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-maven-plugin</artifactId>
57+
</plugin>
58+
</plugins>
59+
</build>
60+
</project>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import javax.persistence.Entity;
20+
import javax.persistence.GeneratedValue;
21+
import javax.persistence.Id;
22+
23+
@Entity
24+
public class Account {
25+
26+
@Id
27+
@GeneratedValue
28+
private Long id;
29+
30+
private String username;
31+
32+
Account() {
33+
}
34+
35+
public Account(String username) {
36+
this.username = username;
37+
}
38+
39+
public String getUsername() {
40+
return this.username;
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import org.springframework.data.jpa.repository.JpaRepository;
20+
21+
public interface AccountRepository extends JpaRepository<Account, Long> {
22+
23+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import javax.transaction.Transactional;
20+
21+
import org.springframework.beans.factory.annotation.Autowired;
22+
import org.springframework.jms.core.JmsTemplate;
23+
import org.springframework.stereotype.Service;
24+
25+
@Service
26+
@Transactional
27+
public class AccountService {
28+
29+
private final JmsTemplate jmsTemplate;
30+
31+
private final AccountRepository accountRepository;
32+
33+
@Autowired
34+
public AccountService(JmsTemplate jmsTemplate, AccountRepository accountRepository) {
35+
this.jmsTemplate = jmsTemplate;
36+
this.accountRepository = accountRepository;
37+
}
38+
39+
public void createAccountAndNotify(String username) {
40+
this.jmsTemplate.convertAndSend("accounts", username);
41+
this.accountRepository.save(new Account(username));
42+
if ("error".equals(username)) {
43+
throw new RuntimeException("Simulated error");
44+
}
45+
}
46+
47+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import org.springframework.jms.annotation.JmsListener;
20+
import org.springframework.stereotype.Component;
21+
22+
@Component
23+
public class Messages {
24+
25+
@JmsListener(destination = "accounts")
26+
public void onMessage(String content) {
27+
System.out.println("----> " + content);
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import java.io.Closeable;
20+
21+
import org.springframework.boot.SpringApplication;
22+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
23+
import org.springframework.context.ApplicationContext;
24+
import org.springframework.context.annotation.ComponentScan;
25+
import org.springframework.context.annotation.Configuration;
26+
27+
@Configuration
28+
@ComponentScan
29+
@EnableAutoConfiguration
30+
public class SampleAtomikosApplication {
31+
32+
public static void main(String[] args) throws Exception {
33+
ApplicationContext context = SpringApplication.run(
34+
SampleAtomikosApplication.class, args);
35+
AccountService service = context.getBean(AccountService.class);
36+
AccountRepository repository = context.getBean(AccountRepository.class);
37+
service.createAccountAndNotify("josh");
38+
System.out.println("Count is " + repository.count());
39+
try {
40+
service.createAccountAndNotify("error");
41+
}
42+
catch (Exception ex) {
43+
System.out.println(ex.getMessage());
44+
}
45+
System.out.println("Count is " + repository.count());
46+
Thread.sleep(100);
47+
((Closeable) context).close();
48+
}
49+
50+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
spring.hornetq.mode=embedded
2+
spring.hornetq.embedded.enabled=true
3+
spring.hornetq.embedded.queues=accounts
4+
5+
logging.level.com.atomikos=WARN
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
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 sample.atomikos;
18+
19+
import org.hamcrest.Matcher;
20+
import org.hamcrest.core.SubstringMatcher;
21+
import org.junit.Rule;
22+
import org.junit.Test;
23+
import org.springframework.boot.test.OutputCapture;
24+
25+
import static org.hamcrest.Matchers.containsString;
26+
import static org.junit.Assert.assertThat;
27+
28+
/**
29+
* Basic integration tests for demo application.
30+
*
31+
* @author Phillip Webb
32+
*/
33+
public class SampleAtomikosApplicationTests {
34+
35+
@Rule
36+
public OutputCapture outputCapture = new OutputCapture();
37+
38+
@Test
39+
public void testTransactionRollback() throws Exception {
40+
SampleAtomikosApplication.main(new String[] {});
41+
String expected = "";
42+
expected += "----> josh\n";
43+
expected += "Count is 1\n";
44+
expected += "Simulated error\n";
45+
expected += "Count is 1\n";
46+
assertThat(this.outputCapture.toString(), containsString(expected));
47+
assertThat(this.outputCapture.toString(), containsStringOnce("---->"));
48+
}
49+
50+
private Matcher<? super String> containsStringOnce(String s) {
51+
return new SubstringMatcher(s) {
52+
53+
@Override
54+
protected String relationship() {
55+
return "containing once";
56+
}
57+
58+
@Override
59+
protected boolean evalSubstringOf(String s) {
60+
int i = 0;
61+
while (s.contains(this.substring)) {
62+
s = s.substring(s.indexOf(this.substring) + this.substring.length());
63+
i++;
64+
}
65+
return i == 1;
66+
}
67+
68+
};
69+
}
70+
71+
}

0 commit comments

Comments
 (0)