Skip to content

Commit 80eb56e

Browse files
authored
Non-reactive template.save() use non-reactive auditor and close clusters in tests. (#1765)
Closed #1756, #1764.
1 parent 6e1f43d commit 80eb56e

File tree

53 files changed

+528
-683
lines changed

Some content is hidden

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

53 files changed

+528
-683
lines changed

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

+46-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434

3535
import com.couchbase.client.java.Collection;
3636
import com.couchbase.client.java.query.QueryScanConsistency;
37+
import org.springframework.util.Assert;
38+
import org.springframework.util.ReflectionUtils;
39+
import reactor.core.publisher.Mono;
3740

3841
/**
3942
* Implements lower-level couchbase operations on top of the SDK with entity mapping capabilities.
@@ -83,8 +86,49 @@ public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final Couch
8386

8487
@Override
8588
public <T> T save(T entity, String... scopeAndCollection) {
86-
return reactive().save(entity, scopeAndCollection).block();
87-
}
89+
Assert.notNull(entity, "Entity must not be null!");
90+
91+
String scope = scopeAndCollection.length > 0 ? scopeAndCollection[0] : null;
92+
String collection = scopeAndCollection.length > 1 ? scopeAndCollection[1] : null;
93+
final CouchbasePersistentEntity<?> mapperEntity = getConverter().getMappingContext()
94+
.getPersistentEntity(entity.getClass());
95+
final CouchbasePersistentProperty versionProperty = mapperEntity.getVersionProperty();
96+
final boolean versionPresent = versionProperty != null;
97+
final Long version = versionProperty == null || versionProperty.getField() == null ? null
98+
: (Long) ReflectionUtils.getField(versionProperty.getField(),
99+
entity);
100+
final boolean existingDocument = version != null && version > 0;
101+
102+
Class clazz = entity.getClass();
103+
104+
if (!versionPresent) { // the entity doesn't have a version property
105+
// No version field - no cas
106+
// If in a transaction, insert is the only thing that will work
107+
return (T)TransactionalSupport.checkForTransactionInThreadLocalStorage()
108+
.map(ctx -> {
109+
if (ctx.isPresent()) {
110+
return (T) insertById(clazz).inScope(scope)
111+
.inCollection(collection)
112+
.one(entity);
113+
} else { // if not in a tx, then upsert will work
114+
return (T) upsertById(clazz).inScope(scope)
115+
.inCollection(collection)
116+
.one(entity);
117+
}
118+
}).block();
119+
120+
} else if (existingDocument) { // there is a version property, and it is non-zero
121+
// Updating existing document with cas
122+
return (T)replaceById(clazz).inScope(scope)
123+
.inCollection(collection)
124+
.one(entity);
125+
} else { // there is a version property, but it's zero or not set.
126+
// Creating new document
127+
return (T)insertById(clazz).inScope(scope)
128+
.inCollection(collection)
129+
.one(entity);
130+
}
131+
}
88132

89133
@Override
90134
public <T> Long count(Query query, Class<T> domainType) {

src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheCollectionIntegrationTests.java

+9
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,30 @@
2424

2525
import org.junit.jupiter.api.BeforeEach;
2626
import org.junit.jupiter.api.Test;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.data.couchbase.core.CouchbaseTemplate;
2729
import org.springframework.data.couchbase.util.Capabilities;
2830
import org.springframework.data.couchbase.util.ClusterType;
2931
import org.springframework.data.couchbase.util.CollectionAwareIntegrationTests;
3032
import org.springframework.data.couchbase.util.IgnoreWhen;
33+
import org.springframework.test.annotation.DirtiesContext;
34+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
35+
import org.springframework.data.couchbase.domain.Config;
3136

3237
/**
3338
* CouchbaseCache tests Theses tests rely on a cb server running.
3439
*
3540
* @author Michael Reiche
3641
*/
3742
@IgnoreWhen(clusterTypes = ClusterType.MOCKED, missesCapabilities = { Capabilities.COLLECTIONS })
43+
@SpringJUnitConfig(Config.class)
44+
@DirtiesContext
3845
class CouchbaseCacheCollectionIntegrationTests extends CollectionAwareIntegrationTests {
3946

4047
volatile CouchbaseCache cache;
4148

49+
@Autowired CouchbaseTemplate couchbaseTemplate;
50+
4251
@BeforeEach
4352
@Override
4453
public void beforeEach() {

src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheIntegrationTests.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
import org.junit.jupiter.api.BeforeEach;
2727
import org.junit.jupiter.api.Test;
2828
import org.springframework.beans.factory.annotation.Autowired;
29-
import org.springframework.context.ApplicationContext;
30-
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
29+
import org.springframework.data.couchbase.core.CouchbaseTemplate;
3130
import org.springframework.data.couchbase.domain.Config;
3231
import org.springframework.data.couchbase.domain.User;
3332
import org.springframework.data.couchbase.domain.UserRepository;
3433
import org.springframework.data.couchbase.util.ClusterType;
3534
import org.springframework.data.couchbase.util.IgnoreWhen;
3635
import org.springframework.data.couchbase.util.JavaIntegrationTests;
36+
import org.springframework.test.annotation.DirtiesContext;
3737
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
3838

3939
/**
@@ -43,11 +43,13 @@
4343
*/
4444
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
4545
@SpringJUnitConfig(Config.class)
46+
@DirtiesContext
4647
class CouchbaseCacheIntegrationTests extends JavaIntegrationTests {
4748

4849
volatile CouchbaseCache cache;
4950
@Autowired CouchbaseCacheManager cacheManager; // autowired not working
5051
@Autowired UserRepository userRepository; // autowired not working
52+
@Autowired CouchbaseTemplate couchbaseTemplate;
5153

5254
@BeforeEach
5355
@Override
@@ -56,9 +58,6 @@ public void beforeEach() {
5658
cache = CouchbaseCacheManager.create(couchbaseTemplate.getCouchbaseClientFactory()).createCouchbaseCache("myCache",
5759
CouchbaseCacheConfiguration.defaultCacheConfig());
5860
cache.clear();
59-
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
60-
cacheManager = ac.getBean(CouchbaseCacheManager.class);
61-
userRepository = ac.getBean(UserRepository.class);
6261
}
6362

6463
@AfterEach
@@ -134,5 +133,4 @@ public void clearWithDelayOk() throws InterruptedException {
134133

135134
@Test
136135
public void noOpt() {}
137-
138136
}

src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.junit.jupiter.api.BeforeEach;
4141
import org.junit.jupiter.api.Test;
4242
import org.springframework.beans.factory.annotation.Autowired;
43+
import org.springframework.context.annotation.Configuration;
4344
import org.springframework.dao.DuplicateKeyException;
4445
import org.springframework.dao.InvalidDataAccessResourceUsageException;
4546
import org.springframework.dao.OptimisticLockingFailureException;
@@ -69,6 +70,7 @@
6970
import org.springframework.data.couchbase.util.ClusterType;
7071
import org.springframework.data.couchbase.util.IgnoreWhen;
7172
import org.springframework.data.couchbase.util.JavaIntegrationTests;
73+
import org.springframework.test.annotation.DirtiesContext;
7274
import org.springframework.test.context.TestPropertySource;
7375
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
7476

@@ -93,6 +95,7 @@
9395
*/
9496
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
9597
@SpringJUnitConfig(Config.class)
98+
@DirtiesContext
9699
@TestPropertySource(properties = { "valid.document.durability = MAJORITY" })
97100
class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
98101

@@ -102,6 +105,7 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
102105
@BeforeEach
103106
@Override
104107
public void beforeEach() {
108+
super.beforeEach();
105109
couchbaseTemplate.removeByQuery(User.class).all();
106110
couchbaseTemplate.removeByQuery(UserAnnotated.class).all();
107111
couchbaseTemplate.removeByQuery(UserAnnotated2.class).all();
@@ -1337,11 +1341,9 @@ void sampleScanId() {
13371341

13381342
}
13391343

1340-
13411344
private void sleepSecs(int i) {
13421345
try {
13431346
Thread.sleep(i * 1000);
13441347
} catch (InterruptedException ie) {}
13451348
}
1346-
13471349
}

src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryCollectionIntegrationTests.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
import org.springframework.data.couchbase.core.query.QueryCriteria;
4444
import org.springframework.data.couchbase.domain.Address;
4545
import org.springframework.data.couchbase.domain.Airport;
46-
import org.springframework.data.couchbase.domain.CollectionsConfig;
4746
import org.springframework.data.couchbase.domain.Course;
47+
import org.springframework.data.couchbase.domain.ConfigScoped;
4848
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
4949
import org.springframework.data.couchbase.domain.Submission;
5050
import org.springframework.data.couchbase.domain.User;
@@ -57,6 +57,7 @@
5757
import org.springframework.data.couchbase.util.ClusterType;
5858
import org.springframework.data.couchbase.util.CollectionAwareIntegrationTests;
5959
import org.springframework.data.couchbase.util.IgnoreWhen;
60+
import org.springframework.test.annotation.DirtiesContext;
6061
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
6162

6263
import com.couchbase.client.core.error.AmbiguousTimeoutException;
@@ -80,7 +81,8 @@
8081
* @author Michael Reiche
8182
*/
8283
@IgnoreWhen(missesCapabilities = { Capabilities.QUERY, Capabilities.COLLECTIONS }, clusterTypes = ClusterType.MOCKED)
83-
@SpringJUnitConfig(CollectionsConfig.class)
84+
@SpringJUnitConfig(ConfigScoped.class)
85+
@DirtiesContext
8486
class CouchbaseTemplateQueryCollectionIntegrationTests extends CollectionAwareIntegrationTests {
8587

8688
@Autowired public CouchbaseTemplate couchbaseTemplate;

src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryIntegrationTests.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@
3838
import org.junit.jupiter.api.BeforeEach;
3939
import org.junit.jupiter.api.Test;
4040
import org.springframework.beans.factory.annotation.Autowired;
41+
import org.springframework.context.annotation.Configuration;
4142
import org.springframework.data.couchbase.core.query.Query;
4243
import org.springframework.data.couchbase.core.query.QueryCriteria;
4344
import org.springframework.data.couchbase.domain.Address;
4445
import org.springframework.data.couchbase.domain.Airport;
4546
import org.springframework.data.couchbase.domain.AssessmentDO;
46-
import org.springframework.data.couchbase.domain.Config;
4747
import org.springframework.data.couchbase.domain.Course;
48+
import org.springframework.data.couchbase.domain.Config;
4849
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
4950
import org.springframework.data.couchbase.domain.PersonWithMaps;
5051
import org.springframework.data.couchbase.domain.Submission;
@@ -60,6 +61,7 @@
6061
import org.springframework.data.domain.PageRequest;
6162
import org.springframework.data.domain.Pageable;
6263
import org.springframework.data.domain.Sort;
64+
import org.springframework.test.annotation.DirtiesContext;
6365
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
6466

6567
/**
@@ -72,6 +74,7 @@
7274
*/
7375
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
7476
@SpringJUnitConfig(Config.class)
77+
@DirtiesContext
7578
class CouchbaseTemplateQueryIntegrationTests extends JavaIntegrationTests {
7679

7780
@Autowired public CouchbaseTemplate couchbaseTemplate;

src/test/java/org/springframework/data/couchbase/core/CustomTypeKeyIntegrationTests.java

+3-35
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@
2424

2525
import org.junit.jupiter.api.Test;
2626
import org.springframework.beans.factory.annotation.Autowired;
27-
import org.springframework.context.annotation.Configuration;
2827
import org.springframework.data.couchbase.CouchbaseClientFactory;
2928
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
3029
import org.springframework.data.couchbase.core.convert.DefaultCouchbaseTypeMapper;
3130
import org.springframework.data.couchbase.domain.User;
32-
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
3331
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
3432
import org.springframework.data.couchbase.util.ClusterType;
3533
import org.springframework.data.couchbase.util.IgnoreWhen;
34+
import org.springframework.test.annotation.DirtiesContext;
3635
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
3736

3837
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
@@ -45,6 +44,7 @@
4544
*/
4645
@SpringJUnitConfig(CustomTypeKeyIntegrationTests.Config.class)
4746
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
47+
@DirtiesContext
4848
public class CustomTypeKeyIntegrationTests extends ClusterAwareIntegrationTests {
4949

5050
private static final String CUSTOM_TYPE_KEY = "javaClass";
@@ -70,43 +70,11 @@ void saveSimpleEntityCorrectlyWithDifferentTypeKey() {
7070
operations.removeById(User.class).one(user.getId());
7171
}
7272

73-
@Configuration
74-
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
75-
static class Config extends AbstractCouchbaseConfiguration {
76-
77-
@Override
78-
public String getConnectionString() {
79-
return connectionString();
80-
}
81-
82-
@Override
83-
public String getUserName() {
84-
return config().adminUsername();
85-
}
86-
87-
@Override
88-
public String getPassword() {
89-
return config().adminPassword();
90-
}
91-
92-
@Override
93-
public String getBucketName() {
94-
return bucketName();
95-
}
96-
97-
@Override
98-
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
99-
if (config().isUsingCloud()) {
100-
builder.securityConfig(
101-
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
102-
}
103-
}
104-
73+
static class Config extends org.springframework.data.couchbase.domain.Config {
10574
@Override
10675
public String typeKey() {
10776
return CUSTOM_TYPE_KEY;
10877
}
109-
11078
}
11179

11280
}

src/test/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateConcurrencyTests.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package org.springframework.data.couchbase.core;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
35
import java.util.concurrent.Semaphore;
6+
7+
import org.junit.jupiter.api.Test;
8+
import org.springframework.beans.factory.annotation.Autowired;
49
import org.springframework.data.couchbase.core.support.PseudoArgs;
510
import org.springframework.data.couchbase.domain.Config;
611
import org.springframework.data.couchbase.util.ClusterType;
712
import org.springframework.data.couchbase.util.IgnoreWhen;
8-
9-
import org.junit.jupiter.api.Test;
10-
import static org.junit.jupiter.api.Assertions.assertEquals;
11-
12-
import org.springframework.beans.factory.annotation.Autowired;
13-
13+
import org.springframework.test.annotation.DirtiesContext;
1414
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
1515

1616
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
1717
@SpringJUnitConfig(Config.class)
18+
@DirtiesContext
1819
public class ReactiveCouchbaseTemplateConcurrencyTests {
1920

2021
@Autowired public CouchbaseTemplate couchbaseTemplate;

0 commit comments

Comments
 (0)