Skip to content

Commit

Permalink
reconfigure configuration scan
Browse files Browse the repository at this point in the history
  • Loading branch information
hazem-ncq committed Feb 8, 2023
1 parent 4591582 commit 8a22117
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.vsware.libraries.redisreactive.cache.config;
package com.vsware.libraries.redisreactive.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
Expand All @@ -24,7 +24,7 @@
import java.time.format.DateTimeFormatter;

@Configuration
@ComponentScan(basePackages = "com.vsware.libraries.redisreactive.cache")
@ComponentScan(basePackages = "com.vsware.libraries.redisreactive")
public class RedisReactiveCacheConfig {

@Value("${spring.redis.date_format:dd-MM-yyyy}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ public Mono<Void> lock(String resourceKey, String fencingKey, int ttl, TimeUnit
RBucketReactive<String> bucket = redissonReactiveClient.getBucket(resourceKey, StringCodec.INSTANCE);
return getCache(resourceKey)
.flatMap(cacheResponse -> {
if (cacheResponse.equals(fencingKey)) {
if (!cacheResponse.equals(fencingKey)) {
return Mono.error(ResourceAlreadyLockedError::new);
}
return Mono.empty();
})
.switchIfEmpty(bucket.set(fencingKey, ttl, timeUnit))
.onErrorResume(throwable -> Mono.error(new LockInternalError(throwable.getMessage())))
.onErrorResume(throwable -> {
if (throwable instanceof ResourceAlreadyLockedError)
return Mono.error(throwable);

return Mono.error(new LockInternalError(throwable.getMessage()));
})
.then();
}

Expand All @@ -47,7 +52,14 @@ public Mono<Void> unlock(String resourceKey, String fencingKey) {
return Mono.empty();
}).then();
}


@Override
public Mono<Boolean> isLocked(String resourceKey, String fencingKey) {
return getCache(resourceKey)
.map(cacheResponse -> cacheResponse.equals(fencingKey))
.defaultIfEmpty(false);
}

private Mono<String> getCache(String resourceKey) {
RBucketReactive<String> bucket = redissonReactiveClient.getBucket(resourceKey, StringCodec.INSTANCE);
return bucket.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
public interface LockerPort {
Mono<Void> lock(String resourceKey, String fencingKey, int ttl, TimeUnit timeUnit);
Mono<Void> unlock(String resourceKey, String fencingKey);
Mono<Boolean> isLocked(String resourceKey, String fencingKey);
}
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/spring.factories
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# AutoConfigure library
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com/vsware/libraries/redisreactive/cache/config/RedisReactiveCacheConfig
com/vsware/libraries/redisreactive/config/RedisReactiveCacheConfig
110 changes: 110 additions & 0 deletions src/test/java/com/vsware/libraries/redisreactive/cache/LockerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.vsware.libraries.redisreactive.cache;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.javafaker.Faker;
import com.vsware.libraries.redisreactive.cache.config.RedisTestContainerConfig;
import com.vsware.libraries.redisreactive.lock.erros.ResourceAlreadyLockedError;
import com.vsware.libraries.redisreactive.lock.ports.LockerPort;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.redisson.api.RedissonReactiveClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@SpringBootTest
class LockerTest {

private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
@Autowired
private RedissonReactiveClient redissonReactiveClient;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private Faker faker;
@Autowired
private LockerPort locker;

@AfterAll
static void stopTestContainer() {
RedisTestContainerConfig.redisContainer.stop();
}

private String calculateCacheKey(String key, Object anyArg) {
return key + "_" + Arrays.hashCode(new Object[]{anyArg});
}

@BeforeEach
void verifyRedisIsEmpty() {
StepVerifier.create(redissonReactiveClient.getKeys().count())
.expectNext(0L)
.verifyComplete();
}

@AfterEach
void cleanRedis() {
redissonReactiveClient.getKeys().flushall().subscribe();
}

@Test
void test_lock() {
// given
final String resourceKey = String.format("test-key-%s", Faker.instance().funnyName().name());
final String fencingKey = UUID.randomUUID().toString();

// when
lock(resourceKey, fencingKey).block();

// then
Assertions.assertThat(locker.isLocked(resourceKey, fencingKey).block()).isTrue();
}

@Test
void test_lock_already_locked() {
// given
final String resourceKey = String.format("test-key-%s", Faker.instance().funnyName().name());
final String fencingKey = UUID.randomUUID().toString();
lock(resourceKey, fencingKey).block();

final String otherFencingKey = UUID.randomUUID().toString();
// when
StepVerifier.create(lock(resourceKey, otherFencingKey))
.expectError(ResourceAlreadyLockedError.class)
.verify();

Assertions.assertThat(locker.isLocked(resourceKey, fencingKey).block()).isTrue();
Assertions.assertThat(locker.isLocked(resourceKey, otherFencingKey).block()).isFalse();
}

@Test
void test_unlock() {
// given
final String resourceKey = String.format("test-key-%s", Faker.instance().funnyName().name());
final String fencingKey = UUID.randomUUID().toString();

lock(resourceKey, fencingKey).block();

// when
locker.unlock(resourceKey, fencingKey).block();

// then
Assertions.assertThat(locker.isLocked(resourceKey, fencingKey).block()).isFalse();
}

private Mono<Void> lock(String resourceKey, String fencingKey) {
return locker.lock(resourceKey,
fencingKey,
10,
TimeUnit.SECONDS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,9 @@ private void checkThatRedisContainsACachedObject(String key, TestTable testTable
}

private void checkThatRedisContainsACachedList(String key, List<TestTable> testTables) {
RBucketReactive<List<TestTable>> bucket = redissonReactiveClient.getBucket(key, new TypedJsonJacksonCodec(new TypeReference<List<TestTable>>() {}, objectMapper));

RBucketReactive<List<TestTable>> bucket = redissonReactiveClient.getBucket(key, new TypedJsonJacksonCodec(new TypeReference<List<TestTable>>() {
}, objectMapper));

StepVerifier.create(bucket.get())
.expectNextMatches(cacheResponse -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
@Configuration
@Testcontainers
public class RedisTestContainerConfig {

@Container
public static GenericContainer redisContainer = new GenericContainer(DockerImageName.parse("redis:6.2.6-alpine"))
.withExposedPorts(6379);
Expand All @@ -29,8 +28,8 @@ public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
redisContainer.start();
Config config = new Config();
config.useSingleServer()
.setAddress("redis://"+redisContainer.getHost()+":"+redisContainer.getMappedPort(6379));
.setAddress("redis://" + redisContainer.getHost() + ":" + redisContainer.getMappedPort(6379));

return new RedissonConnectionFactory(Redisson.create(config));
}

Expand Down

0 comments on commit 8a22117

Please sign in to comment.