Skip to content

Commit 895f988

Browse files
committed
Rebased and tidied transaction branch.
Documentation to follow. Closes #1145.
1 parent e20ed08 commit 895f988

File tree

126 files changed

+1473
-1477
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+1473
-1477
lines changed

.mvn/wrapper/maven-wrapper.jar

47.2 KB
Binary file not shown.

Jenkinsfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pipeline {
6767
steps {
6868
script {
6969
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
70-
docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.basic']) {
70+
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
7171
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase-non-root ' +
7272
'-Dartifactory.server=https://repo.spring.io ' +
7373
"-Dartifactory.username=${ARTIFACTORY_USR} " +

pom.xml

-13
Original file line numberDiff line numberDiff line change
@@ -233,17 +233,6 @@
233233
<version>4.0.3</version>
234234
<scope>test</scope>
235235
</dependency>
236-
<dependency>
237-
<groupId>org.testcontainers</groupId>
238-
<artifactId>testcontainers</artifactId>
239-
</dependency>
240-
241-
<dependency>
242-
<groupId>ch.qos.logback</groupId>
243-
<artifactId>logback-classic</artifactId>
244-
<version>1.2.5</version>
245-
<scope>compile</scope>
246-
</dependency>
247236

248237
</dependencies>
249238

@@ -262,12 +251,10 @@
262251
<enabled>false</enabled>
263252
</releases>
264253
</repository>
265-
<!--
266254
<repository>
267255
<id>jitpack.io</id>
268256
<url>https://jitpack.io</url>
269257
</repository>
270-
-->
271258
</repositories>
272259

273260
<pluginRepositories>

src/main/asciidoc/caching.adoc

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ To make it work, you need to add the `@EnableCaching` annotation and configure t
2222
public class Config extends AbstractCouchbaseConfiguration {
2323
// general methods
2424
25-
@Bean
26-
public CouchbaseCacheManager cacheManager(CouchbaseTemplate couchbaseTemplate) throws Exception {
27-
CouchbaseCacheManager.CouchbaseCacheManagerBuilder builder = CouchbaseCacheManager.CouchbaseCacheManagerBuilder
28-
.fromConnectionFactory(couchbaseTemplate.getCouchbaseClientFactory());
29-
return builder.build();
30-
}
31-
25+
@Bean
26+
public CouchbaseCacheManager cacheManager(CouchbaseTemplate couchbaseTemplate) throws Exception {
27+
CouchbaseCacheManager.CouchbaseCacheManagerBuilder builder = CouchbaseCacheManager.CouchbaseCacheManagerBuilder
28+
.fromConnectionFactory(couchbaseTemplate.getCouchbaseClientFactory());
29+
builder.withCacheConfiguration("mySpringCache", CouchbaseCacheConfiguration.defaultCacheConfig());
30+
return builder.build();
31+
}
3232
----
3333
====
3434

src/main/java/com/couchbase/client/java/transactions/AttemptContextReactiveAccessor.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
/*
3-
* Copyright 2021 the original author or authors
3+
* Copyright 2021-2022 the original author or authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
1616
*/
1717
package com.couchbase.client.java.transactions;
1818

19-
import java.lang.reflect.Field;
20-
2119
import com.couchbase.client.core.annotation.Stability;
2220
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
2321
import com.couchbase.client.java.codec.JsonSerializer;

src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
import java.io.Closeable;
2020

21-
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
22-
import com.couchbase.client.java.transactions.ReactiveTransactionAttemptContext;
23-
import com.couchbase.client.java.transactions.config.TransactionOptions;
2421
import org.springframework.dao.support.PersistenceExceptionTranslator;
2522

2623
import com.couchbase.client.java.Bucket;
@@ -75,4 +72,5 @@ public interface CouchbaseClientFactory extends Closeable {
7572
* The exception translator used on the factory.
7673
*/
7774
PersistenceExceptionTranslator getExceptionTranslator();
75+
7876
}

src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java

+5-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,12 +15,8 @@
1515
*/
1616
package org.springframework.data.couchbase;
1717

18-
import java.time.Duration;
19-
import java.time.temporal.ChronoUnit;
2018
import java.util.function.Supplier;
2119

22-
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
23-
import com.couchbase.client.java.transactions.config.TransactionOptions;
2420
import org.springframework.dao.support.PersistenceExceptionTranslator;
2521
import org.springframework.data.couchbase.core.CouchbaseExceptionTranslator;
2622

@@ -32,11 +28,7 @@
3228
import com.couchbase.client.java.ClusterOptions;
3329
import com.couchbase.client.java.Collection;
3430
import com.couchbase.client.java.Scope;
35-
import com.couchbase.client.java.codec.JsonSerializer;
3631
import com.couchbase.client.java.env.ClusterEnvironment;
37-
import com.couchbase.client.java.transactions.AttemptContextReactiveAccessor;
38-
import com.couchbase.client.java.transactions.config.TransactionsCleanupConfig;
39-
import com.couchbase.client.java.transactions.config.TransactionsConfig;
4032

4133
/**
4234
* The default implementation of a {@link CouchbaseClientFactory}.
@@ -52,18 +44,18 @@ public class SimpleCouchbaseClientFactory implements CouchbaseClientFactory {
5244
private final PersistenceExceptionTranslator exceptionTranslator;
5345

5446
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
55-
final String bucketName) {
47+
final String bucketName) {
5648
this(connectionString, authenticator, bucketName, null);
5749
}
5850

5951
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
60-
final String bucketName, final String scopeName) {
52+
final String bucketName, final String scopeName) {
6153
this(new OwnedSupplier<>(Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator))),
6254
bucketName, scopeName);
6355
}
6456

6557
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
66-
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
58+
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
6759
this(
6860
new OwnedSupplier<>(
6961
Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator).environment(environment))),
@@ -75,7 +67,7 @@ public SimpleCouchbaseClientFactory(final Cluster cluster, final String bucketNa
7567
}
7668

7769
private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final String bucketName,
78-
final String scopeName) {
70+
final String scopeName) {
7971
this.cluster = cluster;
8072
this.bucket = cluster.get().bucket(bucketName);
8173
this.scope = scopeName == null ? bucket.defaultScope() : bucket.scope(scopeName);
@@ -131,8 +123,4 @@ public void close() {
131123
}
132124
}
133125

134-
private static Duration now() {
135-
return Duration.of(System.nanoTime(), ChronoUnit.NANOS);
136-
}
137-
138126
}

src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java

+15-26
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@
1717
package org.springframework.data.couchbase.config;
1818

1919
import static com.couchbase.client.java.ClusterOptions.clusterOptions;
20-
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_MAPPING_CONTEXT;
2120

2221
import java.util.Collections;
2322
import java.util.HashSet;
2423
import java.util.Set;
2524

26-
import com.couchbase.client.java.query.QueryScanConsistency;
2725
import org.springframework.beans.factory.config.BeanDefinition;
2826
import org.springframework.context.annotation.Bean;
2927
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
@@ -67,6 +65,7 @@
6765
import com.couchbase.client.java.env.ClusterEnvironment;
6866
import com.couchbase.client.java.json.JacksonTransformers;
6967
import com.couchbase.client.java.json.JsonValueModule;
68+
import com.couchbase.client.java.query.QueryScanConsistency;
7069
import com.fasterxml.jackson.databind.ObjectMapper;
7170

7271
/**
@@ -136,17 +135,11 @@ protected Authenticator authenticator() {
136135
public CouchbaseClientFactory couchbaseClientFactory(final Cluster couchbaseCluster) {
137136
return new SimpleCouchbaseClientFactory(couchbaseCluster, getBucketName(), getScopeName());
138137
}
139-
/*
140-
@Bean
141-
public ReactiveCouchbaseClientFactory reactiveCouchbaseClientFactory(final Cluster couchbaseCluster) {
142-
return new SimpleReactiveCouchbaseClientFactory(couchbaseCluster, getBucketName(), getScopeName());
143-
}
144-
*/
138+
145139
@Bean(destroyMethod = "disconnect")
146140
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment) {
147-
Cluster c = Cluster.connect(getConnectionString(),
141+
return Cluster.connect(getConnectionString(),
148142
clusterOptions(authenticator()).environment(couchbaseClusterEnvironment));
149-
return c;
150143
}
151144

152145
@Bean(destroyMethod = "shutdown")
@@ -171,29 +164,24 @@ protected void configureEnvironment(final ClusterEnvironment.Builder builder) {
171164

172165
@Bean(name = BeanNames.COUCHBASE_TEMPLATE)
173166
public CouchbaseTemplate couchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
174-
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
175-
return new CouchbaseTemplate(couchbaseClientFactory,
176-
mappingCouchbaseConverter,
177-
couchbaseTranslationService, getDefaultConsistency());
167+
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
168+
return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, couchbaseTranslationService,
169+
getDefaultConsistency());
178170
}
179171

180172
public CouchbaseTemplate couchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
181-
MappingCouchbaseConverter mappingCouchbaseConverter) {
182-
return couchbaseTemplate(couchbaseClientFactory,
183-
mappingCouchbaseConverter,
184-
new JacksonTranslationService());
173+
MappingCouchbaseConverter mappingCouchbaseConverter) {
174+
return couchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, new JacksonTranslationService());
185175
}
186176

187177
@Bean(name = BeanNames.REACTIVE_COUCHBASE_TEMPLATE)
188-
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(
189-
CouchbaseClientFactory couchbaseClientFactory,
178+
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
190179
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
191-
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter,
192-
couchbaseTranslationService, getDefaultConsistency());
180+
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, couchbaseTranslationService,
181+
getDefaultConsistency());
193182
}
194183

