From 545d9570311d0c08386d28093a841f11f79967f6 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 15 May 2023 11:25:40 +0200 Subject: [PATCH] Polishing. Reformat code. Refine dependencies. See #650 Original pull request: #663 --- couchbase/pom.xml | 11 +- couchbase/reactive/pom.xml | 5 - couchbase/transactions/pom.xml | 100 ++++-------- .../java/com/example/demo/AirlineGates.java | 60 +++---- .../example/demo/AirlineGatesRepository.java | 5 +- .../com/example/demo/AirlineGatesService.java | 133 ++++++++------- .../main/java/com/example/demo/CmdRunner.java | 153 +++++++++--------- .../main/java/com/example/demo/Config.java | 52 +++--- .../com/example/demo/DemoApplication.java | 21 ++- .../src/main/resources/application.properties | 1 - .../example/demo/DemoApplicationTests.java | 17 +- .../util/CouchbaseAvailableRule.java | 71 ++++---- 12 files changed, 310 insertions(+), 319 deletions(-) delete mode 100644 couchbase/transactions/src/main/resources/application.properties diff --git a/couchbase/pom.xml b/couchbase/pom.xml index 37eee305..9f741275 100644 --- a/couchbase/pom.xml +++ b/couchbase/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 spring-data-couchbase-examples @@ -24,9 +25,9 @@ - - org.springframework.data - spring-data-couchbase + + org.springframework.boot + spring-boot-starter-data-couchbase diff --git a/couchbase/reactive/pom.xml b/couchbase/reactive/pom.xml index 1c488f0d..8847abe5 100644 --- a/couchbase/reactive/pom.xml +++ b/couchbase/reactive/pom.xml @@ -13,11 +13,6 @@ - - org.springframework.boot - spring-boot-starter-data-couchbase-reactive - - io.projectreactor reactor-core diff --git a/couchbase/transactions/pom.xml b/couchbase/transactions/pom.xml index bf032df9..dd815481 100644 --- a/couchbase/transactions/pom.xml +++ b/couchbase/transactions/pom.xml @@ -1,80 +1,42 @@ - - 4.0.0 + 4.0.0 - spring-data-couchbase-transactions - Spring Data Couchbase - Transaction example - Transactions Demo project for Spring Data Couchbase + spring-data-couchbase-transactions + Spring Data Couchbase - Transaction example + Transactions Demo project for Spring Data Couchbase - - org.springframework.data.examples - spring-data-couchbase-examples - 2.0.0.BUILD-SNAPSHOT - + + org.springframework.data.examples + spring-data-couchbase-examples + 2.0.0.BUILD-SNAPSHOT + - - - org.springframework.boot - spring-boot-starter-data-couchbase - + - - org.springframework.boot - spring-boot-starter-test - test - + + ${project.groupId} + spring-data-couchbase-example-utils + ${project.version} + - - ${project.groupId} - spring-data-couchbase-example-utils - ${project.version} - test - - - org.springframework.data.examples - spring-data-couchbase-example-utils - 2.0.0.BUILD-SNAPSHOT - test - + + junit + junit + compile + - + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - spring-libs-snapshot - https://repo.spring.io/libs-snapshot - - - sonatype-snapshot - https://oss.sonatype.org/content/repositories/snapshots - - true - - - false - - - - - - - spring-snapshots - https://repo.spring.io/snapshot - - - spring-milestones - https://repo.spring.io/milestone - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/couchbase/transactions/src/main/java/com/example/demo/AirlineGates.java b/couchbase/transactions/src/main/java/com/example/demo/AirlineGates.java index 83623427..5df4d5e3 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/AirlineGates.java +++ b/couchbase/transactions/src/main/java/com/example/demo/AirlineGates.java @@ -16,7 +16,6 @@ package com.example.demo; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.index.QueryIndexed; import org.springframework.data.couchbase.core.mapping.Document; @@ -26,37 +25,40 @@ import org.springframework.data.couchbase.core.mapping.Document; */ @Document public class AirlineGates { - @Id String id; - @Version Long version; - @QueryIndexed String name; - String iata; - Long gates; + @Id + String id; + @Version + Long version; + @QueryIndexed + String name; + String iata; + Long gates; - @PersistenceConstructor - public AirlineGates(String id, String name, String iata, Long gates) { - this.id = id; - this.name = name; - this.iata = iata; - this.gates = gates; - } + public AirlineGates(String id, String name, String iata, Long gates) { + this.id = id; + this.name = name; + this.iata = iata; + this.gates = gates; + } - public String getId() { - return id; - } - public Long getGates() { - return gates; - } + public String getId() { + return id; + } - public String toString(){ - StringBuffer sb=new StringBuffer(); - sb.append("{"); - sb.append("\"id\":"+id); - sb.append(", \"name\":"+name); - sb.append(", \"iata\":"+iata); - sb.append(", \"gates\":"+gates); - sb.append("}"); + public Long getGates() { + return gates; + } - return sb.toString(); - } + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("{"); + sb.append("\"id\":" + id); + sb.append(", \"name\":" + name); + sb.append(", \"iata\":" + iata); + sb.append(", \"gates\":" + gates); + sb.append("}"); + + return sb.toString(); + } } diff --git a/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesRepository.java b/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesRepository.java index 49b974ed..e5a0cba5 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesRepository.java +++ b/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesRepository.java @@ -13,18 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.demo; import org.springframework.data.couchbase.repository.CouchbaseRepository; import org.springframework.data.couchbase.repository.DynamicProxyable; -import org.springframework.stereotype.Repository; /** * @author Michael Reiche */ -@Repository public interface AirlineGatesRepository - extends CouchbaseRepository, DynamicProxyable { + extends CouchbaseRepository, DynamicProxyable { } diff --git a/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesService.java b/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesService.java index 273e3e6f..7b10db7b 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesService.java +++ b/couchbase/transactions/src/main/java/com/example/demo/AirlineGatesService.java @@ -15,89 +15,88 @@ */ package com.example.demo; -import reactor.core.publisher.Mono; - import org.springframework.data.couchbase.core.CouchbaseTemplate; import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate; -import org.springframework.data.couchbase.core.TransactionalSupport; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import reactor.core.publisher.Mono; + /** * @author Michael Reiche */ @Service public class AirlineGatesService { - CouchbaseTemplate template; - ReactiveCouchbaseTemplate reactiveTemplate; - AirlineGatesRepository airlineGatesRepository; + CouchbaseTemplate template; + ReactiveCouchbaseTemplate reactiveTemplate; + AirlineGatesRepository airlineGatesRepository; - public AirlineGatesService(CouchbaseTemplate template, AirlineGatesRepository airlineGatesRepository) { - this.template = template; - this.reactiveTemplate = template.reactive(); - this.airlineGatesRepository = airlineGatesRepository; - } + public AirlineGatesService(CouchbaseTemplate template, AirlineGatesRepository airlineGatesRepository) { + this.template = template; + this.reactiveTemplate = template.reactive(); + this.airlineGatesRepository = airlineGatesRepository; + } - @Transactional - public void transferGates(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) { - AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId); - AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId); - toAirlineGates.gates += gatesToTransfer; - fromAirlineGates.gates -= gatesToTransfer; - template.save(fromAirlineGates); - if (exceptionToThrow != null) { - throw exceptionToThrow; - } - template.save(toAirlineGates); - } + @Transactional + public void transferGates(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) { + AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId); + AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId); + toAirlineGates.gates += gatesToTransfer; + fromAirlineGates.gates -= gatesToTransfer; + template.save(fromAirlineGates); + if (exceptionToThrow != null) { + throw exceptionToThrow; + } + template.save(toAirlineGates); + } - @Transactional - public void transferGatesRepo(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) { - AirlineGates fromAirlineGates = airlineGatesRepository.findById(fromId).orElse(null); - AirlineGates toAirlineGates = airlineGatesRepository.findById(toId).orElse(null); - toAirlineGates.gates += gatesToTransfer; - fromAirlineGates.gates -= gatesToTransfer; - airlineGatesRepository.save(fromAirlineGates); - if (exceptionToThrow != null) { - throw exceptionToThrow; - } - airlineGatesRepository.save(toAirlineGates); - } + @Transactional + public void transferGatesRepo(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) { + AirlineGates fromAirlineGates = airlineGatesRepository.findById(fromId).orElse(null); + AirlineGates toAirlineGates = airlineGatesRepository.findById(toId).orElse(null); + toAirlineGates.gates += gatesToTransfer; + fromAirlineGates.gates -= gatesToTransfer; + airlineGatesRepository.save(fromAirlineGates); + if (exceptionToThrow != null) { + throw exceptionToThrow; + } + airlineGatesRepository.save(toAirlineGates); + } - // The @Transactional annotation results in the method of the proxy for the service executing this in a transaction - @Transactional - public Mono transferGatesReactive(String fromId, String toId, int gatesToTransfer, - RuntimeException exceptionToThrow) { - return Mono.deferContextual(ctx -> { - AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId); - AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId); - toAirlineGates.gates += gatesToTransfer; - fromAirlineGates.gates -= gatesToTransfer; - template.save(fromAirlineGates); - if (exceptionToThrow != null) { - throw exceptionToThrow; - } - return reactiveTemplate.save(toAirlineGates).then(); - }); - } + // The @Transactional annotation results in the method of the proxy for the service executing this in a transaction + @Transactional + public Mono transferGatesReactive(String fromId, String toId, int gatesToTransfer, + RuntimeException exceptionToThrow) { + return Mono.deferContextual(ctx -> { + AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId); + AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId); + toAirlineGates.gates += gatesToTransfer; + fromAirlineGates.gates -= gatesToTransfer; + template.save(fromAirlineGates); + if (exceptionToThrow != null) { + throw exceptionToThrow; + } + return reactiveTemplate.save(toAirlineGates).then(); + }); + } - // This does not have the @Transactional annotation therefore is not executed in a transaction - public AirlineGates save(AirlineGates airlineGates) { - return template.save(airlineGates); - } + // This does not have the @Transactional annotation therefore is not executed in a transaction + public AirlineGates save(AirlineGates airlineGates) { + return template.save(airlineGates); + } - // This does not have the @Transactional annotation therefore is not executed in a transaction - public AirlineGates findById(String id) { - return template.findById(AirlineGates.class).one(id); - } + // This does not have the @Transactional annotation therefore is not executed in a transaction + public AirlineGates findById(String id) { + return template.findById(AirlineGates.class).one(id); + } - // This does not have the @Transactional annotation therefore is not executed in a transaction - public AirlineGates saveRepo(AirlineGates airlineGates) { - return airlineGatesRepository.save(airlineGates); - } + // This does not have the @Transactional annotation therefore is not executed in a transaction + public AirlineGates saveRepo(AirlineGates airlineGates) { + return airlineGatesRepository.save(airlineGates); + } - // This does not have the @Transactional annotation therefore is not executed in a transaction - public AirlineGates findByIdRepo(String id) { - return airlineGatesRepository.findById(id).orElse(null); - } + // This does not have the @Transactional annotation therefore is not executed in a transaction + public AirlineGates findByIdRepo(String id) { + return airlineGatesRepository.findById(id).orElse(null); + } } diff --git a/couchbase/transactions/src/main/java/com/example/demo/CmdRunner.java b/couchbase/transactions/src/main/java/com/example/demo/CmdRunner.java index 20d02408..43c9724e 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/CmdRunner.java +++ b/couchbase/transactions/src/main/java/com/example/demo/CmdRunner.java @@ -23,93 +23,98 @@ import org.springframework.stereotype.Component; import org.springframework.util.Assert; /** - * Components of the type CommandLineRunner are called right after the application start up. So the method *run* is - * called as soon as the application starts. - * + * Components of the type CommandLineRunner are called right after the application start up. So the method *run* is called as + * soon as the application starts. + * * @author Michael Reiche */ @Component public class CmdRunner implements CommandLineRunner { - @Autowired CouchbaseTemplate template; - @Autowired AirlineGatesService airlineGatesService; + @Autowired + CouchbaseTemplate template; + @Autowired + AirlineGatesService airlineGatesService; - //@Override - public void run(String... strings) { + // @Override + public void run(String... strings) { - try { // remove leftovers from previous run - template.removeById(AirlineGates.class).one("1"); - } catch (Exception e) {} - try { - template.removeById(AirlineGates.class).one("2"); - } catch (Exception e) {} + try { // remove leftovers from previous run + template.removeById(AirlineGates.class).one("1"); + } catch (Exception e) { + } + try { + template.removeById(AirlineGates.class).one("2"); + } catch (Exception e) { + } - AirlineGates airlineGates1 = new AirlineGates("1", "American Airlines", "JFK", Long.valueOf(200)); // 1 - AirlineGates airlineGates2 = new AirlineGates("2", "Lufthansa", "JFK", Long.valueOf(200)); - AirlineGates saved1 = airlineGatesService.save(airlineGates1); - AirlineGates saved2 = airlineGatesService.save(airlineGates2); - AirlineGates found_a_1 = airlineGatesService.findById(saved1.getId()); // 2 - AirlineGates found_a_2 = airlineGatesService.findById(saved2.getId()); - System.err.println("initialized airlines"); - System.err.println(" found before transferGates: " + found_a_1); - System.err.println(" found before transferGates: " + found_a_2); - // move 50 gates from airline1 to airline2 - int gatesToTransfer = 50; - System.err.println("==============================================================="); - System.err.println("this transferGates attempt will succeed. transferring " + gatesToTransfer); + AirlineGates airlineGates1 = new AirlineGates("1", "American Airlines", "JFK", Long.valueOf(200)); // 1 + AirlineGates airlineGates2 = new AirlineGates("2", "Lufthansa", "JFK", Long.valueOf(200)); + AirlineGates saved1 = airlineGatesService.save(airlineGates1); + AirlineGates saved2 = airlineGatesService.save(airlineGates2); + AirlineGates found_a_1 = airlineGatesService.findById(saved1.getId()); // 2 + AirlineGates found_a_2 = airlineGatesService.findById(saved2.getId()); + System.err.println("initialized airlines"); + System.err.println(" found before transferGates: " + found_a_1); + System.err.println(" found before transferGates: " + found_a_2); + // move 50 gates from airline1 to airline2 + int gatesToTransfer = 50; + System.err.println("==============================================================="); + System.err.println("this transferGates attempt will succeed. transferring " + gatesToTransfer); - airlineGatesService.transferGates(airlineGates1.getId(), airlineGates2.getId(), gatesToTransfer, null); // 3 + airlineGatesService.transferGates(airlineGates1.getId(), airlineGates2.getId(), gatesToTransfer, null); // 3 - AirlineGates found_b_1 = airlineGatesService.findById(airlineGates1.getId()); - AirlineGates found_b_2 = airlineGatesService.findById(airlineGates2.getId()); - System.err.println(" found after transferGates: " + found_b_1); // 4 - System.err.println(" found after transferGates: " + found_b_2); - Assert.isTrue(found_b_1.getGates().equals(found_a_1.getGates() - gatesToTransfer), "should have transferred"); - Assert.isTrue(found_b_2.getGates().equals(found_a_1.getGates() + gatesToTransfer), "should have transferred"); - System.err.println("==============================================================="); - gatesToTransfer = 44; - System.err.println("this transferGates attempt will fail. transferring " + gatesToTransfer); - // attempt to move 44 gates from airline1 to airline2, but it fails. - try { + AirlineGates found_b_1 = airlineGatesService.findById(airlineGates1.getId()); + AirlineGates found_b_2 = airlineGatesService.findById(airlineGates2.getId()); + System.err.println(" found after transferGates: " + found_b_1); // 4 + System.err.println(" found after transferGates: " + found_b_2); + Assert.isTrue(found_b_1.getGates().equals(found_a_1.getGates() - gatesToTransfer), "should have transferred"); + Assert.isTrue(found_b_2.getGates().equals(found_a_1.getGates() + gatesToTransfer), "should have transferred"); + System.err.println("==============================================================="); + gatesToTransfer = 44; + System.err.println("this transferGates attempt will fail. transferring " + gatesToTransfer); + // attempt to move 44 gates from airline1 to airline2, but it fails. + try { - airlineGatesService.transferGates(airlineGates1.getId(), airlineGates2.getId(), 44, new SimulateErrorException()); + airlineGatesService.transferGates(airlineGates1.getId(), airlineGates2.getId(), 44, new SimulateErrorException()); - } catch (RuntimeException rte) { - if (!(rte instanceof TransactionSystemUnambiguousException) && rte != null - && rte.getCause() instanceof SimulateErrorException) { - throw rte; - } - System.err.println(" got exception " + rte); - } - AirlineGates found_c_1 = airlineGatesService.findById(airlineGates1.getId()); - AirlineGates found_c_2 = airlineGatesService.findById(airlineGates2.getId()); - System.err.println(" found after transferGates: " + found_c_1); - System.err.println(" found after transferGates: " + found_c_2); - Assert.isTrue(found_c_1.getGates().equals(found_b_1.getGates()), "should be same as previous"); - Assert.isTrue(found_c_2.getGates().equals(found_b_2.getGates()), "should be same as previous"); - System.err.println("==============================================================="); - gatesToTransfer = 44; - System.err.println("this transferGates attempt will succeed. transferring " + gatesToTransfer); - try { + } catch (RuntimeException rte) { + if (!(rte instanceof TransactionSystemUnambiguousException) && rte != null + && rte.getCause() instanceof SimulateErrorException) { + throw rte; + } + System.err.println(" got exception " + rte); + } + AirlineGates found_c_1 = airlineGatesService.findById(airlineGates1.getId()); + AirlineGates found_c_2 = airlineGatesService.findById(airlineGates2.getId()); + System.err.println(" found after transferGates: " + found_c_1); + System.err.println(" found after transferGates: " + found_c_2); + Assert.isTrue(found_c_1.getGates().equals(found_b_1.getGates()), "should be same as previous"); + Assert.isTrue(found_c_2.getGates().equals(found_b_2.getGates()), "should be same as previous"); + System.err.println("==============================================================="); + gatesToTransfer = 44; + System.err.println("this transferGates attempt will succeed. transferring " + gatesToTransfer); + try { - airlineGatesService.transferGatesReactive(airlineGates1.getId(), airlineGates2.getId(), gatesToTransfer, null) - .block(); + airlineGatesService.transferGatesReactive(airlineGates1.getId(), airlineGates2.getId(), gatesToTransfer, null) + .block(); - } catch (RuntimeException rte) { - if (!(rte instanceof TransactionSystemUnambiguousException) && rte != null - && rte.getCause() instanceof SimulateErrorException) { - throw rte; - } - System.err.println(" got exception " + rte); - } - AirlineGates found_d_1 = airlineGatesService.findById(airlineGates1.getId()); - AirlineGates found_d_2 = airlineGatesService.findById(airlineGates2.getId()); - System.err.println(" found after transferGates: " + found_d_1); - System.err.println(" found after transferGates: " + found_d_2); - Assert.isTrue(found_d_1.getGates().equals(found_c_1.getGates() - gatesToTransfer), "should have transferred"); - Assert.isTrue(found_d_2.getGates().equals(found_c_2.getGates() + gatesToTransfer), "should have transferred"); - System.err.println("==============================================================="); - } + } catch (RuntimeException rte) { + if (!(rte instanceof TransactionSystemUnambiguousException) && rte != null + && rte.getCause() instanceof SimulateErrorException) { + throw rte; + } + System.err.println(" got exception " + rte); + } + AirlineGates found_d_1 = airlineGatesService.findById(airlineGates1.getId()); + AirlineGates found_d_2 = airlineGatesService.findById(airlineGates2.getId()); + System.err.println(" found after transferGates: " + found_d_1); + System.err.println(" found after transferGates: " + found_d_2); + Assert.isTrue(found_d_1.getGates().equals(found_c_1.getGates() - gatesToTransfer), "should have transferred"); + Assert.isTrue(found_d_2.getGates().equals(found_c_2.getGates() + gatesToTransfer), "should have transferred"); + System.err.println("==============================================================="); + } - static class SimulateErrorException extends RuntimeException {} + static class SimulateErrorException extends RuntimeException { + } } diff --git a/couchbase/transactions/src/main/java/com/example/demo/Config.java b/couchbase/transactions/src/main/java/com/example/demo/Config.java index 790e45fb..bcce2bca 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/Config.java +++ b/couchbase/transactions/src/main/java/com/example/demo/Config.java @@ -15,47 +15,45 @@ */ package com.example.demo; -import com.couchbase.client.core.msg.kv.DurabilityLevel; -import com.couchbase.client.java.env.ClusterEnvironment; -import com.couchbase.client.java.transactions.config.TransactionsConfig; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.context.annotation.Configuration; import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; +import com.couchbase.client.core.msg.kv.DurabilityLevel; +import com.couchbase.client.java.env.ClusterEnvironment; +import com.couchbase.client.java.transactions.config.TransactionsConfig; + /** * @author Michael Reiche */ @Configuration -@EnableCouchbaseRepositories({"com.example.demo"}) +@EnableCouchbaseRepositories({ "com.example.demo" }) @EnableTransactionManagement public class Config extends AbstractCouchbaseConfiguration { - @Override - public String getConnectionString() { - return "127.0.0.1"; - } + @Override + public String getConnectionString() { + return "127.0.0.1"; + } - @Override - public String getUserName() { - return "Administrator"; - } + @Override + public String getUserName() { + return "Administrator"; + } - @Override - public String getPassword() { - return "password"; - } + @Override + public String getPassword() { + return "password"; + } - @Override - public String getBucketName() { - return "travel-sample"; - } - - @Override - public void configureEnvironment(ClusterEnvironment.Builder builder){ - builder.transactionsConfig(TransactionsConfig.durabilityLevel(DurabilityLevel.NONE)); - } + @Override + public String getBucketName() { + return "travel-sample"; + } + @Override + public void configureEnvironment(ClusterEnvironment.Builder builder) { + builder.transactionsConfig(TransactionsConfig.durabilityLevel(DurabilityLevel.NONE)); + } } diff --git a/couchbase/transactions/src/main/java/com/example/demo/DemoApplication.java b/couchbase/transactions/src/main/java/com/example/demo/DemoApplication.java index 5c401333..3b94f4bf 100644 --- a/couchbase/transactions/src/main/java/com/example/demo/DemoApplication.java +++ b/couchbase/transactions/src/main/java/com/example/demo/DemoApplication.java @@ -17,17 +17,28 @@ package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import java.util.Properties; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.type.AnnotatedTypeMetadata; + +import example.springdata.couchbase.util.CouchbaseAvailableRule; /** * @author Michael Reiche */ @SpringBootApplication +@Conditional(DemoApplication.CouchbaseAvailable.class) public class DemoApplication { - public static void main(String[] args) { - SpringApplication.run( DemoApplication.class, args ); - } + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + static class CouchbaseAvailable implements Condition { + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return CouchbaseAvailableRule.onLocalhost().isAvailable(); + } + } } diff --git a/couchbase/transactions/src/main/resources/application.properties b/couchbase/transactions/src/main/resources/application.properties deleted file mode 100644 index e439ebd8..00000000 --- a/couchbase/transactions/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.allow-bean-definition-overriding=true diff --git a/couchbase/transactions/src/test/java/com/example/demo/DemoApplicationTests.java b/couchbase/transactions/src/test/java/com/example/demo/DemoApplicationTests.java index f9669e36..4b7492e9 100644 --- a/couchbase/transactions/src/test/java/com/example/demo/DemoApplicationTests.java +++ b/couchbase/transactions/src/test/java/com/example/demo/DemoApplicationTests.java @@ -15,19 +15,26 @@ */ package com.example.demo; -import example.springdata.couchbase.util.EnabledIfCouchbaseAvailable; +import org.junit.ClassRule; import org.junit.jupiter.api.Test; + import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import example.springdata.couchbase.util.CouchbaseAvailableRule; /** * @author Michael Reiche * @author Christoph Strobl */ -@EnabledIfCouchbaseAvailable @SpringBootTest +@ContextConfiguration(classes = DemoApplication.class) class DemoApplicationTests { - @Test - void contextLoads() { - } + @ClassRule // + public static CouchbaseAvailableRule COUCHBASE = CouchbaseAvailableRule.onLocalhost(); + + @Test + void contextLoads() { + } } diff --git a/couchbase/util/src/main/java/example/springdata/couchbase/util/CouchbaseAvailableRule.java b/couchbase/util/src/main/java/example/springdata/couchbase/util/CouchbaseAvailableRule.java index f15af00c..d668a0f2 100644 --- a/couchbase/util/src/main/java/example/springdata/couchbase/util/CouchbaseAvailableRule.java +++ b/couchbase/util/src/main/java/example/springdata/couchbase/util/CouchbaseAvailableRule.java @@ -19,13 +19,14 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.time.Duration; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiConsumer; import javax.net.SocketFactory; import org.junit.AssumptionViolatedException; import org.junit.rules.ExternalResource; - /** * Rule to check Couchbase server availability. If Couchbase is not running, tests are skipped. * @@ -33,35 +34,49 @@ import org.junit.rules.ExternalResource; */ public class CouchbaseAvailableRule extends ExternalResource { - private final String host; - private final int port; - private final Duration timeout = Duration.ofSeconds(1); + private final String host; + private final int port; + private final Duration timeout = Duration.ofSeconds(1); - private CouchbaseAvailableRule(String host, int port) { - this.host = host; - this.port = port; - } + private CouchbaseAvailableRule(String host, int port) { + this.host = host; + this.port = port; + } - /** - * Create a new rule requiring Couchbase running on {@code localhost} on {@code 8091}. - * - * @return the test rule. - */ - public static CouchbaseAvailableRule onLocalhost() { - return new CouchbaseAvailableRule("localhost", 8091); - } + /** + * Create a new rule requiring Couchbase running on {@code localhost} on {@code 8091}. + * + * @return the test rule. + */ + public static CouchbaseAvailableRule onLocalhost() { + return new CouchbaseAvailableRule("localhost", 8091); + } - @Override - protected void before() throws Throwable { + @Override + protected void before() throws Throwable { - Socket socket = SocketFactory.getDefault().createSocket(); - try { - socket.connect(new InetSocketAddress(host, port), Math.toIntExact(timeout.toMillis())); - } catch (IOException e) { - throw new AssumptionViolatedException( - String.format("Couchbase not available on on %s:%d. Skipping tests.", host, port), e); - } finally { - socket.close(); - } - } + check((b, throwable) -> { + if (throwable != null) { + throw new AssumptionViolatedException( + String.format("Couchbase not available on on %s:%d. Skipping tests.", host, port), throwable); + } + }); + } + + public boolean isAvailable() { + + AtomicBoolean b = new AtomicBoolean(); + check((avail, t) -> b.set(avail)); + return b.get(); + } + + private void check(BiConsumer c) { + + try (Socket socket = SocketFactory.getDefault().createSocket()) { + socket.connect(new InetSocketAddress(host, port), Math.toIntExact(timeout.toMillis())); + c.accept(true, null); + } catch (IOException e) { + c.accept(false, e); + } + } }