Add Couchbase Transactions Example.
Closes #650. Original pull request: #663
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
<modules>
|
||||
<module>example</module>
|
||||
<module>reactive</module>
|
||||
<module>transactions</module>
|
||||
<module>util</module>
|
||||
</modules>
|
||||
|
||||
|
||||
17
couchbase/transactions/README.md
Normal file
17
couchbase/transactions/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Getting Started
|
||||
|
||||
### Running the Sample
|
||||
|
||||
* `$> docker run -d --name db -p 8091-8097:8091-8097 -p 11210:11210 -p 11207:11207 -p 18091-18095:18091-18095 -p 18096:18096 -p 18097:18097 couchbase`
|
||||
* Create new _cluster_ via `http://localhost:8091/`
|
||||
* Create new [bucket](http://localhost:8091/ui/index.html#/buckets) named _travel-sample_.
|
||||
*
|
||||
|
||||
### Reference Documentation
|
||||
For further reference, please consider the following sections:
|
||||
|
||||
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
|
||||
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.2/maven-plugin/reference/html/)
|
||||
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.2/maven-plugin/reference/html/#build-image)
|
||||
* [Spring Data Couchbase](https://docs.spring.io/spring-boot/docs/2.5.2/reference/htmlsingle/#boot-features-couchbase)
|
||||
|
||||
80
couchbase/transactions/pom.xml
Normal file
80
couchbase/transactions/pom.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-couchbase-transactions</artifactId>
|
||||
<name>Spring Data Couchbase - Transaction example</name>
|
||||
<description>Transactions Demo project for Spring Data Couchbase</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-couchbase-examples</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-couchbase</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-data-couchbase-example-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-couchbase-example-utils</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype-snapshot</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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
|
||||
*
|
||||
* https://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 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;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Document
|
||||
public class AirlineGates {
|
||||
@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 String getId() {
|
||||
return id;
|
||||
}
|
||||
public Long getGates() {
|
||||
return gates;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2017-2022 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
|
||||
*
|
||||
* https://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 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<AirlineGates, String>, DynamicProxyable<AirlineGatesRepository> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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 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;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Service
|
||||
public class AirlineGatesService {
|
||||
CouchbaseTemplate template;
|
||||
ReactiveCouchbaseTemplate reactiveTemplate;
|
||||
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 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<Void> 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 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 findByIdRepo(String id) {
|
||||
return airlineGatesRepository.findById(id).orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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 com.example.demo;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.transaction.error.TransactionSystemUnambiguousException;
|
||||
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.
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Component
|
||||
public class CmdRunner implements CommandLineRunner {
|
||||
|
||||
@Autowired CouchbaseTemplate template;
|
||||
@Autowired AirlineGatesService airlineGatesService;
|
||||
|
||||
//@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) {}
|
||||
|
||||
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
|
||||
|
||||
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());
|
||||
|
||||
} 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();
|
||||
|
||||
} 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 {}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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 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;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCouchbaseRepositories({"com.example.demo"})
|
||||
@EnableTransactionManagement
|
||||
public class Config extends AbstractCouchbaseConfiguration {
|
||||
@Override
|
||||
public String getConnectionString() {
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserName() {
|
||||
return "Administrator";
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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 com.example.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run( DemoApplication.class, args );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
30
couchbase/transactions/src/main/resources/logback.xml
Normal file
30
couchbase/transactions/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--
|
||||
<logger name="org.springframework.data" level="debug" />
|
||||
-->
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
|
||||
<!-- You can use these logger configurations to log more details:
|
||||
- log the Couchbase queries produced by the framework
|
||||
- log details of geo queries and false positive elimination
|
||||
- log details of the detection of placeholders in N1QL inline queries
|
||||
- log additional debug info during automatic index creation
|
||||
-->
|
||||
|
||||
<logger name="org.springframework.data.couchbase.core" level="info"/>"
|
||||
<logger name="org.springframework.data.couchbase.repository.query" level="info"/>
|
||||
<logger name="com.couchbase.transactions" level="info"/>"
|
||||
<logger name="org.springframework.data.couchbase.transaction" level="info"/>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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 com.example.demo;
|
||||
|
||||
import example.springdata.couchbase.util.EnabledIfCouchbaseAvailable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@EnabledIfCouchbaseAvailable
|
||||
@SpringBootTest
|
||||
class DemoApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user