diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 81b554416..6010218e0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { implementation(project(":module:crypto-demo")) implementation(project(":module:request-demo")) implementation(project(":module:store-demo")) - implementation(project(":module:store-inmemory")) + implementation(project(":module:store-redis")) implementation(project(":service")) implementation(project(":service:module")) implementation(libs.dagger.dagger) @@ -20,7 +20,9 @@ dependencies { implementation(libs.jackson.databind) implementation(libs.jakartaInject.api) implementation(libs.jakartaValidation.api) + implementation(libs.jedis.jedis) // for Dagger implementation(libs.okhttp.okhttp) + implementation(libs.redisEmbedded.redis) // for demo implementation(libs.retrofit.retrofit) testImplementation(project(":testing")) diff --git a/app/src/main/java/org/example/age/app/AvsApp.java b/app/src/main/java/org/example/age/app/AvsApp.java index c253d3bd3..e31fc7c2a 100644 --- a/app/src/main/java/org/example/age/app/AvsApp.java +++ b/app/src/main/java/org/example/age/app/AvsApp.java @@ -14,7 +14,7 @@ import org.example.age.module.crypto.demo.DemoAvsCryptoModule; import org.example.age.module.request.demo.DemoAccountIdModule; import org.example.age.module.store.demo.DemoAvsAccountStoreModule; -import org.example.age.module.store.inmemory.InMemoryPendingStoreModule; +import org.example.age.module.store.redis.RedisPendingStoreModule; import org.example.age.service.AvsServiceModule; import org.example.age.service.module.request.RequestContextProvider; @@ -52,7 +52,7 @@ public void run(AvsAppConfig appConfig, Environment env) { DemoAccountIdModule.class, AvsClientModule.class, DemoAvsAccountStoreModule.class, - InMemoryPendingStoreModule.class, + RedisPendingStoreModule.class, DemoAvsCryptoModule.class, AvsConfigModule.class, EnvModule.class, diff --git a/app/src/main/java/org/example/age/app/SiteApp.java b/app/src/main/java/org/example/age/app/SiteApp.java index ea7863059..addfc033b 100644 --- a/app/src/main/java/org/example/age/app/SiteApp.java +++ b/app/src/main/java/org/example/age/app/SiteApp.java @@ -14,7 +14,7 @@ import org.example.age.module.crypto.demo.DemoSiteCryptoModule; import org.example.age.module.request.demo.DemoAccountIdModule; import org.example.age.module.store.demo.DemoSiteAccountStoreModule; -import org.example.age.module.store.inmemory.InMemoryPendingStoreModule; +import org.example.age.module.store.redis.RedisPendingStoreModule; import org.example.age.service.SiteServiceModule; import org.example.age.service.module.request.RequestContextProvider; @@ -52,7 +52,7 @@ public void run(SiteAppConfig appConfig, Environment env) { DemoAccountIdModule.class, SiteClientModule.class, DemoSiteAccountStoreModule.class, - InMemoryPendingStoreModule.class, + RedisPendingStoreModule.class, DemoSiteCryptoModule.class, SiteConfigModule.class, EnvModule.class, diff --git a/app/src/main/java/org/example/age/app/config/AvsAppConfig.java b/app/src/main/java/org/example/age/app/config/AvsAppConfig.java index 5b74a70d8..15180ee30 100644 --- a/app/src/main/java/org/example/age/app/config/AvsAppConfig.java +++ b/app/src/main/java/org/example/age/app/config/AvsAppConfig.java @@ -7,6 +7,7 @@ import org.example.age.module.client.AvsClientsConfig; import org.example.age.module.crypto.demo.AvsKeysConfig; import org.example.age.module.store.demo.AvsStoresConfig; +import org.example.age.module.store.redis.RedisConfig; import org.example.age.service.AvsServiceConfig; /** Configuration for the application. */ @@ -20,6 +21,10 @@ public final class AvsAppConfig extends Configuration { @NotNull private AvsClientsConfig clients; + @Valid + @NotNull + private RedisConfig redis; + @Valid @NotNull private AvsStoresConfig stores; @@ -48,6 +53,16 @@ public void setClients(AvsClientsConfig clients) { this.clients = clients; } + @JsonProperty + public RedisConfig getRedis() { + return redis; + } + + @JsonProperty + public void setRedis(RedisConfig redis) { + this.redis = redis; + } + @JsonProperty public AvsStoresConfig getStores() { return stores; diff --git a/app/src/main/java/org/example/age/app/config/AvsConfigModule.java b/app/src/main/java/org/example/age/app/config/AvsConfigModule.java index 96ebfe8d7..73f70d230 100644 --- a/app/src/main/java/org/example/age/app/config/AvsConfigModule.java +++ b/app/src/main/java/org/example/age/app/config/AvsConfigModule.java @@ -5,6 +5,7 @@ import org.example.age.module.client.AvsClientsConfig; import org.example.age.module.crypto.demo.AvsKeysConfig; import org.example.age.module.store.demo.AvsStoresConfig; +import org.example.age.module.store.redis.RedisConfig; import org.example.age.service.AvsServiceConfig; /** @@ -12,6 +13,7 @@ * @@ -31,6 +33,11 @@ static AvsClientsConfig provieAvsClientsConfig(AvsAppConfig appConfig) { return appConfig.getClients(); } + @Provides + static RedisConfig provideRedisConfig(AvsAppConfig appConfig) { + return appConfig.getRedis(); + } + @Provides static AvsStoresConfig provideAvsStoresConfig(AvsAppConfig appConfig) { return appConfig.getStores(); diff --git a/app/src/main/java/org/example/age/app/config/SiteAppConfig.java b/app/src/main/java/org/example/age/app/config/SiteAppConfig.java index 10341bbd2..c074d90d2 100644 --- a/app/src/main/java/org/example/age/app/config/SiteAppConfig.java +++ b/app/src/main/java/org/example/age/app/config/SiteAppConfig.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull; import org.example.age.module.client.SiteClientsConfig; import org.example.age.module.crypto.demo.SiteKeysConfig; +import org.example.age.module.store.redis.RedisConfig; import org.example.age.service.SiteServiceConfig; /** Configuration for the application. */ @@ -19,6 +20,10 @@ public final class SiteAppConfig extends Configuration { @NotNull private SiteClientsConfig clients; + @Valid + @NotNull + private RedisConfig redis; + @Valid @NotNull private SiteKeysConfig keys; @@ -43,6 +48,16 @@ public void setClients(SiteClientsConfig clients) { this.clients = clients; } + @JsonProperty + public RedisConfig getRedis() { + return redis; + } + + @JsonProperty + public void setRedis(RedisConfig redis) { + this.redis = redis; + } + @JsonProperty public SiteKeysConfig getKeys() { return keys; diff --git a/app/src/main/java/org/example/age/app/config/SiteConfigModule.java b/app/src/main/java/org/example/age/app/config/SiteConfigModule.java index f469180c0..eaccb54cf 100644 --- a/app/src/main/java/org/example/age/app/config/SiteConfigModule.java +++ b/app/src/main/java/org/example/age/app/config/SiteConfigModule.java @@ -4,6 +4,7 @@ import dagger.Provides; import org.example.age.module.client.SiteClientsConfig; import org.example.age.module.crypto.demo.SiteKeysConfig; +import org.example.age.module.store.redis.RedisConfig; import org.example.age.service.SiteServiceConfig; /** @@ -11,6 +12,7 @@ * *

@@ -29,6 +31,11 @@ static SiteClientsConfig provieSiteClientsConfig(SiteAppConfig appConfig) { return appConfig.getClients(); } + @Provides + static RedisConfig provideRedisConfig(SiteAppConfig appConfig) { + return appConfig.getRedis(); + } + @Provides static SiteKeysConfig provideSiteKeysConfig(SiteAppConfig appConfig) { return appConfig.getKeys(); diff --git a/app/src/main/java/org/example/age/demo/Demo.java b/app/src/main/java/org/example/age/demo/Demo.java index da0a2b200..352cb605f 100644 --- a/app/src/main/java/org/example/age/demo/Demo.java +++ b/app/src/main/java/org/example/age/demo/Demo.java @@ -28,8 +28,9 @@ public final class Demo { /** Main method. */ @SuppressWarnings("CatchAndPrintStackTrace") - public static void main(String[] args) { + public static void main(String[] args) throws IOException { try { + DemoInfra.startRedis(); DemoInfra.startServer(checkMyAge, "config-check-my-age.yaml"); DemoInfra.startServer(crackle, "config-crackle.yaml"); DemoInfra.startServer(pop, "config-pop.yaml"); @@ -41,7 +42,7 @@ public static void main(String[] args) { } catch (Exception e) { e.printStackTrace(); } finally { - System.exit(0); + DemoInfra.stop(); } } diff --git a/app/src/main/java/org/example/age/demo/DemoInfra.java b/app/src/main/java/org/example/age/demo/DemoInfra.java index 530e93320..f6a13dbfe 100644 --- a/app/src/main/java/org/example/age/demo/DemoInfra.java +++ b/app/src/main/java/org/example/age/demo/DemoInfra.java @@ -5,20 +5,30 @@ import io.dropwizard.core.Application; import io.dropwizard.jackson.Jackson; import java.io.File; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import okhttp3.OkHttpClient; import okhttp3.Request; import org.example.age.api.client.retrofit.ApiClient; +import redis.embedded.RedisServer; /** Client/server infrastructure for the demo. */ public final class DemoInfra { + private static RedisServer redis; + private static final OkHttpClient httpClient = new OkHttpClient(); private static final ObjectWriter objectWriter = Jackson.newObjectMapper() .setSerializationInclusion(JsonInclude.Include.NON_NULL) .writerWithDefaultPrettyPrinter(); + /** Starts Redis. */ + public static void startRedis() throws IOException { + redis = new RedisServer(6379); + redis.start(); + } + /** Starts an application. */ public static void startServer(Application app, String configPath) throws Exception { app.run("server", getResourcePath(configPath)); @@ -41,6 +51,12 @@ public static ObjectWriter getObjectWriter() { return objectWriter; } + /** Stops everything (and terminates the application). */ + public static void stop() throws IOException { + redis.stop(); + System.exit(0); + } + /** Get the absolute path of a resource file. */ private static String getResourcePath(String relativePath) throws URISyntaxException { ClassLoader classLoader = DemoInfra.class.getClassLoader(); diff --git a/app/src/main/resources/config-check-my-age.yaml b/app/src/main/resources/config-check-my-age.yaml index fdddae698..55e4facdf 100644 --- a/app/src/main/resources/config-check-my-age.yaml +++ b/app/src/main/resources/config-check-my-age.yaml @@ -9,6 +9,9 @@ clients: crackle: http://localhost:8080 pop: http://localhost:8081 +redis: + url: http://localhost:6379 + stores: verifiedAccounts: John Smith: diff --git a/app/src/main/resources/config-crackle.yaml b/app/src/main/resources/config-crackle.yaml index 89b87641d..08c8b27f5 100644 --- a/app/src/main/resources/config-crackle.yaml +++ b/app/src/main/resources/config-crackle.yaml @@ -5,6 +5,9 @@ service: clients: avsUrl: http://localhost:9090 +redis: + url: http://localhost:6379 + keys: signing: wX: 61340499596180719707288738669477306360190613239883629564918816825111167687915 diff --git a/app/src/main/resources/config-pop.yaml b/app/src/main/resources/config-pop.yaml index c56d09fc5..3f925e001 100644 --- a/app/src/main/resources/config-pop.yaml +++ b/app/src/main/resources/config-pop.yaml @@ -5,6 +5,9 @@ service: clients: avsUrl: http://localhost:9090 +redis: + url: http://localhost:6379 + keys: signing: wX: 61340499596180719707288738669477306360190613239883629564918816825111167687915 diff --git a/app/src/test/java/org/example/age/app/AppVerificationTest.java b/app/src/test/java/org/example/age/app/AppVerificationTest.java index a36f40230..931f3d3a2 100644 --- a/app/src/test/java/org/example/age/app/AppVerificationTest.java +++ b/app/src/test/java/org/example/age/app/AppVerificationTest.java @@ -15,6 +15,7 @@ import org.example.age.app.config.AvsAppConfig; import org.example.age.app.config.SiteAppConfig; import org.example.age.app.testing.TestServiceClient; +import org.example.age.testing.RedisExtension; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import retrofit2.Response; @@ -29,6 +30,9 @@ public final class AppVerificationTest { private static final DropwizardAppExtension avsApp = new DropwizardAppExtension<>(AvsApp.class, ResourceHelpers.resourceFilePath("config-avs.yaml")); + @RegisterExtension + private static final RedisExtension redis = new RedisExtension(6379); + @RegisterExtension private static final TestServiceClient siteClient = new TestServiceClient<>(8080, "username", SiteApi.class); diff --git a/app/src/test/resources/config-avs.yaml b/app/src/test/resources/config-avs.yaml index f9f90144c..a8e3e3eac 100644 --- a/app/src/test/resources/config-avs.yaml +++ b/app/src/test/resources/config-avs.yaml @@ -7,6 +7,9 @@ clients: siteUrls: site: http://localhost:8080 +redis: + url: http://localhost:6379 + stores: verifiedAccounts: person: diff --git a/app/src/test/resources/config-site.yaml b/app/src/test/resources/config-site.yaml index a0d705f32..006046882 100644 --- a/app/src/test/resources/config-site.yaml +++ b/app/src/test/resources/config-site.yaml @@ -5,6 +5,9 @@ service: clients: avsUrl: http://localhost:9090 +redis: + url: http://localhost:6379 + keys: signing: wX: 61340499596180719707288738669477306360190613239883629564918816825111167687915 diff --git a/module/store-inmemory/build.gradle.kts b/module/store-inmemory/build.gradle.kts deleted file mode 100644 index 3f5d93925..000000000 --- a/module/store-inmemory/build.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -plugins { - `java-library` - id("org.example.age.java-conventions") -} - -dependencies { - annotationProcessor(libs.dagger.compiler) - - api(project(":service:module")) - api(libs.dagger.dagger) - api(libs.jackson.databind) - implementation(libs.guava.guava) - implementation(libs.jakartaInject.api) - - testAnnotationProcessor(libs.dagger.compiler) - - testImplementation(project(":testing")) -} diff --git a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStore.java b/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStore.java deleted file mode 100644 index ccd67133f..000000000 --- a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStore.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.example.age.module.store.inmemory; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.Maps; -import java.io.IOException; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import org.example.age.service.module.store.PendingStore; - -/** Implementation of {@link PendingStore}. Requires sticky sessions to work in a distributed environment. */ -final class InMemoryPendingStore implements PendingStore { - - private final BiMap store = Maps.synchronizedBiMap(HashBiMap.create()); - private final ObjectMapper mapper; - private final Class valueType; - private final ScheduledExecutorService scheduledExecutor; - - public InMemoryPendingStore(ObjectMapper mapper, Class valueType, ScheduledExecutorService scheduledExecutor) { - this.mapper = mapper; - this.valueType = valueType; - this.scheduledExecutor = scheduledExecutor; - } - - @SuppressWarnings("FutureReturnValueIgnored") - @Override - public CompletionStage put(String key, V value, OffsetDateTime expiration) { - Duration expiresIn = Duration.between(OffsetDateTime.now(ZoneOffset.UTC), expiration); - if (expiresIn.isNegative() || expiresIn.isZero()) { - return CompletableFuture.completedFuture(null); - } - - JsonHolder jsonHolder = serialize(value); - store.put(key, jsonHolder); - Runnable expirationTask = () -> store.inverse().remove(jsonHolder); - scheduledExecutor.schedule(expirationTask, expiresIn.toMillis(), TimeUnit.MILLISECONDS); - return CompletableFuture.completedFuture(null); - } - - @Override - public CompletionStage> tryGet(String key) { - Optional maybeValue = Optional.ofNullable(store.get(key)).map(this::deserialize); - return CompletableFuture.completedFuture(maybeValue); - } - - @Override - public CompletionStage> tryRemove(String key) { - Optional maybeValue = Optional.ofNullable(store.remove(key)).map(this::deserialize); - return CompletableFuture.completedFuture(maybeValue); - } - - /** Serializes the value to JSON. */ - private JsonHolder serialize(V value) { - try { - return new JsonHolder(mapper.writeValueAsString(value)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** Deserializes a value from JSON. */ - private V deserialize(JsonHolder jsonHolder) { - try { - return mapper.readValue(jsonHolder.value, valueType); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** Holder for a JSON value. {@link #equals(Object)} behaves like {@code ==}. */ - private static final class JsonHolder { - - public final String value; - - public JsonHolder(String value) { - this.value = value; - } - } -} diff --git a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreModule.java b/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreModule.java deleted file mode 100644 index 64cd7c90f..000000000 --- a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreModule.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.example.age.module.store.inmemory; - -import com.fasterxml.jackson.databind.ObjectMapper; -import dagger.Binds; -import dagger.Module; -import java.util.concurrent.ScheduledExecutorService; -import org.example.age.service.module.store.PendingStoreRepository; - -/** - * Dagger module that binds {@link PendingStoreRepository}. - *

- * Depends on an unbound... - *

- *

- * Requires sticky sessions to work in a distributed environment. - */ -@Module -public interface InMemoryPendingStoreModule { - - @Binds - PendingStoreRepository bindPendingStoreRepository(InMemoryPendingStoreRepository impl); -} diff --git a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreRepository.java b/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreRepository.java deleted file mode 100644 index cc0a2c382..000000000 --- a/module/store-inmemory/src/main/java/org/example/age/module/store/inmemory/InMemoryPendingStoreRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.example.age.module.store.inmemory; - -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; -import org.example.age.service.module.store.PendingStore; -import org.example.age.service.module.store.PendingStoreRepository; - -/** Implementation of {@link PendingStoreRepository}. Requires sticky sessions to work in a distributed environment. */ -@Singleton -final class InMemoryPendingStoreRepository implements PendingStoreRepository { - - private final Map> stores = Collections.synchronizedMap(new HashMap<>()); - private final ObjectMapper mapper; - private final ScheduledExecutorService scheduledExecutor; - - @Inject - public InMemoryPendingStoreRepository(ObjectMapper mapper, ScheduledExecutorService scheduledExecutor) { - this.mapper = mapper; - this.scheduledExecutor = scheduledExecutor; - } - - @SuppressWarnings("unchecked") - @Override - public PendingStore get(String name, Class valueType) { - return (PendingStore) stores.computeIfAbsent(name, n -> createPendingStore(valueType)); - } - - /** Creates a {@link PendingStore}. */ - private PendingStore createPendingStore(Class valueType) { - return new InMemoryPendingStore<>(mapper, valueType, scheduledExecutor); - } -} diff --git a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/InMemoryPendingStoreTest.java b/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/InMemoryPendingStoreTest.java deleted file mode 100644 index 05e835d29..000000000 --- a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/InMemoryPendingStoreTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.example.age.module.store.inmemory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.example.age.testing.CompletionStageTesting.getCompleted; - -import dagger.Component; -import jakarta.inject.Singleton; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.Optional; -import org.example.age.module.store.inmemory.testing.FakeScheduledExecutorService; -import org.example.age.module.store.inmemory.testing.TestDependenciesModule; -import org.example.age.service.module.store.PendingStore; -import org.example.age.service.module.store.PendingStoreRepository; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public final class InMemoryPendingStoreTest { - - private PendingStore store; - private FakeScheduledExecutorService scheduledExecutor; - - @BeforeEach - public void createPendingStoreEtAl() { - TestComponent component = TestComponent.create(); - PendingStoreRepository stores = component.pendingStoreRepository(); - store = stores.get("name", Integer.class); - scheduledExecutor = component.fakeScheduledExecutorService(); - } - - @Test - public void putThenRemove() { - getCompleted(store.put("key", 1, expiresIn(5))); - Optional maybeValue1 = getCompleted(store.tryRemove("key")); - assertThat(maybeValue1).hasValue(1); - Optional maybeValue2 = getCompleted(store.tryGet("key")); - assertThat(maybeValue2).isEmpty(); - } - - @Test - public void expire() { - getCompleted(store.put("key", 1, expiresIn(5))); - scheduledExecutor.runScheduledTask(); - Optional maybeValue = getCompleted(store.tryGet("key")); - assertThat(maybeValue).isEmpty(); - } - - @Test - public void putExpiredValue() { - getCompleted(store.put("key", 1, expiresIn(-5))); - Optional maybeValue = getCompleted(store.tryGet("key")); - assertThat(maybeValue).isEmpty(); - } - - @Test - public void expireOldValue() { - getCompleted(store.put("key", 1, expiresIn(5))); - getCompleted(store.put("key", 1, expiresIn(5))); - scheduledExecutor.runScheduledTask(); - Optional maybeValue = getCompleted(store.tryGet("key")); - assertThat(maybeValue).hasValue(1); - } - - @Test - public void putSameValue() { - getCompleted(store.put("key1", 1, expiresIn(5))); - getCompleted(store.put("key2", 1, expiresIn(5))); - Optional maybeValue1 = getCompleted(store.tryGet("key1")); - assertThat(maybeValue1).hasValue(1); - Optional maybeValue2 = getCompleted(store.tryGet("key2")); - assertThat(maybeValue2).hasValue(1); - } - - private static OffsetDateTime expiresIn(int minutes) { - return OffsetDateTime.now(ZoneOffset.UTC).plus(Duration.ofMinutes(minutes)); - } - - /** Dagger component for the stores. */ - @Component(modules = {InMemoryPendingStoreModule.class, TestDependenciesModule.class}) - @Singleton - interface TestComponent { - - static TestComponent create() { - return DaggerInMemoryPendingStoreTest_TestComponent.create(); - } - - PendingStoreRepository pendingStoreRepository(); - - FakeScheduledExecutorService fakeScheduledExecutorService(); - } -} diff --git a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/FakeScheduledExecutorService.java b/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/FakeScheduledExecutorService.java deleted file mode 100644 index 015388fc8..000000000 --- a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/FakeScheduledExecutorService.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.example.age.module.store.inmemory.testing; - -import jakarta.inject.Inject; -import jakarta.inject.Singleton; -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.List; -import java.util.Queue; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** Fake implementation of {@link ScheduledExecutorService}. Scheduled tasks are manually run in FIFO order. */ -@Singleton -public final class FakeScheduledExecutorService implements ScheduledExecutorService { - - private final Queue scheduledTasks = new ArrayDeque<>(); - - @Inject - public FakeScheduledExecutorService() {} - - @Override - public ScheduledFuture schedule(Runnable task, long delay, TimeUnit unit) { - scheduledTasks.add(task); - return null; - } - - /** Runs a single scheduled task. */ - public void runScheduledTask() { - scheduledTasks.remove().run(); - } - - // unsupported operations - - @Override - public ScheduledFuture schedule(Callable task, long delay, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public List> invokeAll(Collection> tasks) { - throw new UnsupportedOperationException(); - } - - @Override - public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public T invokeAny(Collection> tasks) { - throw new UnsupportedOperationException(); - } - - @Override - public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isShutdown() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isTerminated() { - throw new UnsupportedOperationException(); - } - - @Override - public void shutdown() { - throw new UnsupportedOperationException(); - } - - @Override - public List shutdownNow() { - throw new UnsupportedOperationException(); - } - - @Override - public Future submit(Runnable task) { - throw new UnsupportedOperationException(); - } - - @Override - public Future submit(Runnable task, T result) { - throw new UnsupportedOperationException(); - } - - @Override - public Future submit(Callable task) { - throw new UnsupportedOperationException(); - } - - @Override - public void execute(Runnable task) { - throw new UnsupportedOperationException(); - } -} diff --git a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/TestDependenciesModule.java b/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/TestDependenciesModule.java deleted file mode 100644 index 03ccb53ec..000000000 --- a/module/store-inmemory/src/test/java/org/example/age/module/store/inmemory/testing/TestDependenciesModule.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.example.age.module.store.inmemory.testing; - -import com.fasterxml.jackson.databind.ObjectMapper; -import dagger.Binds; -import dagger.Module; -import java.util.concurrent.ScheduledExecutorService; -import org.example.age.testing.TestEnvModule; - -/** - * Dagger module that binds... - *

- */ -@Module(includes = TestEnvModule.class) -public interface TestDependenciesModule { - - @Binds - ScheduledExecutorService bindScheduledExecutorService(FakeScheduledExecutorService impl); -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8f581e860..44f37f82c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,7 +7,6 @@ include( "module:request-demo", "module:client", "module:store-redis", - "module:store-inmemory", "module:store-demo", "module:crypto-demo", "app",