195-
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(
196-
CouchbaseClientFactory couchbaseClientFactory,
184+
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
197185
MappingCouchbaseConverter mappingCouchbaseConverter) {
198186
return reactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter,
199187
new JacksonTranslationService());
@@ -301,7 +289,7 @@ public TranslationService couchbaseTranslationService() {
301289
/**
302290
* Creates a {@link CouchbaseMappingContext} equipped with entity classes scanned from the mapping base package.
303291
*/
304-
@Bean(COUCHBASE_MAPPING_CONTEXT)
292+
@Bean(BeanNames.COUCHBASE_MAPPING_CONTEXT)
305293
public CouchbaseMappingContext couchbaseMappingContext(CustomConversions customConversions) throws Exception {
306294
CouchbaseMappingContext mappingContext = new CouchbaseMappingContext();
307295
mappingContext.setInitialEntitySet(getInitialEntitySet());
@@ -358,7 +346,8 @@ public CouchbaseTransactionalOperator transactionalOperator(
358346
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
359347
public TransactionInterceptor transactionInterceptor(TransactionManager couchbaseTransactionManager) {
360348
TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
361-
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager, transactionAttributeSource);
349+
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager,
350+
transactionAttributeSource);
362351
interceptor.setTransactionAttributeSource(transactionAttributeSource);
363352
if (couchbaseTransactionManager != null) {
364353
interceptor.setTransactionManager(couchbaseTransactionManager);

src/main/java/org/springframework/data/couchbase/config/BeanNames.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,5 +64,5 @@ public class BeanNames {
6464

6565
public static final String COUCHBASE_TRANSACTION_MANAGER = "couchbaseTransactionManager";
6666

67-
public static final String COUCHBASE_TRANSACTIONAL_OPERATOR = "couchbaseTransactionalOperator" ;
67+
public static final String COUCHBASE_TRANSACTIONAL_OPERATOR = "couchbaseTransactionalOperator";
6868
}

src/main/java/org/springframework/data/couchbase/core/AbstractTemplateSupport.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021 the original author or authors
2+
* Copyright 2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,12 @@
4141

4242
import com.couchbase.client.core.error.CouchbaseException;
4343

44+
45+
/**
46+
* Base shared by Reactive and non-Reactive TemplateSupport
47+
*
48+
* @author Michael Reiche
49+
*/
4450
public abstract class AbstractTemplateSupport {
4551

4652
final ReactiveCouchbaseTemplate template;

src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java

+26-6
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,39 @@
1919
import java.util.ConcurrentModificationException;
2020
import java.util.concurrent.TimeoutException;
2121

22-
import com.couchbase.client.core.error.transaction.TransactionOperationFailedException;
2322
import org.springframework.dao.DataAccessException;
2423
import org.springframework.dao.DataAccessResourceFailureException;
2524
import org.springframework.dao.DataIntegrityViolationException;
2625
import org.springframework.dao.DataRetrievalFailureException;
2726
import org.springframework.dao.DuplicateKeyException;
2827
import org.springframework.dao.InvalidDataAccessResourceUsageException;
29-
import org.springframework.dao.OptimisticLockingFailureException;;
28+
import org.springframework.dao.OptimisticLockingFailureException;
3029
import org.springframework.dao.QueryTimeoutException;
3130
import org.springframework.dao.TransientDataAccessResourceException;
3231
import org.springframework.dao.support.PersistenceExceptionTranslator;
33-
34-
import com.couchbase.client.core.error.*;
3532
import org.springframework.data.couchbase.transaction.error.UncategorizedTransactionDataAccessException;
3633

34+
import com.couchbase.client.core.error.BucketNotFoundException;
35+
import com.couchbase.client.core.error.CasMismatchException;
36+
import com.couchbase.client.core.error.CollectionNotFoundException;
37+
import com.couchbase.client.core.error.ConfigException;
38+
import com.couchbase.client.core.error.DecodingFailureException;
39+
import com.couchbase.client.core.error.DesignDocumentNotFoundException;
40+
import com.couchbase.client.core.error.DocumentExistsException;
41+
import com.couchbase.client.core.error.DocumentLockedException;
42+
import com.couchbase.client.core.error.DocumentNotFoundException;
43+
import com.couchbase.client.core.error.DurabilityAmbiguousException;
44+
import com.couchbase.client.core.error.DurabilityImpossibleException;
45+
import com.couchbase.client.core.error.DurabilityLevelNotAvailableException;
46+
import com.couchbase.client.core.error.EncodingFailureException;
47+
import com.couchbase.client.core.error.ReplicaNotConfiguredException;
48+
import com.couchbase.client.core.error.RequestCanceledException;
49+
import com.couchbase.client.core.error.ScopeNotFoundException;
50+
import com.couchbase.client.core.error.ServiceNotAvailableException;
51+
import com.couchbase.client.core.error.TemporaryFailureException;
52+
import com.couchbase.client.core.error.ValueTooLargeException;
53+
import com.couchbase.client.core.error.transaction.TransactionOperationFailedException;
54+
3755
/**
3856
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
3957
* <p>
@@ -43,6 +61,8 @@
4361
*
4462
* @author Michael Nitschinger
4563
* @author Simon Baslé
64+
* @author Michael Reiche
65+
* @author Graham Pople
4666
*/
4767
public class CouchbaseExceptionTranslator implements PersistenceExceptionTranslator {
4868

@@ -73,7 +93,7 @@ public final DataAccessException translateExceptionIfPossible(final RuntimeExcep
7393
return new OptimisticLockingFailureException(ex.getMessage(), ex);
7494
}
7595

76-
if ( ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
96+
if (ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
7797
|| ex instanceof DurabilityImpossibleException || ex instanceof DurabilityAmbiguousException) {
7898
return new DataIntegrityViolationException(ex.getMessage(), ex);
7999
}
@@ -102,7 +122,7 @@ public final DataAccessException translateExceptionIfPossible(final RuntimeExcep
102122

103123
if (ex instanceof TransactionOperationFailedException) {
104124
// Replace the TransactionOperationFailedException, since we want the Spring operation to fail with a
105-
// Spring error. Internal state has already been set in the AttemptContext so the retry, rollback etc.
125+
// Spring error. Internal state has already been set in the AttemptContext so the retry, rollback etc.
106126
// will get respected regardless of what gets propagated (or not) from the lambda.
107127
return new UncategorizedTransactionDataAccessException((TransactionOperationFailedException) ex);
108128
}

0 commit comments

Comments
 (0)