From 7811214b4faca2efaa1fd621d5d6f3291dadd68b Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 14:16:45 -0800 Subject: [PATCH 1/9] refactor: centralize auth utils functions --- .../sdk/auth/EnvVarCredentialProvider.java | 15 +++------- .../sdk/auth/EnvVarV2CredentialProvider.java | 30 +++---------------- .../java/momento/sdk/internal/AuthUtils.java | 25 ++++++++++++++++ 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/momento-sdk/src/main/java/momento/sdk/auth/EnvVarCredentialProvider.java b/momento-sdk/src/main/java/momento/sdk/auth/EnvVarCredentialProvider.java index 70076639..593337c9 100644 --- a/momento-sdk/src/main/java/momento/sdk/auth/EnvVarCredentialProvider.java +++ b/momento-sdk/src/main/java/momento/sdk/auth/EnvVarCredentialProvider.java @@ -2,6 +2,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import momento.sdk.internal.AuthUtils; /** * Parses connection and authentication information from a JWT read from an environment variable. @@ -15,7 +16,7 @@ public class EnvVarCredentialProvider extends StringCredentialProvider { * @param envVarName the environment variable containing the Momento authentication token. */ public EnvVarCredentialProvider(@Nonnull String envVarName) { - super(getApiKeyValueFromEnvVar(envVarName), null, null, null, null); + super(AuthUtils.getApiKeyValueFromEnvVar(envVarName), null, null, null, null); } /** @@ -32,15 +33,7 @@ public EnvVarCredentialProvider( @Nullable String controlHost, @Nullable String cacheHost, @Nullable String storageHost) { - super(getApiKeyValueFromEnvVar(envVarName), controlHost, cacheHost, storageHost, null); - } - - private static String getApiKeyValueFromEnvVar(String envVarName) { - String authToken = System.getenv(envVarName); - if (authToken == null) { - throw new IllegalArgumentException( - "Missing required Momento API Key environment variable: " + envVarName); - } - return authToken; + super( + AuthUtils.getApiKeyValueFromEnvVar(envVarName), controlHost, cacheHost, storageHost, null); } } diff --git a/momento-sdk/src/main/java/momento/sdk/auth/EnvVarV2CredentialProvider.java b/momento-sdk/src/main/java/momento/sdk/auth/EnvVarV2CredentialProvider.java index 7b4c6caf..df8502cd 100644 --- a/momento-sdk/src/main/java/momento/sdk/auth/EnvVarV2CredentialProvider.java +++ b/momento-sdk/src/main/java/momento/sdk/auth/EnvVarV2CredentialProvider.java @@ -1,35 +1,13 @@ package momento.sdk.auth; import javax.annotation.Nonnull; -import momento.sdk.exceptions.InvalidArgumentException; +import momento.sdk.internal.AuthUtils; public class EnvVarV2CredentialProvider extends ApiKeyV2CredentialProvider { public EnvVarV2CredentialProvider(@Nonnull String apiKeyEnvVar, @Nonnull String endpointEnvVar) { - super(getApiKeyValueFromEnvVar(apiKeyEnvVar), getEndpointValueFromEnvVar(endpointEnvVar)); - } - - private static String getApiKeyValueFromEnvVar(String apiKeyEnvVar) { - if (apiKeyEnvVar == null || apiKeyEnvVar.isEmpty()) { // Check for empty env var name - throw new InvalidArgumentException("Env var name cannot be empty"); - } - - String authToken = System.getenv(apiKeyEnvVar); - if (authToken == null || authToken.isEmpty()) { // Check for empty value - throw new InvalidArgumentException("Env var " + apiKeyEnvVar + " must be set"); - } - return authToken; - } - - private static String getEndpointValueFromEnvVar(String endpointEnvVar) { - if (endpointEnvVar == null || endpointEnvVar.isEmpty()) { // Check for empty env var name - throw new InvalidArgumentException("Endpoint env var name cannot be empty"); - } - - String authToken = System.getenv(endpointEnvVar); - if (authToken == null || authToken.isEmpty()) { // Check for empty value - throw new InvalidArgumentException(" Endpoint env var " + endpointEnvVar + " must be set"); - } - return authToken; + super( + AuthUtils.getApiKeyValueFromEnvVar(apiKeyEnvVar), + AuthUtils.getApiKeyValueFromEnvVar(endpointEnvVar)); } } diff --git a/momento-sdk/src/main/java/momento/sdk/internal/AuthUtils.java b/momento-sdk/src/main/java/momento/sdk/internal/AuthUtils.java index baf102b5..104a5539 100644 --- a/momento-sdk/src/main/java/momento/sdk/internal/AuthUtils.java +++ b/momento-sdk/src/main/java/momento/sdk/internal/AuthUtils.java @@ -1,6 +1,7 @@ package momento.sdk.internal; import java.util.Base64; +import momento.sdk.exceptions.InvalidArgumentException; public class AuthUtils { @@ -41,4 +42,28 @@ public static boolean isBase64Encoded(String apiKey) { return false; } } + + public static String getApiKeyValueFromEnvVar(String apiKeyEnvVar) { + if (apiKeyEnvVar == null || apiKeyEnvVar.isEmpty()) { // Check for empty env var name + throw new InvalidArgumentException("API key env var name cannot be empty"); + } + + String authToken = System.getenv(apiKeyEnvVar); + if (authToken == null || authToken.isEmpty()) { // Check for empty value + throw new InvalidArgumentException("Env var " + apiKeyEnvVar + " must be set"); + } + return authToken; + } + + public static String getEndpointValueFromEnvVar(String endpointEnvVar) { + if (endpointEnvVar == null || endpointEnvVar.isEmpty()) { // Check for empty env var name + throw new InvalidArgumentException("Endpoint env var name cannot be empty"); + } + + String authToken = System.getenv(endpointEnvVar); + if (authToken == null || authToken.isEmpty()) { // Check for empty value + throw new InvalidArgumentException(" Endpoint env var " + endpointEnvVar + " must be set"); + } + return authToken; + } } From 7fa2fdf366afdd53c0f1614ff39c7a6d494ea089 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 14:52:29 -0800 Subject: [PATCH 2/9] chore: update non-auth client examples to use v2 key --- examples/cache-with-aws/build.gradle.kts | 2 +- .../java/momento/client/example/BasicExample.java | 5 +++-- examples/cache/README.md | 15 ++++++++------- examples/cache/build.gradle.kts | 2 +- .../java/momento/client/example/BasicExample.java | 4 +--- .../momento/client/example/BatchUtilsExample.java | 4 +--- .../momento/client/example/DictionaryExample.java | 11 +---------- .../java/momento/client/example/ListExample.java | 11 +---------- .../momento/client/example/LoadGenerator.java | 12 ++---------- .../java/momento/client/example/SetExample.java | 10 +--------- .../momento/client/example/SortedSetExample.java | 15 +++------------ examples/lambda/docker/build.gradle.kts | 2 +- .../momento/lambda/example/MomentoJavaLambda.java | 10 ++++------ examples/leaderboard/README.template.md | 3 ++- examples/leaderboard/build.gradle.kts | 2 +- .../java/momento/client/example/BasicExample.java | 5 ++--- .../client/example/doc_examples/CheatSheet.java | 4 ++-- .../example/doc_examples/DocExamplesJavaAPIs.java | 6 ++---- examples/token/build.gradle.kts | 2 +- .../client/example/DisposableTokenExample.java | 2 +- .../docs_examples/DocExamplesJavaAPIs.java | 2 +- examples/topic/build.gradle.kts | 2 +- .../java/momento/client/example/TopicExample.java | 11 +---------- 23 files changed, 42 insertions(+), 100 deletions(-) diff --git a/examples/cache-with-aws/build.gradle.kts b/examples/cache-with-aws/build.gradle.kts index 04fa1797..6a31b3fd 100644 --- a/examples/cache-with-aws/build.gradle.kts +++ b/examples/cache-with-aws/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") // For examples to store secrets in AWS Secrets Manager implementation("software.amazon.awssdk:secretsmanager:2.20.93") diff --git a/examples/cache-with-aws/src/main/java/momento/client/example/BasicExample.java b/examples/cache-with-aws/src/main/java/momento/client/example/BasicExample.java index e186c89e..6a51368d 100644 --- a/examples/cache-with-aws/src/main/java/momento/client/example/BasicExample.java +++ b/examples/cache-with-aws/src/main/java/momento/client/example/BasicExample.java @@ -20,6 +20,7 @@ public class BasicExample { + private static final String MOMENTO_ENDPOINT = "cache.cell-4-us-west-2-1.prod.a.momentohq.com"; private static final String API_KEY_SECRET_NAME = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); @@ -85,7 +86,7 @@ private static void listCaches(CacheClient cacheClient) { } public static CredentialProvider getCredentialsFromSecretsManagerAuthToken() { - final Region region = Region.of("us-east-1"); + final Region region = Region.of("us-west-2"); // Create a Secrets Manager client final SecretsManagerClient client = @@ -111,7 +112,7 @@ public static CredentialProvider getCredentialsFromSecretsManagerAuthToken() { final String secret = getSecretValueResponse.secretString(); try { - return CredentialProvider.fromString(secret); + return CredentialProvider.fromApiKeyV2(secret, MOMENTO_ENDPOINT); } catch (SdkException e) { logger.error( "An error occured while parsing the secrets manager vended" diff --git a/examples/cache/README.md b/examples/cache/README.md index 4f4bed52..7bce83e6 100644 --- a/examples/cache/README.md +++ b/examples/cache/README.md @@ -10,10 +10,11 @@ _Read this in other languages_: [日本語](README.ja.md) - JDK 14 or above is required to run the example - To get started with Momento you will need a Momento API key. You can get one from the [Momento Console](https://console.gomomento.com). +- A Momento service endpoint is required. Choose the one for the [region](https://docs.momentohq.com/platform/regions) you'll be using, e.g. `cache.cell-1-ap-southeast-1-1.prod.a.momentohq.com` for ap-southeast-1. ### Basic ```bash -MOMENTO_API_KEY= ./gradlew basic +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew basic ``` Example Code: [BasicExample.java](cache/src/main/java/momento/client/example/BasicExample.java) @@ -21,35 +22,35 @@ Example Code: [BasicExample.java](cache/src/main/java/momento/client/example/Bas ### List ```bash -MOMENTO_API_KEY= ./gradlew list +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew list ``` Example Code: [ListExample.java](cache/src/main/java/momento/client/example/ListExample.java) ### Set ```bash -MOMENTO_API_KEY= ./gradlew set +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew set ``` Example Code: [SetExample.java](cache/src/main/java/momento/client/example/SetExample.java) ### Dictionary ```bash -MOMENTO_API_KEY= ./gradlew dictionary +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew dictionary ``` Example Code: [DictionaryExample.java](cache/src/main/java/momento/client/example/DictionaryExample.java) ### Sorted Set ```bash -MOMENTO_API_KEY= ./gradlew sortedSet +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew sortedSet ``` Example Code: [SortedSetExample.java](cache/src/main/java/momento/client/example/SortedSetExample.java) ### Batch Util ```bash -MOMENTO_API_KEY= ./gradlew sortedSet +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew sortedSet ``` Example Code: [SortedSetExample.java](cache/src/main/java/momento/client/example/SortedSetExample.java) @@ -57,7 +58,7 @@ Example Code: [SortedSetExample.java](cache/src/main/java/momento/client/example ### With a Backing Database ```bash -MOMENTO_API_KEY= ./gradlew withDatabase +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew withDatabase ``` Example Code: [WithDatabaseExample.java](cache/src/main/java/momento/client/example/advanced/WithDatabaseExample.java) diff --git a/examples/cache/build.gradle.kts b/examples/cache/build.gradle.kts index 100bc220..805d4a41 100644 --- a/examples/cache/build.gradle.kts +++ b/examples/cache/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") implementation("com.google.guava:guava:31.1-android") diff --git a/examples/cache/src/main/java/momento/client/example/BasicExample.java b/examples/cache/src/main/java/momento/client/example/BasicExample.java index ad75aafc..1e5258b2 100644 --- a/examples/cache/src/main/java/momento/client/example/BasicExample.java +++ b/examples/cache/src/main/java/momento/client/example/BasicExample.java @@ -3,7 +3,6 @@ import java.time.Duration; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.AlreadyExistsException; import momento.sdk.responses.cache.GetResponse; @@ -13,7 +12,6 @@ public class BasicExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "cache"; @@ -23,7 +21,7 @@ public class BasicExample { public static void main(String[] args) { printStartBanner(); - final CredentialProvider credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { diff --git a/examples/cache/src/main/java/momento/client/example/BatchUtilsExample.java b/examples/cache/src/main/java/momento/client/example/BatchUtilsExample.java index 7a50cf76..3cf17902 100644 --- a/examples/cache/src/main/java/momento/client/example/BatchUtilsExample.java +++ b/examples/cache/src/main/java/momento/client/example/BatchUtilsExample.java @@ -5,7 +5,6 @@ import java.util.List; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.batchutils.MomentoBatchUtils; import momento.sdk.batchutils.request.BatchGetRequest; import momento.sdk.batchutils.response.BatchGetResponse; @@ -28,7 +27,6 @@ */ public class BatchUtilsExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "cache"; @@ -40,7 +38,7 @@ public class BatchUtilsExample { public static void main(String[] args) { - final CredentialProvider credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { diff --git a/examples/cache/src/main/java/momento/client/example/DictionaryExample.java b/examples/cache/src/main/java/momento/client/example/DictionaryExample.java index 8d154153..6cb06acd 100644 --- a/examples/cache/src/main/java/momento/client/example/DictionaryExample.java +++ b/examples/cache/src/main/java/momento/client/example/DictionaryExample.java @@ -5,10 +5,8 @@ import java.util.stream.Collectors; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.AlreadyExistsException; -import momento.sdk.exceptions.SdkException; import momento.sdk.responses.cache.control.CacheCreateResponse; import momento.sdk.responses.cache.dictionary.DictionaryFetchResponse; import momento.sdk.responses.cache.dictionary.DictionaryRemoveFieldResponse; @@ -19,7 +17,6 @@ public class DictionaryExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "dictionary-example-cache"; @@ -30,13 +27,7 @@ public class DictionaryExample { public static void main(String[] args) { logStartBanner(); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { diff --git a/examples/cache/src/main/java/momento/client/example/ListExample.java b/examples/cache/src/main/java/momento/client/example/ListExample.java index e0ec2300..cea1f98d 100644 --- a/examples/cache/src/main/java/momento/client/example/ListExample.java +++ b/examples/cache/src/main/java/momento/client/example/ListExample.java @@ -4,10 +4,8 @@ import java.util.List; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.AlreadyExistsException; -import momento.sdk.exceptions.SdkException; import momento.sdk.responses.cache.control.CacheCreateResponse; import momento.sdk.responses.cache.list.ListConcatenateFrontResponse; import momento.sdk.responses.cache.list.ListFetchResponse; @@ -19,7 +17,6 @@ public class ListExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "list-example-cache"; @@ -30,13 +27,7 @@ public class ListExample { public static void main(String[] args) { logStartBanner(); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { diff --git a/examples/cache/src/main/java/momento/client/example/LoadGenerator.java b/examples/cache/src/main/java/momento/client/example/LoadGenerator.java index 6eace3af..1be9850b 100644 --- a/examples/cache/src/main/java/momento/client/example/LoadGenerator.java +++ b/examples/cache/src/main/java/momento/client/example/LoadGenerator.java @@ -11,10 +11,8 @@ import java.util.function.Function; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.MomentoErrorCode; -import momento.sdk.exceptions.SdkException; import momento.sdk.responses.cache.GetResponse; import momento.sdk.responses.cache.SetResponse; import org.HdrHistogram.ConcurrentHistogram; @@ -24,7 +22,7 @@ @SuppressWarnings("UnstableApiUsage") public class LoadGenerator { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; + private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "java-loadgen"; private static final Logger logger = LoggerFactory.getLogger(LoadGenerator.class); @@ -57,13 +55,7 @@ public LoadGenerator( int warmupTime) { cacheValue = "x".repeat(cacheValueLength); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); client = CacheClient.create(credentialProvider, Configurations.Laptop.v1(), DEFAULT_ITEM_TTL); client.createCache(CACHE_NAME); diff --git a/examples/cache/src/main/java/momento/client/example/SetExample.java b/examples/cache/src/main/java/momento/client/example/SetExample.java index 6f49724a..ac73ddfb 100644 --- a/examples/cache/src/main/java/momento/client/example/SetExample.java +++ b/examples/cache/src/main/java/momento/client/example/SetExample.java @@ -4,10 +4,8 @@ import java.util.Set; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.AlreadyExistsException; -import momento.sdk.exceptions.SdkException; import momento.sdk.responses.cache.control.CacheCreateResponse; import momento.sdk.responses.cache.set.SetAddElementResponse; import momento.sdk.responses.cache.set.SetAddElementsResponse; @@ -29,13 +27,7 @@ public class SetExample { public static void main(String[] args) { logStartBanner(); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { diff --git a/examples/cache/src/main/java/momento/client/example/SortedSetExample.java b/examples/cache/src/main/java/momento/client/example/SortedSetExample.java index 253f5642..86b620f0 100644 --- a/examples/cache/src/main/java/momento/client/example/SortedSetExample.java +++ b/examples/cache/src/main/java/momento/client/example/SortedSetExample.java @@ -6,10 +6,8 @@ import java.util.stream.Collectors; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; -import momento.sdk.exceptions.AlreadyExistsException; -import momento.sdk.exceptions.SdkException; +import momento.sdk.exceptions.CacheAlreadyExistsException; import momento.sdk.responses.cache.control.CacheCreateResponse; import momento.sdk.responses.cache.sortedset.SortedSetFetchResponse; import momento.sdk.responses.cache.sortedset.SortedSetGetScoresResponse; @@ -22,7 +20,6 @@ public class SortedSetExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "set-example-cache"; @@ -33,13 +30,7 @@ public class SortedSetExample { public static void main(String[] args) { logStartBanner(); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create(credentialProvider, Configurations.Laptop.latest(), DEFAULT_ITEM_TTL)) { @@ -47,7 +38,7 @@ public static void main(String[] args) { // Create a cache final CacheCreateResponse createResponse = client.createCache(CACHE_NAME).join(); if (createResponse instanceof CacheCreateResponse.Error error) { - if (error.getCause() instanceof AlreadyExistsException) { + if (error.getCause() instanceof CacheAlreadyExistsException) { logger.info("Cache with name '{}' already exists.", CACHE_NAME); } else { logger.error("Cache creation failed with error " + error.getErrorCode(), error); diff --git a/examples/lambda/docker/build.gradle.kts b/examples/lambda/docker/build.gradle.kts index 9fa5aa45..2d5491fe 100644 --- a/examples/lambda/docker/build.gradle.kts +++ b/examples/lambda/docker/build.gradle.kts @@ -12,7 +12,7 @@ repositories { dependencies { implementation("com.amazonaws:aws-lambda-java-core:1.2.1") - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") } tasks.jar { diff --git a/examples/lambda/docker/src/main/java/momento/lambda/example/MomentoJavaLambda.java b/examples/lambda/docker/src/main/java/momento/lambda/example/MomentoJavaLambda.java index 2a6a7385..8f5e58b8 100644 --- a/examples/lambda/docker/src/main/java/momento/lambda/example/MomentoJavaLambda.java +++ b/examples/lambda/docker/src/main/java/momento/lambda/example/MomentoJavaLambda.java @@ -4,7 +4,6 @@ import com.amazonaws.services.lambda.runtime.RequestHandler; import momento.sdk.CacheClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.exceptions.AlreadyExistsException; import momento.sdk.responses.cache.GetResponse; @@ -15,7 +14,6 @@ public class MomentoJavaLambda implements RequestHandler, String> { - private static final String AUTH_TOKEN_ENV_VAR = "MOMENTO_AUTH_TOKEN"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "cache"; @@ -25,10 +23,10 @@ public class MomentoJavaLambda implements RequestHandler, St @Override public String handleRequest(Map event, Context context) { - final CredentialProvider credentialProvider = new EnvVarCredentialProvider(AUTH_TOKEN_ENV_VAR); + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); - try (final CacheClient client = - CacheClient.create(credentialProvider, Configurations.Lambda.latest(), DEFAULT_ITEM_TTL)) { + try (final CacheClient client + = CacheClient.create(credentialProvider, Configurations.Lambda.latest(), DEFAULT_ITEM_TTL)) { createCache(client, CACHE_NAME); @@ -66,4 +64,4 @@ private static void createCache(CacheClient cacheClient, String cacheName) { } } } -} \ No newline at end of file +} diff --git a/examples/leaderboard/README.template.md b/examples/leaderboard/README.template.md index 867a40cc..3921f32e 100644 --- a/examples/leaderboard/README.template.md +++ b/examples/leaderboard/README.template.md @@ -8,11 +8,12 @@ - JDK 14 or above is required to run the example - To get started with Momento you will need a Momento API key. You can get one from the [Momento Console](https://console.gomomento.com). +- A Momento service endpoint is required. Choose the one for the [region](https://docs.momentohq.com/platform/regions) you'll be using, e.g. `cache.cell-1-ap-southeast-1-1.prod.a.momentohq.com` for ap-southeast-1. ### Basic ```bash -MOMENTO_API_KEY= ./gradlew basic +MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew basic ``` Example Code: [BasicExample.java](src/main/java/momento/client/example/BasicExample.java) diff --git a/examples/leaderboard/build.gradle.kts b/examples/leaderboard/build.gradle.kts index 7cd47a19..58c25632 100644 --- a/examples/leaderboard/build.gradle.kts +++ b/examples/leaderboard/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") // Logging framework to log and enable logging in the Momento client. implementation("ch.qos.logback:logback-classic:1.4.7") diff --git a/examples/leaderboard/src/main/java/momento/client/example/BasicExample.java b/examples/leaderboard/src/main/java/momento/client/example/BasicExample.java index 782c8572..0073392c 100644 --- a/examples/leaderboard/src/main/java/momento/client/example/BasicExample.java +++ b/examples/leaderboard/src/main/java/momento/client/example/BasicExample.java @@ -7,7 +7,6 @@ import momento.sdk.ILeaderboard; import momento.sdk.LeaderboardClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.config.LeaderboardConfigurations; import momento.sdk.responses.SortOrder; @@ -17,14 +16,14 @@ import momento.sdk.responses.leaderboard.UpsertResponse; public class BasicExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; + private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "cache"; private static final String LEADERBOARD_NAME = "leaderboard"; public static void main(String[] args) { - final CredentialProvider credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient cacheClient = CacheClient.create( diff --git a/examples/leaderboard/src/main/java/momento/client/example/doc_examples/CheatSheet.java b/examples/leaderboard/src/main/java/momento/client/example/doc_examples/CheatSheet.java index 76db1d05..06ada6b6 100644 --- a/examples/leaderboard/src/main/java/momento/client/example/doc_examples/CheatSheet.java +++ b/examples/leaderboard/src/main/java/momento/client/example/doc_examples/CheatSheet.java @@ -5,11 +5,11 @@ import momento.sdk.config.LeaderboardConfigurations; public class CheatSheet { + public static void main(String[] args) { try (final LeaderboardClient leaderboardClient = LeaderboardClient.builder( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), - LeaderboardConfigurations.Laptop.latest()) + CredentialProvider.fromEnvVarV2(), LeaderboardConfigurations.Laptop.latest()) .build()) { // ... } diff --git a/examples/leaderboard/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java b/examples/leaderboard/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java index c16e7733..424115ac 100644 --- a/examples/leaderboard/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java +++ b/examples/leaderboard/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java @@ -28,8 +28,7 @@ public class DocExamplesJavaAPIs { public static void example_API_InstantiateLeaderboardClient() { try (final LeaderboardClient leaderboardClient = LeaderboardClient.builder( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), - LeaderboardConfigurations.Laptop.latest()) + CredentialProvider.fromEnvVarV2(), LeaderboardConfigurations.Laptop.latest()) .build()) { // ... } @@ -256,8 +255,7 @@ public static void example_API_LeaderboardGetCompetitionRank(ILeaderboard leader public static void main(String[] args) { try (final LeaderboardClient leaderboardClient = LeaderboardClient.builder( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), - LeaderboardConfigurations.Laptop.latest()) + CredentialProvider.fromEnvVarV2(), LeaderboardConfigurations.Laptop.latest()) .build()) { example_API_InstantiateLeaderboardClient(); example_API_CreateLeaderboard(leaderboardClient); diff --git a/examples/token/build.gradle.kts b/examples/token/build.gradle.kts index 9daf8bf2..93990b5b 100644 --- a/examples/token/build.gradle.kts +++ b/examples/token/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") implementation("com.google.guava:guava:31.1-android") diff --git a/examples/token/src/main/java/momento/client/example/DisposableTokenExample.java b/examples/token/src/main/java/momento/client/example/DisposableTokenExample.java index 8285b2a7..d062e72e 100644 --- a/examples/token/src/main/java/momento/client/example/DisposableTokenExample.java +++ b/examples/token/src/main/java/momento/client/example/DisposableTokenExample.java @@ -19,7 +19,7 @@ public class DisposableTokenExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; + private static final String API_KEY_ENV_VAR = "V1_API_KEY"; public static void main(String[] args) throws Exception { printStartBanner(); diff --git a/examples/token/src/main/java/momento/client/example/docs_examples/DocExamplesJavaAPIs.java b/examples/token/src/main/java/momento/client/example/docs_examples/DocExamplesJavaAPIs.java index ee6f0806..172382ff 100644 --- a/examples/token/src/main/java/momento/client/example/docs_examples/DocExamplesJavaAPIs.java +++ b/examples/token/src/main/java/momento/client/example/docs_examples/DocExamplesJavaAPIs.java @@ -26,7 +26,7 @@ public static void example_API_GenerateDisposableToken(AuthClient authClient) { public static void main(String[] args) { try (final AuthClient authClient = - AuthClient.builder(CredentialProvider.fromEnvVar("MOMENTO_API_KEY")).build()) { + AuthClient.builder(CredentialProvider.fromEnvVar("V1_API_KEY")).build()) { example_API_GenerateDisposableToken(authClient); } } diff --git a/examples/topic/build.gradle.kts b/examples/topic/build.gradle.kts index 77b66d8b..02d70aee 100644 --- a/examples/topic/build.gradle.kts +++ b/examples/topic/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("software.momento.java:sdk:1.21.0") + implementation("software.momento.java:sdk:1.23.0") implementation("com.google.guava:guava:31.1-android") diff --git a/examples/topic/src/main/java/momento/client/example/TopicExample.java b/examples/topic/src/main/java/momento/client/example/TopicExample.java index 1a6ce108..b96ddbfb 100644 --- a/examples/topic/src/main/java/momento/client/example/TopicExample.java +++ b/examples/topic/src/main/java/momento/client/example/TopicExample.java @@ -5,11 +5,9 @@ import momento.sdk.ISubscriptionCallbacks; import momento.sdk.TopicClient; import momento.sdk.auth.CredentialProvider; -import momento.sdk.auth.EnvVarCredentialProvider; import momento.sdk.config.Configurations; import momento.sdk.config.TopicConfigurations; import momento.sdk.exceptions.AlreadyExistsException; -import momento.sdk.exceptions.SdkException; import momento.sdk.responses.cache.control.CacheCreateResponse; import momento.sdk.responses.topic.TopicMessage; import momento.sdk.responses.topic.TopicPublishResponse; @@ -19,7 +17,6 @@ public class TopicExample { - private static final String API_KEY_ENV_VAR = "MOMENTO_API_KEY"; private static final Duration DEFAULT_ITEM_TTL = Duration.ofSeconds(60); private static final String CACHE_NAME = "topic-example-cache"; @@ -30,13 +27,7 @@ public class TopicExample { public static void main(String[] args) { logStartBanner(); - final CredentialProvider credentialProvider; - try { - credentialProvider = new EnvVarCredentialProvider(API_KEY_ENV_VAR); - } catch (SdkException e) { - logger.error("Unable to load credential from environment variable " + API_KEY_ENV_VAR, e); - throw e; - } + final CredentialProvider credentialProvider = CredentialProvider.fromEnvVarV2(); try (final CacheClient client = CacheClient.create( From b1302eebfc7f164c1fa30e2f6d72e1cb303d48c4 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 15:28:02 -0800 Subject: [PATCH 3/9] chore: separate v1 and v2 tests --- .../momento/sdk/cache/BaseCacheTestClass.java | 10 +- .../momento/sdk/cache/CacheTestApiKeyV2.java | 1197 +++++++++++++++++ .../leaderboard/BaseLeaderboardTestClass.java | 9 +- .../LeaderboardClientTestApiKeyV2.java | 450 +++++++ .../sdk/topics/TopicClientTestApiKeyV2.java | 131 ++ 5 files changed, 1795 insertions(+), 2 deletions(-) create mode 100644 momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java create mode 100644 momento-sdk/src/intTest/java/momento/sdk/leaderboard/LeaderboardClientTestApiKeyV2.java create mode 100644 momento-sdk/src/intTest/java/momento/sdk/topics/TopicClientTestApiKeyV2.java diff --git a/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java b/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java index 953d7ba5..311bc4e9 100644 --- a/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java +++ b/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java @@ -13,18 +13,22 @@ import org.junit.jupiter.api.BeforeAll; public class BaseCacheTestClass { + protected static final Duration DEFAULT_TTL_SECONDS = Duration.ofSeconds(60); protected static final Duration FIVE_SECONDS = Duration.ofSeconds(5); protected static CredentialProvider credentialProvider; + protected static CredentialProvider credentialProviderApiKeyV2; protected static CacheClient cacheClient; + protected static CacheClient cacheClientApiKeyV2; protected static String cacheName; @BeforeAll static void beforeAll() { final boolean consistentReads = System.getenv("CONSISTENT_READS") != null; - credentialProvider = CredentialProvider.fromEnvVar("MOMENTO_API_KEY"); + credentialProvider = CredentialProvider.fromEnvVar("V1_API_KEY"); + credentialProviderApiKeyV2 = CredentialProvider.fromEnvVarV2(); final Configuration config = Configurations.Laptop.latest(); final Configuration consistentConfig = config.withReadConcern(ReadConcern.CONSISTENT); @@ -34,6 +38,9 @@ static void beforeAll() { ? CacheClient.builder(credentialProvider, consistentConfig, DEFAULT_TTL_SECONDS).build() : CacheClient.builder(credentialProvider, config, DEFAULT_TTL_SECONDS).build(); + cacheClientApiKeyV2 = + CacheClient.builder(credentialProvider, config, DEFAULT_TTL_SECONDS).build(); + cacheName = testCacheName(); ensureTestCacheExists(cacheName); } @@ -42,6 +49,7 @@ static void beforeAll() { static void afterAll() { cleanupTestCache(cacheName); cacheClient.close(); + cacheClientApiKeyV2.close(); } protected static void ensureTestCacheExists(String cacheName) { diff --git a/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java b/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java new file mode 100644 index 00000000..8254cf4b --- /dev/null +++ b/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java @@ -0,0 +1,1197 @@ +package momento.sdk.cache; + +import static momento.sdk.TestUtils.randomString; +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import momento.sdk.exceptions.CacheAlreadyExistsException; +import momento.sdk.exceptions.CacheNotFoundException; +import momento.sdk.requests.CollectionTtl; +import momento.sdk.responses.SortOrder; +import momento.sdk.responses.cache.DeleteResponse; +import momento.sdk.responses.cache.GetBatchResponse; +import momento.sdk.responses.cache.GetResponse; +import momento.sdk.responses.cache.IncrementResponse; +import momento.sdk.responses.cache.SetBatchResponse; +import momento.sdk.responses.cache.SetIfNotExistsResponse; +import momento.sdk.responses.cache.SetResponse; +import momento.sdk.responses.cache.control.CacheCreateResponse; +import momento.sdk.responses.cache.control.CacheDeleteResponse; +import momento.sdk.responses.cache.control.CacheFlushResponse; +import momento.sdk.responses.cache.control.CacheListResponse; +import momento.sdk.responses.cache.dictionary.DictionaryFetchResponse; +import momento.sdk.responses.cache.dictionary.DictionaryGetFieldResponse; +import momento.sdk.responses.cache.dictionary.DictionaryIncrementResponse; +import momento.sdk.responses.cache.dictionary.DictionaryRemoveFieldResponse; +import momento.sdk.responses.cache.dictionary.DictionarySetFieldResponse; +import momento.sdk.responses.cache.list.ListConcatenateBackResponse; +import momento.sdk.responses.cache.list.ListConcatenateFrontResponse; +import momento.sdk.responses.cache.list.ListFetchResponse; +import momento.sdk.responses.cache.list.ListLengthResponse; +import momento.sdk.responses.cache.list.ListPopBackResponse; +import momento.sdk.responses.cache.list.ListPopFrontResponse; +import momento.sdk.responses.cache.list.ListPushBackResponse; +import momento.sdk.responses.cache.list.ListPushFrontResponse; +import momento.sdk.responses.cache.list.ListRemoveValueResponse; +import momento.sdk.responses.cache.list.ListRetainResponse; +import momento.sdk.responses.cache.set.SetAddElementsResponse; +import momento.sdk.responses.cache.set.SetFetchResponse; +import momento.sdk.responses.cache.set.SetRemoveElementResponse; +import momento.sdk.responses.cache.sortedset.ScoredElement; +import momento.sdk.responses.cache.sortedset.SortedSetFetchResponse; +import momento.sdk.responses.cache.sortedset.SortedSetGetRankResponse; +import momento.sdk.responses.cache.sortedset.SortedSetGetScoreResponse; +import momento.sdk.responses.cache.sortedset.SortedSetIncrementScoreResponse; +import momento.sdk.responses.cache.sortedset.SortedSetPutElementResponse; +import momento.sdk.responses.cache.sortedset.SortedSetPutElementsResponse; +import momento.sdk.responses.cache.sortedset.SortedSetRemoveElementsResponse; +import momento.sdk.responses.cache.ttl.ItemGetTtlResponse; +import momento.sdk.responses.cache.ttl.UpdateTtlResponse; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +final class CacheTestApiKeyV2 extends BaseCacheTestClass { + + // control plane + @Test + public void listsCachesHappyPath() { + final String newCache = randomString("name"); + + assertThat(cacheClient.createCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(CacheCreateResponse.Success.class); + + try { + assertThat(cacheClient.listCaches()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(CacheListResponse.Success.class)) + .satisfies( + success -> + assertThat(success.getCaches()).anyMatch(ci -> ci.name().equals(newCache))); + } finally { + // cleanup + assertThat(cacheClient.deleteCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(CacheDeleteResponse.Success.class); + } + } + + @Test + public void createDeleteCache_HappyPath() { + final String newCache = randomString("java-v2"); + + assertThat(cacheClient.createCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(CacheCreateResponse.Success.class); + + assertThat(cacheClient.createCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(CacheCreateResponse.Error.class)) + .satisfies( + error -> assertThat(error).hasCauseInstanceOf(CacheAlreadyExistsException.class)); + + assertThat(cacheClient.deleteCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(CacheDeleteResponse.Success.class); + + assertThat(cacheClient.deleteCache(newCache)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(CacheDeleteResponse.Error.class)) + .satisfies(error -> assertThat(error).hasCauseInstanceOf(CacheNotFoundException.class)); + } + + @Test + public void shouldFlushCacheContents() { + final String cacheToFlush = randomString("cacheToFlush"); + final String key = randomString(); + final String value = randomString(); + final Duration ttl1Hour = Duration.ofHours(1); + + try { + CacheCreateResponse response = cacheClient.createCache(cacheToFlush).join(); + assertThat(response).isInstanceOf(CacheCreateResponse.Success.class); + assertThat(cacheClient.set(cacheName, key, value, ttl1Hour)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetResponse.Success.class)) + .satisfies(success -> assertThat(success.value()).isEqualTo(value)); + + // Execute Flush + assertThat(cacheClient.flushCache(cacheName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(CacheFlushResponse.Success.class); + + // Verify that previously set key is now a MISS + assertThat(cacheClient.get(cacheName, key)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(GetResponse.Miss.class); + } finally { + cacheClient.deleteCache(cacheToFlush).join(); + } + } + + // get set delete + @Test + public void createCacheGetSetDeleteValuesAndDeleteCache() { + final String alternateCacheName = randomString("alternateName"); + final String key = randomString("key"); + final String value = randomString("value"); + + cacheClient.createCache(alternateCacheName).join(); + try { + cacheClient.set(cacheName, key, value).join(); + + final GetResponse getResponse = cacheClient.get(cacheName, key).join(); + assertThat(getResponse).isInstanceOf(GetResponse.Hit.class); + assertThat(((GetResponse.Hit) getResponse).valueString()).isEqualTo(value); + + final DeleteResponse deleteResponse = cacheClient.delete(cacheName, key).join(); + assertThat(deleteResponse).isInstanceOf(DeleteResponse.Success.class); + + final GetResponse getAfterDeleteResponse = cacheClient.get(cacheName, key).join(); + assertThat(getAfterDeleteResponse).isInstanceOf(GetResponse.Miss.class); + + final GetResponse getForKeyInSomeOtherCache = cacheClient.get(alternateCacheName, key).join(); + assertThat(getForKeyInSomeOtherCache).isInstanceOf(GetResponse.Miss.class); + } finally { + cacheClient.deleteCache(alternateCacheName).join(); + } + } + + @Test + public void shouldSetStringValueToStringKeyWhenKeyNotExistsWithTtl() { + final String key = randomString(); + final String value = randomString(); + + SetIfNotExistsResponse setIfNotExistsResponse = + cacheClient.setIfNotExists(cacheName, key, value, DEFAULT_TTL_SECONDS).join(); + + assertThat(setIfNotExistsResponse).isInstanceOf(SetIfNotExistsResponse.Stored.class); + assertThat(((SetIfNotExistsResponse.Stored) setIfNotExistsResponse).keyString()).isEqualTo(key); + assertThat(((SetIfNotExistsResponse.Stored) setIfNotExistsResponse).valueString()) + .isEqualTo(value); + + GetResponse getResponse = cacheClient.get(cacheName, key).join(); + assertThat(getResponse).isInstanceOf(GetResponse.Hit.class); + assertThat(((GetResponse.Hit) getResponse).valueString()).isEqualTo(value); + } + + @Test + public void getBatchSetBatchHappyPath() { + final Map items = new HashMap<>(); + items.put("key1", "val1"); + items.put("key2", "val2"); + items.put("key3", "val3"); + final SetBatchResponse setBatchResponse = + cacheClient.setBatch(cacheName, items, Duration.ofMinutes(1)).join(); + assertThat(setBatchResponse).isInstanceOf(SetBatchResponse.Success.class); + for (SetResponse setResponse : + ((SetBatchResponse.Success) setBatchResponse).results().values()) { + assertThat(setResponse).isInstanceOf(SetResponse.Success.class); + } + + final GetBatchResponse getBatchResponse = + cacheClient.getBatch(cacheName, items.keySet()).join(); + + assertThat(getBatchResponse).isInstanceOf(GetBatchResponse.Success.class); + assertThat(((GetBatchResponse.Success) getBatchResponse).valueMapStringString()) + .containsExactlyEntriesOf(items); + } + + // other cache methods + @Test + public void shouldUpdateTTLAndGetItWithStringKey() { + final String key = randomString(); + + // set a key with default ttl + SetResponse setResponse = cacheClient.set(cacheName, key, "value", DEFAULT_TTL_SECONDS).join(); + + assertThat(setResponse).isInstanceOf(SetResponse.Success.class); + + ItemGetTtlResponse itemGetTtlResponse = cacheClient.itemGetTtl(cacheName, key).join(); + + // retrieved ttl should work and less than default ttl + assertThat(itemGetTtlResponse).isInstanceOf(ItemGetTtlResponse.Hit.class); + assertThat(((ItemGetTtlResponse.Hit) itemGetTtlResponse).remainingTtlMillis()) + .isLessThan(DEFAULT_TTL_SECONDS.toMillis()); + + // update ttl to 300 seconds + Duration updatedTTL = Duration.of(300, ChronoUnit.SECONDS); + UpdateTtlResponse updateTtlResponse = cacheClient.updateTtl(cacheName, key, updatedTTL).join(); + + assertThat(updateTtlResponse).isInstanceOf(UpdateTtlResponse.Set.class); + + itemGetTtlResponse = cacheClient.itemGetTtl(cacheName, key).join(); + + // assert that the updated ttl is less than 300 seconds but more than 300 - epsilon (taken as 60 + // to reduce flakiness) + assertThat(itemGetTtlResponse).isInstanceOf(ItemGetTtlResponse.Hit.class); + assertThat(((ItemGetTtlResponse.Hit) itemGetTtlResponse).remainingTtlMillis()) + .isLessThan(updatedTTL.toMillis()); + assertThat(((ItemGetTtlResponse.Hit) itemGetTtlResponse).remainingTtlMillis()) + .isGreaterThan(updatedTTL.minusSeconds(60).toMillis()); + } + + @Test + public void shouldReturnCacheIncrementedValuesWithStringField() { + final String field = randomString(); + + IncrementResponse incrementResponse = + cacheClient.increment(cacheName, field, 1, DEFAULT_TTL_SECONDS).join(); + + assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); + assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(1); + + // increment with ttl specified + incrementResponse = cacheClient.increment(cacheName, field, 50, DEFAULT_TTL_SECONDS).join(); + + assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); + assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(51); + + // increment without ttl specified + incrementResponse = cacheClient.increment(cacheName, field, -1051).join(); + + assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); + assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(-1000); + + GetResponse getResp = cacheClient.get(cacheName, field).join(); + assertThat(getResp).isInstanceOf(GetResponse.Hit.class); + assertThat(((GetResponse.Hit) getResp).valueString()).isEqualTo("-1000"); + } + + // dictionary + @Test + public void dictionarySetFieldAndDictionaryFetchAndHappyPath() { + final String dictionaryName = randomString(); + + // Set String key, String Value + assertThat( + cacheClient.dictionarySetField( + cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionarySetFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryFetch(cacheName, dictionaryName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryFetchResponse.Hit.class)) + .satisfies( + hit -> assertThat(hit.valueMapStringString()).hasSize(1).containsEntry("a", "b")); + + // Set String key, ByteArray Value + assertThat( + cacheClient.dictionarySetField( + cacheName, dictionaryName, "c", "d".getBytes(), CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionarySetFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryFetch(cacheName, dictionaryName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueMapStringByteArray()) + .hasSize(2) + .containsEntry("c", "d".getBytes())); + } + + @Test + public void dictionaryGetFieldHappyPath() { + final String dictionaryName = randomString(); + + // Get the value as a string + assertThat( + cacheClient.dictionarySetField( + cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionarySetFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) + .satisfies( + hit -> { + assertThat(hit.fieldString()).isEqualTo("a"); + assertThat(hit.valueString()).isEqualTo("b"); + }); + + // Get the value as a byte array + assertThat( + cacheClient.dictionarySetField( + cacheName, dictionaryName, "c", "d".getBytes(), CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionarySetFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "c")) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) + .satisfies( + hit -> { + assertThat(hit.field()).isEqualTo("c"); + assertThat(hit.valueByteArray()).isEqualTo("d".getBytes()); + }); + } + + @Test + public void dictionaryIncrementStringFieldHappyPath() { + final String dictionaryName = randomString(); + + // Increment with ttl + assertThat(cacheClient.dictionaryIncrement(cacheName, dictionaryName, "a", 1)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) + .satisfies(success -> assertThat(success.value()).isEqualTo(1)); + + assertThat( + cacheClient.dictionaryIncrement( + cacheName, dictionaryName, "a", 41, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) + .satisfies(success -> assertThat(success.value()).isEqualTo(42)); + + // Increment without ttl + assertThat( + cacheClient.dictionaryIncrement( + cacheName, dictionaryName, "a", -1042, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) + .satisfies(success -> assertThat(success.value()).isEqualTo(-1000)); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) + .satisfies( + hit -> { + assertThat(hit.fieldString()).isEqualTo("a"); + assertThat(hit.valueString()).isEqualTo("-1000"); + }); + } + + @Test + public void dictionaryRemoveFieldStringHappyPath() { + final String dictionaryName = randomString(); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionaryGetFieldResponse.Miss.class); + + assertThat( + cacheClient.dictionarySetField( + cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionarySetFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) + .satisfies( + hit -> { + assertThat(hit.fieldString()).isEqualTo("a"); + assertThat(hit.valueString()).isEqualTo("b"); + }); + + assertThat(cacheClient.dictionaryRemoveField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionaryRemoveFieldResponse.Success.class); + + assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DictionaryGetFieldResponse.Miss.class); + } + + // list + @Test + public void listConcatenateBackStringHappyPath() { + final String listName = randomString(); + final List oldValues = Arrays.asList("val1", "val2", "val3"); + final List newValues = Arrays.asList("val4", "val5", "val6"); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listConcatenateBack( + cacheName, listName, oldValues, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateBackResponse.Success.class); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()).hasSize(3).containsExactlyElementsOf(oldValues)); + + assertThat(cacheClient.listConcatenateBack(cacheName, listName, newValues)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateBackResponse.Success.class); + + final Iterable expectedList = Iterables.concat(oldValues, newValues); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(6) + .containsExactlyElementsOf(expectedList)); + + // Add the original values again and truncate the list to 6 items + assertThat(cacheClient.listConcatenateBack(cacheName, listName, oldValues, 6)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateBackResponse.Success.class); + + final Iterable newExpectedList = Iterables.concat(newValues, oldValues); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(6) + .containsExactlyElementsOf(newExpectedList)); + } + + @Test + public void shouldFetchAllValuesWhenListFetchWithPositiveStartEndIndices() { + List values = Arrays.asList("val1", "val2", "val3", "val4"); + final String listName = randomString(); + + cacheClient + .listConcatenateBack( + cacheName, listName, values, null, CollectionTtl.of(DEFAULT_TTL_SECONDS)) + .join(); + + ListFetchResponse listFetchResponse = cacheClient.listFetch(cacheName, listName, 1, 3).join(); + + assertThat(listFetchResponse).isInstanceOf(ListFetchResponse.Hit.class); + + List expectedResult = Arrays.asList("val2", "val3"); + assertThat(((ListFetchResponse.Hit) listFetchResponse).valueListString()) + .isEqualTo(expectedResult); + } + + @Test + public void listConcatenateFrontStringHappyPath() { + final String listName = randomString(); + final List oldValues = Arrays.asList("val1", "val2", "val3"); + final List newValues = Arrays.asList("val4", "val5", "val6"); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listConcatenateFront( + cacheName, listName, oldValues, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()).hasSize(3).containsExactlyElementsOf(oldValues)); + + assertThat(cacheClient.listConcatenateFront(cacheName, listName, newValues)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + final Iterable expectedList = Iterables.concat(newValues, oldValues); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(6) + .containsExactlyElementsOf(expectedList)); + + // Add the original values again and truncate the list to 6 items + assertThat(cacheClient.listConcatenateFront(cacheName, listName, oldValues, 6)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + final Iterable newExpectedList = Iterables.concat(oldValues, newValues); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(6) + .containsExactlyElementsOf(newExpectedList)); + } + + @Test + public void listLengthHappyPath() { + final String listName = randomString(); + final List stringValues = Arrays.asList("val1", "val2", "val3"); + final List byteArrayValues = + Arrays.asList("val1".getBytes(), "val2".getBytes(), "val3".getBytes()); + + assertThat(cacheClient.listLength(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListLengthResponse.Miss.class); + + // add string values to list + assertThat( + cacheClient.listConcatenateFront( + cacheName, listName, stringValues, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + assertThat(cacheClient.listLength(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListLengthResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.getListLength()).isEqualTo(stringValues.size())); + + // add byte array values to list + assertThat( + cacheClient.listConcatenateFrontByteArray( + cacheName, listName, byteArrayValues, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + assertThat(cacheClient.listLength(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListLengthResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.getListLength()) + .isEqualTo(stringValues.size() + byteArrayValues.size())); + } + + @Test + public void listPopBackHappyPath() { + final String listName = randomString(); + List values = Arrays.asList("val1", "val2", "val3"); + + assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listConcatenateBack( + cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateBackResponse.Success.class); + + // Pop the value as string from back of the list + assertThat(cacheClient.listPopBack(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListPopBackResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueString()).isEqualTo("val3")); + + // Pop the value as byte array from the back of the new list + assertThat(cacheClient.listPopBack(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListPopBackResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueByteArray()).isEqualTo("val2".getBytes())); + } + + @Test + public void listPopFrontHappyPath() { + final String listName = randomString(); + List values = Arrays.asList("val1", "val2", "val3"); + + assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listConcatenateBack( + cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateBackResponse.Success.class); + + // Pop the value as string from front of the list + assertThat(cacheClient.listPopFront(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListPopFrontResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueString()).isEqualTo("val1")); + + // Pop the value as byte array from the front of the new list + assertThat(cacheClient.listPopFront(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListPopFrontResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueByteArray()).isEqualTo("val2".getBytes())); + } + + @Test + public void listPushBackStringHappyPath() { + final String listName = randomString(); + final String oldValue = "val1"; + final String newValue = "val2"; + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listPushBack( + cacheName, listName, oldValue, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushBackResponse.Success.class); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueListString()).hasSize(1).containsOnly(oldValue)); + + // Add the same value + assertThat(cacheClient.listPushBack(cacheName, listName, oldValue)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushBackResponse.Success.class); + + final List expectedList = Arrays.asList(oldValue, oldValue); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(2) + .containsExactlyElementsOf(expectedList)); + + // Add a new value and truncate the list to 2 items + assertThat(cacheClient.listPushBack(cacheName, listName, newValue, 2)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushBackResponse.Success.class); + + final List newExpectedList = Arrays.asList(oldValue, newValue); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(2) + .containsExactlyElementsOf(newExpectedList)); + } + + @Test + public void listPushFrontStringHappyPath() { + final String listName = randomString(); + final String oldValue = "val1"; + final String newValue = "val2"; + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListFetchResponse.Miss.class); + + assertThat( + cacheClient.listPushFront( + cacheName, listName, oldValue, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushFrontResponse.Success.class); + + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueListString()).hasSize(1).containsOnly(oldValue)); + + // Add the same value + assertThat(cacheClient.listPushFront(cacheName, listName, oldValue)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushFrontResponse.Success.class); + + final List expectedList = Arrays.asList(oldValue, oldValue); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(2) + .containsExactlyElementsOf(expectedList)); + + // Add a new value and truncate the list to 2 items + assertThat(cacheClient.listPushFront(cacheName, listName, newValue, 2)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListPushFrontResponse.Success.class); + + final List newExpectedList = Arrays.asList(newValue, oldValue); + assertThat(cacheClient.listFetch(cacheName, listName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueListString()) + .hasSize(2) + .containsExactlyElementsOf(newExpectedList)); + } + + @Test + public void listRemoveValueStringHappyPath() { + final String listName = randomString(); + List values = Arrays.asList("val1", "val1", "val2", "val3", "val4"); + + assertThat( + cacheClient.listConcatenateFront( + cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + // Remove value from list + String removeValue = "val1"; + assertThat(cacheClient.listRemoveValue(cacheName, listName, removeValue)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListRemoveValueResponse.Success.class); + + List expectedList = Arrays.asList("val2", "val3", "val4"); + assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueListString()).hasSize(3).containsAll(expectedList)); + } + + @Test + public void shouldRetainAllValuesWhenListRetainWithPositiveStartEndIndices() { + final String listName = randomString(); + final List stringValues = Arrays.asList("val1", "val2", "val3", "val4"); + + assertThat( + cacheClient.listConcatenateFront( + cacheName, listName, stringValues, null, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListConcatenateFrontResponse.Success.class); + + assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueListString()).hasSize(4).containsAll(stringValues)); + + assertThat(cacheClient.listRetain(cacheName, listName, 1, 3)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(ListRetainResponse.Success.class); + + List expectedList = Arrays.asList("val2", "val3"); + assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueListString()).hasSize(2).containsAll(expectedList)); + } + + // set + @Test + public void setAddElementsStringHappyPath() { + final String setName = randomString(); + final Set firstSet = Sets.newHashSet("one", "two"); + final Set secondSet = Sets.newHashSet("two", "three"); + + assertThat(cacheClient.setAddElements(cacheName, setName, firstSet)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetAddElementsResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(2).containsAll(firstSet)); + + // Try to add the same elements again + assertThat( + cacheClient.setAddElements(cacheName, setName, firstSet, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetAddElementsResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(2).containsAll(firstSet)); + + // Add a set with one new and one overlapping element + assertThat( + cacheClient.setAddElements(cacheName, setName, secondSet, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetAddElementsResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.valueSetString()) + .hasSize(3) + .containsAll(firstSet) + .containsAll(secondSet)); + } + + @Test + public void setRemoveElementStringHappyPath() { + final String setName = randomString(); + final String element1 = "one"; + final String element2 = "two"; + final Set elements = Sets.newHashSet(element1, element2); + + // Add some elements to a set + assertThat( + cacheClient.setAddElements(cacheName, setName, elements, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetAddElementsResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies( + hit -> assertThat(hit.valueSetString()).hasSize(2).containsOnly(element1, element2)); + + // Remove an element + assertThat(cacheClient.setRemoveElement(cacheName, setName, element1)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetRemoveElementResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(1).containsOnly(element2)); + + // Try to remove the same element again + assertThat(cacheClient.setRemoveElement(cacheName, setName, element1)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetRemoveElementResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(1).containsOnly(element2)); + + // Remove the last element + assertThat(cacheClient.setRemoveElement(cacheName, setName, element2)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetRemoveElementResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetFetchResponse.Miss.class); + + // Remove an element from the now non-existent set + assertThat(cacheClient.setRemoveElement(cacheName, setName, element2)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetRemoveElementResponse.Success.class); + + assertThat(cacheClient.setFetch(cacheName, setName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SetFetchResponse.Miss.class); + } + + // sorted set + @Test + public void sortedSetPutElementStringHappyPath() { + final String sortedSetName = randomString(); + final String value = "1"; + final double score = 1.0; + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetFetchResponse.Miss.class); + + assertThat( + cacheClient.sortedSetPutElement( + cacheName, sortedSetName, value, score, CollectionTtl.fromCacheTtl())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementResponse.Success.class); + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).map(ScoredElement::getValue).containsOnly(value); + assertThat(scoredElements).map(ScoredElement::getScore).containsOnly(score); + }); + } + + @Test + public void sortedSetFetchByRankStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + final String two = "2"; + final String three = "3"; + final String four = "4"; + final String five = "5"; + + final Map elements = new HashMap<>(); + elements.put(one, 0.0); + elements.put(two, 1.0); + elements.put(three, 0.5); + elements.put(four, 2.0); + elements.put(five, 1.5); + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetFetchResponse.Miss.class); + + assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementsResponse.Success.class); + + // Full set ascending, end index larger than set + assertThat( + cacheClient.sortedSetFetchByRank(cacheName, sortedSetName, 0, 6, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(5); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(one, three, two, five, four); + }); + + // Partial set descending + assertThat( + cacheClient.sortedSetFetchByRank(cacheName, sortedSetName, 1, 4, SortOrder.DESCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(3); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(five, two, three); + }); + } + + @Test + public void sortedSetFetchByScoreStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + final String two = "2"; + final String three = "3"; + final String four = "4"; + final String five = "5"; + + final Map elements = new HashMap<>(); + elements.put(one, 0.0); + elements.put(two, 1.0); + elements.put(three, 0.5); + elements.put(four, 2.0); + elements.put(five, 1.5); + + assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetFetchResponse.Miss.class); + + assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementsResponse.Success.class); + + // Full set ascending, end index larger than set + assertThat( + cacheClient.sortedSetFetchByScore( + cacheName, sortedSetName, 0.0, 9.9, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(5); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(one, three, two, five, four); + assertThat(scoredElements) + .map(ScoredElement::getScore) + .containsSequence(0.0, 0.5, 1.0, 1.5, 2.0); + }); + + // Partial set descending + assertThat( + cacheClient.sortedSetFetchByScore( + cacheName, sortedSetName, 0.2, 1.9, SortOrder.DESCENDING, 0, 99)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(3); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(five, two, three); + }); + + // Partial set limited by offset and count + assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName, null, null, null, 1, 3)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(3); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(three, two, five); + }); + + // Full set ascending + assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> { + final List scoredElements = hit.elementsList(); + assertThat(scoredElements).hasSize(5); + // check ordering + assertThat(scoredElements) + .map(ScoredElement::getValue) + .containsSequence(one, three, two, five, four); + }); + } + + @Test + public void sortedSetGetRankStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + final String two = "2"; + + assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetGetRankResponse.Miss.class); + + assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementResponse.Success.class); + + assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.rank()).isEqualTo(0)); + + // Add another element that changes the rank of the first one + assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementResponse.Success.class); + + assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.rank()).isEqualTo(1)); + + // Check the descending rank + assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, SortOrder.DESCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.rank()).isEqualTo(0)); + } + + @Test + public void sortedSetGetScoreStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + final String two = "2"; + + assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetGetScoreResponse.Miss.class); + + assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementResponse.Success.class); + + assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetScoreResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.score()).isEqualTo(1.0)); + + // Add another element that changes the rank of the first one + assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementResponse.Success.class); + + assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetScoreResponse.Hit.class)) + .satisfies(hit -> assertThat(hit.score()).isEqualTo(1.0)); + } + + @Test + public void sortedSetIncrementScoreStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + + assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, 1.0)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) + .satisfies(success -> assertThat(success.score()).isEqualTo(1.0)); + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.elementsList()) + .hasSize(1) + .map(ScoredElement::getScore) + .containsOnly(1.0)); + + assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, 14.5)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) + .satisfies(success -> assertThat(success.score()).isEqualTo(15.5)); + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.elementsList()) + .hasSize(1) + .map(ScoredElement::getScore) + .containsOnly(15.5)); + + assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, -115.5)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) + .satisfies(success -> assertThat(success.score()).isEqualTo(-100)); + } + + @Test + public void sortedSetRemoveElementsStringHappyPath() { + final String sortedSetName = randomString(); + final String one = "1"; + final String two = "2"; + final String three = "3"; + final Map elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0); + + assertThat(cacheClient.sortedSetRemoveElements(cacheName, sortedSetName, elements.keySet())) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetRemoveElementsResponse.Success.class); + + assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetPutElementsResponse.Success.class); + + assertThat( + cacheClient.sortedSetRemoveElements( + cacheName, sortedSetName, Sets.newHashSet(one, two))) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(SortedSetRemoveElementsResponse.Success.class); + + assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) + .satisfies( + hit -> + assertThat(hit.elementsList()) + .hasSize(1) + .map(ScoredElement::getValue) + .containsOnly(three)); + } +} diff --git a/momento-sdk/src/intTest/java/momento/sdk/leaderboard/BaseLeaderboardTestClass.java b/momento-sdk/src/intTest/java/momento/sdk/leaderboard/BaseLeaderboardTestClass.java index c3e4ad92..6cde9f08 100644 --- a/momento-sdk/src/intTest/java/momento/sdk/leaderboard/BaseLeaderboardTestClass.java +++ b/momento-sdk/src/intTest/java/momento/sdk/leaderboard/BaseLeaderboardTestClass.java @@ -15,17 +15,21 @@ import org.junit.jupiter.api.BeforeAll; public class BaseLeaderboardTestClass { + protected static final Duration DEFAULT_TTL_SECONDS = Duration.ofSeconds(60); protected static final Duration FIVE_SECONDS = Duration.ofSeconds(5); protected static CredentialProvider credentialProvider; + protected static CredentialProvider credentialProviderApiKeyV2; protected static CacheClient cacheClient; protected static LeaderboardClient leaderboardClient; + protected static LeaderboardClient leaderboardClientApiKeyV2; protected static String cacheName; @BeforeAll static void beforeAll() { - credentialProvider = CredentialProvider.fromEnvVar("MOMENTO_API_KEY"); + credentialProvider = CredentialProvider.fromEnvVar("V1_API_KEY"); + credentialProviderApiKeyV2 = CredentialProvider.fromEnvVarV2(); final Configuration config = Configurations.Laptop.latest(); @@ -33,6 +37,8 @@ static void beforeAll() { final LeaderboardConfiguration leaderboardConfig = LeaderboardConfigurations.Laptop.latest(); leaderboardClient = LeaderboardClient.builder(credentialProvider, leaderboardConfig).build(); + leaderboardClientApiKeyV2 = + LeaderboardClient.builder(credentialProviderApiKeyV2, leaderboardConfig).build(); cacheName = testCacheName(); ensureTestCacheExists(cacheName); @@ -43,6 +49,7 @@ static void afterAll() { cleanupTestCache(cacheName); cacheClient.close(); leaderboardClient.close(); + leaderboardClientApiKeyV2.close(); } protected static void ensureTestCacheExists(String cacheName) { diff --git a/momento-sdk/src/intTest/java/momento/sdk/leaderboard/LeaderboardClientTestApiKeyV2.java b/momento-sdk/src/intTest/java/momento/sdk/leaderboard/LeaderboardClientTestApiKeyV2.java new file mode 100644 index 00000000..b5069424 --- /dev/null +++ b/momento-sdk/src/intTest/java/momento/sdk/leaderboard/LeaderboardClientTestApiKeyV2.java @@ -0,0 +1,450 @@ +package momento.sdk.leaderboard; + +import static momento.sdk.TestUtils.randomString; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import momento.sdk.ILeaderboard; +import momento.sdk.responses.SortOrder; +import momento.sdk.responses.leaderboard.DeleteResponse; +import momento.sdk.responses.leaderboard.FetchResponse; +import momento.sdk.responses.leaderboard.LeaderboardElement; +import momento.sdk.responses.leaderboard.LengthResponse; +import momento.sdk.responses.leaderboard.RemoveElementsResponse; +import momento.sdk.responses.leaderboard.UpsertResponse; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +public class LeaderboardClientTestApiKeyV2 extends BaseLeaderboardTestClass { + + @Test + public void upsertHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).hasSize(3); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2, 3); + }); + + elements.clear(); + elements.put(2, 4.0); + elements.put(3, 3.0); + elements.put(4, 2.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).hasSize(4); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 4, 3, 2); + }); + } + + @Test + public void fetchByScoreHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + // ascending + assertThat(leaderboard.fetchByScore()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2, 3); + }); + assertThat(leaderboard.fetchByScore(null, null, null, 1, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2, 3); + }); + assertThat(leaderboard.fetchByScore(null, null, SortOrder.ASCENDING, 0, 2)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2); + }); + + // descending + assertThat(leaderboard.fetchByScore(null, null, SortOrder.DESCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(3, 2, 1); + }); + assertThat(leaderboard.fetchByScore(null, null, SortOrder.DESCENDING, 1, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2, 1); + }); + assertThat(leaderboard.fetchByScore(null, null, SortOrder.DESCENDING, 0, 2)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(3, 2); + }); + + // limited by max score + assertThat(leaderboard.fetchByScore(null, 2.1, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2); + }); + + // limited by min score + assertThat(leaderboard.fetchByScore(1.1, null, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2, 3); + }); + + // limited by min score and max score + assertThat(leaderboard.fetchByScore(1.1, 3.0, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2); + }); + } + + @Test + public void fetchByRankHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + // ascending + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2, 3); + }); + + // descending + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.DESCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(3, 2, 1); + }); + + // rank range smaller than leaderboard size + assertThat(leaderboard.fetchByRank(0, 2, null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2); + }); + + assertThat(leaderboard.fetchByRank(1, 2, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2); + }); + } + + @Test + public void getRankHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + // ascending + assertThat(leaderboard.getRank(elements.keySet(), SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 0), tuple(2, 1), tuple(3, 2))); + + // descending + assertThat(leaderboard.getRank(elements.keySet(), SortOrder.DESCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 2), tuple(2, 1), tuple(3, 0))); + + // ids are a subset of the leaderboard + assertThat(leaderboard.getRank(new HashSet<>(Arrays.asList(1, 2)), null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 0), tuple(2, 1))); + + // ids are a superset of the leaderboard + assertThat(leaderboard.getRank(new HashSet<>(Arrays.asList(1, 2, 3, 4)), null)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 0), tuple(2, 1), tuple(3, 2))); + } + + @Test + public void lengthHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.length()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(LengthResponse.Success.class)) + .satisfies(resp -> assertThat(resp.length()).isEqualTo(0)); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + assertThat(leaderboard.length()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(LengthResponse.Success.class)) + .satisfies(resp -> assertThat(resp.length()).isEqualTo(3)); + } + + @Test + public void removeElementsHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).hasSize(3); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(1, 2, 3); + }); + + assertThat(leaderboard.removeElements(Collections.singleton(1))) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(RemoveElementsResponse.Success.class); + + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).hasSize(2); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2, 3); + }); + + assertThat(leaderboard.removeElements(Collections.singleton(99999))) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(RemoveElementsResponse.Success.class); + + assertThat(leaderboard.fetchByRank(0, 10, SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> { + final List scoredElements = resp.elementsList(); + assertThat(scoredElements).hasSize(2); + assertThat(scoredElements).map(LeaderboardElement::getId).containsExactly(2, 3); + }); + } + + @Test + public void deleteHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(1, 1.0); + elements.put(2, 2.0); + elements.put(3, 3.0); + + assertThat(leaderboard.delete()) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DeleteResponse.Success.class); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + assertThat(leaderboard.length()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(LengthResponse.Success.class)) + .satisfies(resp -> assertThat(resp.length()).isEqualTo(3)); + + assertThat(leaderboard.delete()) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(DeleteResponse.Success.class); + + assertThat(leaderboard.length()) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(LengthResponse.Success.class)) + .satisfies(resp -> assertThat(resp.length()).isEqualTo(0)); + } + + @Test + public void getCompetitionRankHappyPath() { + final String leaderboardName = randomString("leaderboard"); + final ILeaderboard leaderboard = + leaderboardClientApiKeyV2.leaderboard(cacheName, leaderboardName); + + final Map elements = new HashMap<>(); + elements.put(0, 20.0); + elements.put(1, 10.0); + elements.put(2, 10.0); + elements.put(3, 5.0); + + assertThat(leaderboard.upsert(elements)) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(UpsertResponse.Success.class); + + // descending + assertThat(leaderboard.getCompetitionRank(elements.keySet())) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(0, 0), tuple(1, 1), tuple(2, 1), tuple(3, 3))); + + // ascending + assertThat(leaderboard.getCompetitionRank(elements.keySet(), SortOrder.ASCENDING)) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(0, 3), tuple(1, 1), tuple(2, 1), tuple(3, 0))); + + // ids are a subset of the leaderboard + assertThat(leaderboard.getCompetitionRank(new HashSet<>(Arrays.asList(1, 2)))) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 1), tuple(2, 1))); + + // ids are a superset of the leaderboard + assertThat(leaderboard.getCompetitionRank(new HashSet<>(Arrays.asList(1, 2, 3, 4)))) + .succeedsWithin(FIVE_SECONDS) + .asInstanceOf(InstanceOfAssertFactories.type(FetchResponse.Success.class)) + .satisfies( + resp -> + assertThat(resp.elementsList()) + .extracting("id", "rank") + .containsExactly(tuple(1, 1), tuple(2, 1), tuple(3, 3))); + } +} diff --git a/momento-sdk/src/intTest/java/momento/sdk/topics/TopicClientTestApiKeyV2.java b/momento-sdk/src/intTest/java/momento/sdk/topics/TopicClientTestApiKeyV2.java new file mode 100644 index 00000000..13744405 --- /dev/null +++ b/momento-sdk/src/intTest/java/momento/sdk/topics/TopicClientTestApiKeyV2.java @@ -0,0 +1,131 @@ +package momento.sdk.topics; + +import static momento.sdk.TestUtils.randomString; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Semaphore; +import momento.sdk.ISubscriptionCallbacks; +import momento.sdk.TopicClient; +import momento.sdk.cache.BaseCacheTestClass; +import momento.sdk.config.TopicConfigurations; +import momento.sdk.responses.topic.TopicMessage; +import momento.sdk.responses.topic.TopicPublishResponse; +import momento.sdk.responses.topic.TopicSubscribeResponse; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +public class TopicClientTestApiKeyV2 extends BaseCacheTestClass { + + private static TopicClient topicClient; + + @BeforeAll + static void setupAll() { + topicClient = + TopicClient.builder(credentialProviderApiKeyV2, TopicConfigurations.Laptop.latest()) + .build(); + } + + @AfterAll + static void teardownAll() { + topicClient.close(); + } + + private ISubscriptionCallbacks callbacks() { + return new ISubscriptionCallbacks() { + @Override + public void onItem(TopicMessage message) {} + + @Override + public void onCompleted() {} + + @Override + public void onError(Throwable t) {} + }; + } + + private ISubscriptionCallbacks callbacks( + Semaphore onItemSemaphore, List receivedMessages) { + return new ISubscriptionCallbacks() { + @Override + public void onItem(TopicMessage message) { + receivedMessages.add(message); + onItemSemaphore.release(); + } + + @Override + public void onCompleted() {} + + @Override + public void onError(Throwable t) {} + }; + } + + @Test + @Timeout(10) + public void topicPublishSubscribe_ByteArray_HappyPath() throws InterruptedException { + final String topicName = randomString(); + final byte[] value = new byte[] {0x00}; + + final Semaphore onItemSemaphore = new Semaphore(0); + final List receivedMessages = new ArrayList<>(); + final ISubscriptionCallbacks callbacks = callbacks(onItemSemaphore, receivedMessages); + + final TopicSubscribeResponse subscribeResponse = + topicClient.subscribe(cacheName, topicName, callbacks).join(); + assertThat(subscribeResponse).isInstanceOf(TopicSubscribeResponse.Subscription.class); + + try { + final CompletableFuture publishFuture = + topicClient.publish(cacheName, topicName, value); + onItemSemaphore.acquire(); + + assertThat(publishFuture) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(TopicPublishResponse.Success.class); + + assertThat(receivedMessages) + .filteredOn(tm -> tm instanceof TopicMessage.Binary) + .map(tm -> ((TopicMessage.Binary) tm).getValue()) + .containsOnly(value); + } finally { + ((TopicSubscribeResponse.Subscription) subscribeResponse).unsubscribe(); + } + } + + @Test + @Timeout(10) + public void topicPublishSubscribe_String_HappyPath() throws InterruptedException { + final String topicName = randomString(); + final String value = "test-value"; + + final Semaphore onItemSemaphore = new Semaphore(0); + final List receivedMessages = new ArrayList<>(); + final ISubscriptionCallbacks callbacks = callbacks(onItemSemaphore, receivedMessages); + + final TopicSubscribeResponse subscribeResponse = + topicClient.subscribe(cacheName, topicName, callbacks).join(); + assertThat(subscribeResponse).isInstanceOf(TopicSubscribeResponse.Subscription.class); + + try { + final CompletableFuture publishFuture = + topicClient.publish(cacheName, topicName, value); + onItemSemaphore.acquire(); + + assertThat(publishFuture) + .succeedsWithin(FIVE_SECONDS) + .isInstanceOf(TopicPublishResponse.Success.class); + + assertThat(receivedMessages) + .filteredOn(tm -> tm instanceof TopicMessage.Text) + .map(tm -> ((TopicMessage.Text) tm).getValue()) + .containsOnly(value); + } finally { + ((TopicSubscribeResponse.Subscription) subscribeResponse).unsubscribe(); + } + } +} From fe9cb3ecc0d23d6a0edb158cae1e098d7771be7d Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 15:36:45 -0800 Subject: [PATCH 4/9] ci: new env vars --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac028609..6d9cbb6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,11 +4,14 @@ on: pull_request: branches: [ main ] +env: + V1_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} + MOMENTO_API_KEY: ${{ secrets.ALPHA_API_KEY_V2 }} + MOMENTO_ENDPOINT: "cell-alpha-dev.preprod.a.momentohq.com" + jobs: build: runs-on: ubuntu-latest - env: - MOMENTO_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} steps: - name: Checkout project @@ -53,8 +56,6 @@ jobs: build-examples: runs-on: ubuntu-latest - env: - MOMENTO_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} steps: - name: Checkout project From 53d556811aa226ba43715642a495d315b48abea5 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 15:52:59 -0800 Subject: [PATCH 5/9] missed some examples, add docs snippets --- .../example/doc_examples/CheatSheet.java | 3 +- .../doc_examples/DocExamplesJavaAPIs.java | 31 +++++++++++++++++-- .../example/doc_examples/ReadmeExample.java | 3 +- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/examples/cache/src/main/java/momento/client/example/doc_examples/CheatSheet.java b/examples/cache/src/main/java/momento/client/example/doc_examples/CheatSheet.java index a1ae87e1..da5d2e62 100644 --- a/examples/cache/src/main/java/momento/client/example/doc_examples/CheatSheet.java +++ b/examples/cache/src/main/java/momento/client/example/doc_examples/CheatSheet.java @@ -6,10 +6,11 @@ import momento.sdk.config.Configurations; public class CheatSheet { + public static void main(String[] args) { try (final CacheClient cacheClient = CacheClient.create( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), + CredentialProvider.fromEnvVarV2(), Configurations.Laptop.v1(), Duration.ofSeconds(60) /* defaultTTL for your cache items*/, Duration.ofSeconds(10) /* eagerConnectionTimeout, default is 30 seconds */)) { diff --git a/examples/cache/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java b/examples/cache/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java index eb5c0676..af742e1d 100644 --- a/examples/cache/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java +++ b/examples/cache/src/main/java/momento/client/example/doc_examples/DocExamplesJavaAPIs.java @@ -25,12 +25,19 @@ public class DocExamplesJavaAPIs { + "2lZWFZrSWpvaUlpd2ljM1ZpSWpvaWFuSnZZMnRsZEVCbGVHRnRjR3hsTG1OdmJTSjkuOEl5OHE4NExzci1EM1lDb19IUDRkLXhqSGRUOFVDSX" + "V2QVljeGhGTXl6OCIsICJlbmRwb2ludCI6ICJ0ZXN0Lm1vbWVudG9ocS5jb20ifQo="; + public static final String FAKE_V2_API_KEY = + "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0IjoiZyIsImp0aSI6InNvbWUtaWQifQ.GMr9nA6HE0ttB6llXct_2Sg5-fOKGFbJCdACZFgNbN1fhT6OPg_hVc8ThGzBrWC_RlsBpLA1nzqK3SOJDXYxAw"; + public static String retrieveAuthTokenFromYourSecretsManager() { return FAKE_V1_API_KEY; } + public static String retrieveApiKeyV2FromYourSecretsManager() { + return FAKE_V2_API_KEY; + } + public static void example_API_CredentialProviderFromEnvVar() { - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"); + CredentialProvider.fromEnvVar("V1_API_KEY"); } public static void example_API_CredentialProviderFromString() { @@ -38,6 +45,21 @@ public static void example_API_CredentialProviderFromString() { CredentialProvider.fromString(authToken); } + public static void example_API_CredentialProviderFromEnvVarV2() { + CredentialProvider.fromEnvVarV2(); + } + + public static void example_API_CredentialProviderFromApiKeyV2() { + final String apiKey = retrieveApiKeyV2FromYourSecretsManager(); + final String endpoint = "cell-4-us-west-2-1.prod.a.momentohq.com"; + CredentialProvider.fromApiKeyV2(apiKey, endpoint); + } + + public static void example_API_CredentialProviderFromDispoableToken() { + final String authToken = retrieveAuthTokenFromYourSecretsManager(); + CredentialProvider.fromDisposableToken(authToken); + } + public static void example_API_ConfigurationLaptop() { Configurations.Laptop.v1(); } @@ -54,7 +76,7 @@ public static void example_API_ConfigurationLowLatency() { public static void example_API_InstantiateCacheClient() { try (CacheClient cacheClient = CacheClient.create( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), + CredentialProvider.fromEnvVarV2(), Configurations.Laptop.v1(), Duration.ofSeconds(60))) { // ... @@ -210,6 +232,9 @@ public static void example_API_SetIfNotExists(CacheClient cacheClient) { public static void main(String[] args) { example_API_CredentialProviderFromEnvVar(); example_API_CredentialProviderFromString(); + example_API_CredentialProviderFromEnvVarV2(); + example_API_CredentialProviderFromApiKeyV2(); + example_API_CredentialProviderFromDispoableToken(); example_API_ConfigurationLaptop(); example_API_ConfigurationInRegionLatest(); example_API_ConfigurationLowLatency(); @@ -217,7 +242,7 @@ public static void main(String[] args) { example_API_InstantiateCacheClient(); try (final CacheClient cacheClient = CacheClient.builder( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), + CredentialProvider.fromEnvVarV2(), Configurations.Laptop.v1(), Duration.ofSeconds(60)) .build()) { diff --git a/examples/cache/src/main/java/momento/client/example/doc_examples/ReadmeExample.java b/examples/cache/src/main/java/momento/client/example/doc_examples/ReadmeExample.java index 40e9f7aa..ac1bde1c 100644 --- a/examples/cache/src/main/java/momento/client/example/doc_examples/ReadmeExample.java +++ b/examples/cache/src/main/java/momento/client/example/doc_examples/ReadmeExample.java @@ -7,10 +7,11 @@ import momento.sdk.responses.cache.GetResponse; public class ReadmeExample { + public static void main(String[] args) { try (final CacheClient cacheClient = CacheClient.create( - CredentialProvider.fromEnvVar("MOMENTO_API_KEY"), + CredentialProvider.fromEnvVarV2(), Configurations.Laptop.v1(), Duration.ofSeconds(60))) { final String cacheName = "cache"; From f87cd02324d6c6a6ec63e9ce56eedf619998ce37 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 15:54:57 -0800 Subject: [PATCH 6/9] fix test --- .../test/java/momento/sdk/auth/V2CredentialProviderTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/momento-sdk/src/test/java/momento/sdk/auth/V2CredentialProviderTest.java b/momento-sdk/src/test/java/momento/sdk/auth/V2CredentialProviderTest.java index e3ee6e2b..444ce2a2 100644 --- a/momento-sdk/src/test/java/momento/sdk/auth/V2CredentialProviderTest.java +++ b/momento-sdk/src/test/java/momento/sdk/auth/V2CredentialProviderTest.java @@ -55,7 +55,8 @@ void fromApiKeyV2EmptyArguments() { void fromEnvVarV2NotSetDefaultEnvVars() { // either env var may be checked first assertThatExceptionOfType(InvalidArgumentException.class) - .isThrownBy(() -> CredentialProvider.fromEnvVarV2()) + .isThrownBy( + () -> CredentialProvider.fromEnvVarV2("NONEXISTENT_ENV_VAR", "NONEXISTENT_ENDPOINT")) .withMessageContaining("must be set"); } From 46e18a9efe36dc2045ff6962e5e94d0872049333 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 16:15:43 -0800 Subject: [PATCH 7/9] actually use the v2 api key cache client --- .../momento/sdk/cache/CacheTestApiKeyV2.java | 308 +++++++++--------- 1 file changed, 162 insertions(+), 146 deletions(-) diff --git a/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java b/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java index 8254cf4b..d70dda08 100644 --- a/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java +++ b/momento-sdk/src/intTest/java/momento/sdk/cache/CacheTestApiKeyV2.java @@ -66,12 +66,12 @@ final class CacheTestApiKeyV2 extends BaseCacheTestClass { public void listsCachesHappyPath() { final String newCache = randomString("name"); - assertThat(cacheClient.createCache(newCache)) + assertThat(cacheClientApiKeyV2.createCache(newCache)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(CacheCreateResponse.Success.class); try { - assertThat(cacheClient.listCaches()) + assertThat(cacheClientApiKeyV2.listCaches()) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(CacheListResponse.Success.class)) .satisfies( @@ -79,7 +79,7 @@ public void listsCachesHappyPath() { assertThat(success.getCaches()).anyMatch(ci -> ci.name().equals(newCache))); } finally { // cleanup - assertThat(cacheClient.deleteCache(newCache)) + assertThat(cacheClientApiKeyV2.deleteCache(newCache)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(CacheDeleteResponse.Success.class); } @@ -89,21 +89,21 @@ public void listsCachesHappyPath() { public void createDeleteCache_HappyPath() { final String newCache = randomString("java-v2"); - assertThat(cacheClient.createCache(newCache)) + assertThat(cacheClientApiKeyV2.createCache(newCache)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(CacheCreateResponse.Success.class); - assertThat(cacheClient.createCache(newCache)) + assertThat(cacheClientApiKeyV2.createCache(newCache)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(CacheCreateResponse.Error.class)) .satisfies( error -> assertThat(error).hasCauseInstanceOf(CacheAlreadyExistsException.class)); - assertThat(cacheClient.deleteCache(newCache)) + assertThat(cacheClientApiKeyV2.deleteCache(newCache)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(CacheDeleteResponse.Success.class); - assertThat(cacheClient.deleteCache(newCache)) + assertThat(cacheClientApiKeyV2.deleteCache(newCache)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(CacheDeleteResponse.Error.class)) .satisfies(error -> assertThat(error).hasCauseInstanceOf(CacheNotFoundException.class)); @@ -117,24 +117,24 @@ public void shouldFlushCacheContents() { final Duration ttl1Hour = Duration.ofHours(1); try { - CacheCreateResponse response = cacheClient.createCache(cacheToFlush).join(); + CacheCreateResponse response = cacheClientApiKeyV2.createCache(cacheToFlush).join(); assertThat(response).isInstanceOf(CacheCreateResponse.Success.class); - assertThat(cacheClient.set(cacheName, key, value, ttl1Hour)) + assertThat(cacheClientApiKeyV2.set(cacheName, key, value, ttl1Hour)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetResponse.Success.class)) .satisfies(success -> assertThat(success.value()).isEqualTo(value)); // Execute Flush - assertThat(cacheClient.flushCache(cacheName)) + assertThat(cacheClientApiKeyV2.flushCache(cacheName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(CacheFlushResponse.Success.class); // Verify that previously set key is now a MISS - assertThat(cacheClient.get(cacheName, key)) + assertThat(cacheClientApiKeyV2.get(cacheName, key)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(GetResponse.Miss.class); } finally { - cacheClient.deleteCache(cacheToFlush).join(); + cacheClientApiKeyV2.deleteCache(cacheToFlush).join(); } } @@ -145,24 +145,25 @@ public void createCacheGetSetDeleteValuesAndDeleteCache() { final String key = randomString("key"); final String value = randomString("value"); - cacheClient.createCache(alternateCacheName).join(); + cacheClientApiKeyV2.createCache(alternateCacheName).join(); try { - cacheClient.set(cacheName, key, value).join(); + cacheClientApiKeyV2.set(cacheName, key, value).join(); - final GetResponse getResponse = cacheClient.get(cacheName, key).join(); + final GetResponse getResponse = cacheClientApiKeyV2.get(cacheName, key).join(); assertThat(getResponse).isInstanceOf(GetResponse.Hit.class); assertThat(((GetResponse.Hit) getResponse).valueString()).isEqualTo(value); - final DeleteResponse deleteResponse = cacheClient.delete(cacheName, key).join(); + final DeleteResponse deleteResponse = cacheClientApiKeyV2.delete(cacheName, key).join(); assertThat(deleteResponse).isInstanceOf(DeleteResponse.Success.class); - final GetResponse getAfterDeleteResponse = cacheClient.get(cacheName, key).join(); + final GetResponse getAfterDeleteResponse = cacheClientApiKeyV2.get(cacheName, key).join(); assertThat(getAfterDeleteResponse).isInstanceOf(GetResponse.Miss.class); - final GetResponse getForKeyInSomeOtherCache = cacheClient.get(alternateCacheName, key).join(); + final GetResponse getForKeyInSomeOtherCache = + cacheClientApiKeyV2.get(alternateCacheName, key).join(); assertThat(getForKeyInSomeOtherCache).isInstanceOf(GetResponse.Miss.class); } finally { - cacheClient.deleteCache(alternateCacheName).join(); + cacheClientApiKeyV2.deleteCache(alternateCacheName).join(); } } @@ -172,14 +173,14 @@ public void shouldSetStringValueToStringKeyWhenKeyNotExistsWithTtl() { final String value = randomString(); SetIfNotExistsResponse setIfNotExistsResponse = - cacheClient.setIfNotExists(cacheName, key, value, DEFAULT_TTL_SECONDS).join(); + cacheClientApiKeyV2.setIfNotExists(cacheName, key, value, DEFAULT_TTL_SECONDS).join(); assertThat(setIfNotExistsResponse).isInstanceOf(SetIfNotExistsResponse.Stored.class); assertThat(((SetIfNotExistsResponse.Stored) setIfNotExistsResponse).keyString()).isEqualTo(key); assertThat(((SetIfNotExistsResponse.Stored) setIfNotExistsResponse).valueString()) .isEqualTo(value); - GetResponse getResponse = cacheClient.get(cacheName, key).join(); + GetResponse getResponse = cacheClientApiKeyV2.get(cacheName, key).join(); assertThat(getResponse).isInstanceOf(GetResponse.Hit.class); assertThat(((GetResponse.Hit) getResponse).valueString()).isEqualTo(value); } @@ -191,7 +192,7 @@ public void getBatchSetBatchHappyPath() { items.put("key2", "val2"); items.put("key3", "val3"); final SetBatchResponse setBatchResponse = - cacheClient.setBatch(cacheName, items, Duration.ofMinutes(1)).join(); + cacheClientApiKeyV2.setBatch(cacheName, items, Duration.ofMinutes(1)).join(); assertThat(setBatchResponse).isInstanceOf(SetBatchResponse.Success.class); for (SetResponse setResponse : ((SetBatchResponse.Success) setBatchResponse).results().values()) { @@ -199,7 +200,7 @@ public void getBatchSetBatchHappyPath() { } final GetBatchResponse getBatchResponse = - cacheClient.getBatch(cacheName, items.keySet()).join(); + cacheClientApiKeyV2.getBatch(cacheName, items.keySet()).join(); assertThat(getBatchResponse).isInstanceOf(GetBatchResponse.Success.class); assertThat(((GetBatchResponse.Success) getBatchResponse).valueMapStringString()) @@ -212,11 +213,12 @@ public void shouldUpdateTTLAndGetItWithStringKey() { final String key = randomString(); // set a key with default ttl - SetResponse setResponse = cacheClient.set(cacheName, key, "value", DEFAULT_TTL_SECONDS).join(); + SetResponse setResponse = + cacheClientApiKeyV2.set(cacheName, key, "value", DEFAULT_TTL_SECONDS).join(); assertThat(setResponse).isInstanceOf(SetResponse.Success.class); - ItemGetTtlResponse itemGetTtlResponse = cacheClient.itemGetTtl(cacheName, key).join(); + ItemGetTtlResponse itemGetTtlResponse = cacheClientApiKeyV2.itemGetTtl(cacheName, key).join(); // retrieved ttl should work and less than default ttl assertThat(itemGetTtlResponse).isInstanceOf(ItemGetTtlResponse.Hit.class); @@ -225,11 +227,12 @@ public void shouldUpdateTTLAndGetItWithStringKey() { // update ttl to 300 seconds Duration updatedTTL = Duration.of(300, ChronoUnit.SECONDS); - UpdateTtlResponse updateTtlResponse = cacheClient.updateTtl(cacheName, key, updatedTTL).join(); + UpdateTtlResponse updateTtlResponse = + cacheClientApiKeyV2.updateTtl(cacheName, key, updatedTTL).join(); assertThat(updateTtlResponse).isInstanceOf(UpdateTtlResponse.Set.class); - itemGetTtlResponse = cacheClient.itemGetTtl(cacheName, key).join(); + itemGetTtlResponse = cacheClientApiKeyV2.itemGetTtl(cacheName, key).join(); // assert that the updated ttl is less than 300 seconds but more than 300 - epsilon (taken as 60 // to reduce flakiness) @@ -245,24 +248,25 @@ public void shouldReturnCacheIncrementedValuesWithStringField() { final String field = randomString(); IncrementResponse incrementResponse = - cacheClient.increment(cacheName, field, 1, DEFAULT_TTL_SECONDS).join(); + cacheClientApiKeyV2.increment(cacheName, field, 1, DEFAULT_TTL_SECONDS).join(); assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(1); // increment with ttl specified - incrementResponse = cacheClient.increment(cacheName, field, 50, DEFAULT_TTL_SECONDS).join(); + incrementResponse = + cacheClientApiKeyV2.increment(cacheName, field, 50, DEFAULT_TTL_SECONDS).join(); assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(51); // increment without ttl specified - incrementResponse = cacheClient.increment(cacheName, field, -1051).join(); + incrementResponse = cacheClientApiKeyV2.increment(cacheName, field, -1051).join(); assertThat(incrementResponse).isInstanceOf(IncrementResponse.Success.class); assertThat(((IncrementResponse.Success) incrementResponse).valueNumber()).isEqualTo(-1000); - GetResponse getResp = cacheClient.get(cacheName, field).join(); + GetResponse getResp = cacheClientApiKeyV2.get(cacheName, field).join(); assertThat(getResp).isInstanceOf(GetResponse.Hit.class); assertThat(((GetResponse.Hit) getResp).valueString()).isEqualTo("-1000"); } @@ -274,12 +278,12 @@ public void dictionarySetFieldAndDictionaryFetchAndHappyPath() { // Set String key, String Value assertThat( - cacheClient.dictionarySetField( + cacheClientApiKeyV2.dictionarySetField( cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionarySetFieldResponse.Success.class); - assertThat(cacheClient.dictionaryFetch(cacheName, dictionaryName)) + assertThat(cacheClientApiKeyV2.dictionaryFetch(cacheName, dictionaryName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryFetchResponse.Hit.class)) .satisfies( @@ -287,12 +291,12 @@ public void dictionarySetFieldAndDictionaryFetchAndHappyPath() { // Set String key, ByteArray Value assertThat( - cacheClient.dictionarySetField( + cacheClientApiKeyV2.dictionarySetField( cacheName, dictionaryName, "c", "d".getBytes(), CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionarySetFieldResponse.Success.class); - assertThat(cacheClient.dictionaryFetch(cacheName, dictionaryName)) + assertThat(cacheClientApiKeyV2.dictionaryFetch(cacheName, dictionaryName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryFetchResponse.Hit.class)) .satisfies( @@ -308,12 +312,12 @@ public void dictionaryGetFieldHappyPath() { // Get the value as a string assertThat( - cacheClient.dictionarySetField( + cacheClientApiKeyV2.dictionarySetField( cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionarySetFieldResponse.Success.class); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) .satisfies( @@ -324,12 +328,12 @@ public void dictionaryGetFieldHappyPath() { // Get the value as a byte array assertThat( - cacheClient.dictionarySetField( + cacheClientApiKeyV2.dictionarySetField( cacheName, dictionaryName, "c", "d".getBytes(), CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionarySetFieldResponse.Success.class); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "c")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "c")) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) .satisfies( @@ -344,13 +348,13 @@ public void dictionaryIncrementStringFieldHappyPath() { final String dictionaryName = randomString(); // Increment with ttl - assertThat(cacheClient.dictionaryIncrement(cacheName, dictionaryName, "a", 1)) + assertThat(cacheClientApiKeyV2.dictionaryIncrement(cacheName, dictionaryName, "a", 1)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) .satisfies(success -> assertThat(success.value()).isEqualTo(1)); assertThat( - cacheClient.dictionaryIncrement( + cacheClientApiKeyV2.dictionaryIncrement( cacheName, dictionaryName, "a", 41, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) @@ -358,13 +362,13 @@ public void dictionaryIncrementStringFieldHappyPath() { // Increment without ttl assertThat( - cacheClient.dictionaryIncrement( + cacheClientApiKeyV2.dictionaryIncrement( cacheName, dictionaryName, "a", -1042, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryIncrementResponse.Success.class)) .satisfies(success -> assertThat(success.value()).isEqualTo(-1000)); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) .satisfies( @@ -378,17 +382,17 @@ public void dictionaryIncrementStringFieldHappyPath() { public void dictionaryRemoveFieldStringHappyPath() { final String dictionaryName = randomString(); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionaryGetFieldResponse.Miss.class); assertThat( - cacheClient.dictionarySetField( + cacheClientApiKeyV2.dictionarySetField( cacheName, dictionaryName, "a", "b", CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionarySetFieldResponse.Success.class); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(DictionaryGetFieldResponse.Hit.class)) .satisfies( @@ -397,11 +401,11 @@ public void dictionaryRemoveFieldStringHappyPath() { assertThat(hit.valueString()).isEqualTo("b"); }); - assertThat(cacheClient.dictionaryRemoveField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryRemoveField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionaryRemoveFieldResponse.Success.class); - assertThat(cacheClient.dictionaryGetField(cacheName, dictionaryName, "a")) + assertThat(cacheClientApiKeyV2.dictionaryGetField(cacheName, dictionaryName, "a")) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(DictionaryGetFieldResponse.Miss.class); } @@ -413,29 +417,29 @@ public void listConcatenateBackStringHappyPath() { final List oldValues = Arrays.asList("val1", "val2", "val3"); final List newValues = Arrays.asList("val4", "val5", "val6"); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listConcatenateBack( + cacheClientApiKeyV2.listConcatenateBack( cacheName, listName, oldValues, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateBackResponse.Success.class); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( hit -> assertThat(hit.valueListString()).hasSize(3).containsExactlyElementsOf(oldValues)); - assertThat(cacheClient.listConcatenateBack(cacheName, listName, newValues)) + assertThat(cacheClientApiKeyV2.listConcatenateBack(cacheName, listName, newValues)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateBackResponse.Success.class); final Iterable expectedList = Iterables.concat(oldValues, newValues); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -445,12 +449,12 @@ public void listConcatenateBackStringHappyPath() { .containsExactlyElementsOf(expectedList)); // Add the original values again and truncate the list to 6 items - assertThat(cacheClient.listConcatenateBack(cacheName, listName, oldValues, 6)) + assertThat(cacheClientApiKeyV2.listConcatenateBack(cacheName, listName, oldValues, 6)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateBackResponse.Success.class); final Iterable newExpectedList = Iterables.concat(newValues, oldValues); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -470,7 +474,8 @@ public void shouldFetchAllValuesWhenListFetchWithPositiveStartEndIndices() { cacheName, listName, values, null, CollectionTtl.of(DEFAULT_TTL_SECONDS)) .join(); - ListFetchResponse listFetchResponse = cacheClient.listFetch(cacheName, listName, 1, 3).join(); + ListFetchResponse listFetchResponse = + cacheClientApiKeyV2.listFetch(cacheName, listName, 1, 3).join(); assertThat(listFetchResponse).isInstanceOf(ListFetchResponse.Hit.class); @@ -485,29 +490,29 @@ public void listConcatenateFrontStringHappyPath() { final List oldValues = Arrays.asList("val1", "val2", "val3"); final List newValues = Arrays.asList("val4", "val5", "val6"); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listConcatenateFront( + cacheClientApiKeyV2.listConcatenateFront( cacheName, listName, oldValues, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( hit -> assertThat(hit.valueListString()).hasSize(3).containsExactlyElementsOf(oldValues)); - assertThat(cacheClient.listConcatenateFront(cacheName, listName, newValues)) + assertThat(cacheClientApiKeyV2.listConcatenateFront(cacheName, listName, newValues)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); final Iterable expectedList = Iterables.concat(newValues, oldValues); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -517,12 +522,12 @@ public void listConcatenateFrontStringHappyPath() { .containsExactlyElementsOf(expectedList)); // Add the original values again and truncate the list to 6 items - assertThat(cacheClient.listConcatenateFront(cacheName, listName, oldValues, 6)) + assertThat(cacheClientApiKeyV2.listConcatenateFront(cacheName, listName, oldValues, 6)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); final Iterable newExpectedList = Iterables.concat(oldValues, newValues); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -539,30 +544,30 @@ public void listLengthHappyPath() { final List byteArrayValues = Arrays.asList("val1".getBytes(), "val2".getBytes(), "val3".getBytes()); - assertThat(cacheClient.listLength(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listLength(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListLengthResponse.Miss.class); // add string values to list assertThat( - cacheClient.listConcatenateFront( + cacheClientApiKeyV2.listConcatenateFront( cacheName, listName, stringValues, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); - assertThat(cacheClient.listLength(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listLength(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListLengthResponse.Hit.class)) .satisfies(hit -> assertThat(hit.getListLength()).isEqualTo(stringValues.size())); // add byte array values to list assertThat( - cacheClient.listConcatenateFrontByteArray( + cacheClientApiKeyV2.listConcatenateFrontByteArray( cacheName, listName, byteArrayValues, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); - assertThat(cacheClient.listLength(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listLength(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListLengthResponse.Hit.class)) .satisfies( @@ -576,24 +581,24 @@ public void listPopBackHappyPath() { final String listName = randomString(); List values = Arrays.asList("val1", "val2", "val3"); - assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName, null, null)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listConcatenateBack( + cacheClientApiKeyV2.listConcatenateBack( cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateBackResponse.Success.class); // Pop the value as string from back of the list - assertThat(cacheClient.listPopBack(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listPopBack(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListPopBackResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueString()).isEqualTo("val3")); // Pop the value as byte array from the back of the new list - assertThat(cacheClient.listPopBack(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listPopBack(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListPopBackResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueByteArray()).isEqualTo("val2".getBytes())); @@ -604,24 +609,24 @@ public void listPopFrontHappyPath() { final String listName = randomString(); List values = Arrays.asList("val1", "val2", "val3"); - assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName, null, null)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listConcatenateBack( + cacheClientApiKeyV2.listConcatenateBack( cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateBackResponse.Success.class); // Pop the value as string from front of the list - assertThat(cacheClient.listPopFront(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listPopFront(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListPopFrontResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueString()).isEqualTo("val1")); // Pop the value as byte array from the front of the new list - assertThat(cacheClient.listPopFront(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listPopFront(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListPopFrontResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueByteArray()).isEqualTo("val2".getBytes())); @@ -633,28 +638,28 @@ public void listPushBackStringHappyPath() { final String oldValue = "val1"; final String newValue = "val2"; - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listPushBack( + cacheClientApiKeyV2.listPushBack( cacheName, listName, oldValue, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushBackResponse.Success.class); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueListString()).hasSize(1).containsOnly(oldValue)); // Add the same value - assertThat(cacheClient.listPushBack(cacheName, listName, oldValue)) + assertThat(cacheClientApiKeyV2.listPushBack(cacheName, listName, oldValue)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushBackResponse.Success.class); final List expectedList = Arrays.asList(oldValue, oldValue); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -664,12 +669,12 @@ public void listPushBackStringHappyPath() { .containsExactlyElementsOf(expectedList)); // Add a new value and truncate the list to 2 items - assertThat(cacheClient.listPushBack(cacheName, listName, newValue, 2)) + assertThat(cacheClientApiKeyV2.listPushBack(cacheName, listName, newValue, 2)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushBackResponse.Success.class); final List newExpectedList = Arrays.asList(oldValue, newValue); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -685,28 +690,28 @@ public void listPushFrontStringHappyPath() { final String oldValue = "val1"; final String newValue = "val2"; - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListFetchResponse.Miss.class); assertThat( - cacheClient.listPushFront( + cacheClientApiKeyV2.listPushFront( cacheName, listName, oldValue, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushFrontResponse.Success.class); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueListString()).hasSize(1).containsOnly(oldValue)); // Add the same value - assertThat(cacheClient.listPushFront(cacheName, listName, oldValue)) + assertThat(cacheClientApiKeyV2.listPushFront(cacheName, listName, oldValue)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushFrontResponse.Success.class); final List expectedList = Arrays.asList(oldValue, oldValue); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -716,12 +721,12 @@ public void listPushFrontStringHappyPath() { .containsExactlyElementsOf(expectedList)); // Add a new value and truncate the list to 2 items - assertThat(cacheClient.listPushFront(cacheName, listName, newValue, 2)) + assertThat(cacheClientApiKeyV2.listPushFront(cacheName, listName, newValue, 2)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListPushFrontResponse.Success.class); final List newExpectedList = Arrays.asList(newValue, oldValue); - assertThat(cacheClient.listFetch(cacheName, listName)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies( @@ -737,19 +742,19 @@ public void listRemoveValueStringHappyPath() { List values = Arrays.asList("val1", "val1", "val2", "val3", "val4"); assertThat( - cacheClient.listConcatenateFront( + cacheClientApiKeyV2.listConcatenateFront( cacheName, listName, values, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); // Remove value from list String removeValue = "val1"; - assertThat(cacheClient.listRemoveValue(cacheName, listName, removeValue)) + assertThat(cacheClientApiKeyV2.listRemoveValue(cacheName, listName, removeValue)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListRemoveValueResponse.Success.class); List expectedList = Arrays.asList("val2", "val3", "val4"); - assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName, null, null)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueListString()).hasSize(3).containsAll(expectedList)); @@ -761,22 +766,22 @@ public void shouldRetainAllValuesWhenListRetainWithPositiveStartEndIndices() { final List stringValues = Arrays.asList("val1", "val2", "val3", "val4"); assertThat( - cacheClient.listConcatenateFront( + cacheClientApiKeyV2.listConcatenateFront( cacheName, listName, stringValues, null, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListConcatenateFrontResponse.Success.class); - assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName, null, null)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueListString()).hasSize(4).containsAll(stringValues)); - assertThat(cacheClient.listRetain(cacheName, listName, 1, 3)) + assertThat(cacheClientApiKeyV2.listRetain(cacheName, listName, 1, 3)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(ListRetainResponse.Success.class); List expectedList = Arrays.asList("val2", "val3"); - assertThat(cacheClient.listFetch(cacheName, listName, null, null)) + assertThat(cacheClientApiKeyV2.listFetch(cacheName, listName, null, null)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(ListFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueListString()).hasSize(2).containsAll(expectedList)); @@ -789,33 +794,35 @@ public void setAddElementsStringHappyPath() { final Set firstSet = Sets.newHashSet("one", "two"); final Set secondSet = Sets.newHashSet("two", "three"); - assertThat(cacheClient.setAddElements(cacheName, setName, firstSet)) + assertThat(cacheClientApiKeyV2.setAddElements(cacheName, setName, firstSet)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetAddElementsResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(2).containsAll(firstSet)); // Try to add the same elements again assertThat( - cacheClient.setAddElements(cacheName, setName, firstSet, CollectionTtl.fromCacheTtl())) + cacheClientApiKeyV2.setAddElements( + cacheName, setName, firstSet, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetAddElementsResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(2).containsAll(firstSet)); // Add a set with one new and one overlapping element assertThat( - cacheClient.setAddElements(cacheName, setName, secondSet, CollectionTtl.fromCacheTtl())) + cacheClientApiKeyV2.setAddElements( + cacheName, setName, secondSet, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetAddElementsResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies( @@ -835,51 +842,52 @@ public void setRemoveElementStringHappyPath() { // Add some elements to a set assertThat( - cacheClient.setAddElements(cacheName, setName, elements, CollectionTtl.fromCacheTtl())) + cacheClientApiKeyV2.setAddElements( + cacheName, setName, elements, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetAddElementsResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies( hit -> assertThat(hit.valueSetString()).hasSize(2).containsOnly(element1, element2)); // Remove an element - assertThat(cacheClient.setRemoveElement(cacheName, setName, element1)) + assertThat(cacheClientApiKeyV2.setRemoveElement(cacheName, setName, element1)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetRemoveElementResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(1).containsOnly(element2)); // Try to remove the same element again - assertThat(cacheClient.setRemoveElement(cacheName, setName, element1)) + assertThat(cacheClientApiKeyV2.setRemoveElement(cacheName, setName, element1)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetRemoveElementResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SetFetchResponse.Hit.class)) .satisfies(hit -> assertThat(hit.valueSetString()).hasSize(1).containsOnly(element2)); // Remove the last element - assertThat(cacheClient.setRemoveElement(cacheName, setName, element2)) + assertThat(cacheClientApiKeyV2.setRemoveElement(cacheName, setName, element2)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetRemoveElementResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetFetchResponse.Miss.class); // Remove an element from the now non-existent set - assertThat(cacheClient.setRemoveElement(cacheName, setName, element2)) + assertThat(cacheClientApiKeyV2.setRemoveElement(cacheName, setName, element2)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetRemoveElementResponse.Success.class); - assertThat(cacheClient.setFetch(cacheName, setName)) + assertThat(cacheClientApiKeyV2.setFetch(cacheName, setName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SetFetchResponse.Miss.class); } @@ -891,17 +899,17 @@ public void sortedSetPutElementStringHappyPath() { final String value = "1"; final double score = 1.0; - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetFetchResponse.Miss.class); assertThat( - cacheClient.sortedSetPutElement( + cacheClientApiKeyV2.sortedSetPutElement( cacheName, sortedSetName, value, score, CollectionTtl.fromCacheTtl())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementResponse.Success.class); - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -928,17 +936,18 @@ public void sortedSetFetchByRankStringHappyPath() { elements.put(four, 2.0); elements.put(five, 1.5); - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetFetchResponse.Miss.class); - assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + assertThat(cacheClientApiKeyV2.sortedSetPutElements(cacheName, sortedSetName, elements)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementsResponse.Success.class); // Full set ascending, end index larger than set assertThat( - cacheClient.sortedSetFetchByRank(cacheName, sortedSetName, 0, 6, SortOrder.ASCENDING)) + cacheClientApiKeyV2.sortedSetFetchByRank( + cacheName, sortedSetName, 0, 6, SortOrder.ASCENDING)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -953,7 +962,8 @@ public void sortedSetFetchByRankStringHappyPath() { // Partial set descending assertThat( - cacheClient.sortedSetFetchByRank(cacheName, sortedSetName, 1, 4, SortOrder.DESCENDING)) + cacheClientApiKeyV2.sortedSetFetchByRank( + cacheName, sortedSetName, 1, 4, SortOrder.DESCENDING)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -983,17 +993,17 @@ public void sortedSetFetchByScoreStringHappyPath() { elements.put(four, 2.0); elements.put(five, 1.5); - assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByScore(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetFetchResponse.Miss.class); - assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + assertThat(cacheClientApiKeyV2.sortedSetPutElements(cacheName, sortedSetName, elements)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementsResponse.Success.class); // Full set ascending, end index larger than set assertThat( - cacheClient.sortedSetFetchByScore( + cacheClientApiKeyV2.sortedSetFetchByScore( cacheName, sortedSetName, 0.0, 9.9, SortOrder.ASCENDING)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) @@ -1012,7 +1022,7 @@ public void sortedSetFetchByScoreStringHappyPath() { // Partial set descending assertThat( - cacheClient.sortedSetFetchByScore( + cacheClientApiKeyV2.sortedSetFetchByScore( cacheName, sortedSetName, 0.2, 1.9, SortOrder.DESCENDING, 0, 99)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) @@ -1027,7 +1037,9 @@ public void sortedSetFetchByScoreStringHappyPath() { }); // Partial set limited by offset and count - assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName, null, null, null, 1, 3)) + assertThat( + cacheClientApiKeyV2.sortedSetFetchByScore( + cacheName, sortedSetName, null, null, null, 1, 3)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -1041,7 +1053,7 @@ public void sortedSetFetchByScoreStringHappyPath() { }); // Full set ascending - assertThat(cacheClient.sortedSetFetchByScore(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByScore(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -1061,31 +1073,33 @@ public void sortedSetGetRankStringHappyPath() { final String one = "1"; final String two = "2"; - assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + assertThat(cacheClientApiKeyV2.sortedSetGetRank(cacheName, sortedSetName, one, null)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetGetRankResponse.Miss.class); - assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) + assertThat(cacheClientApiKeyV2.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementResponse.Success.class); - assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + assertThat(cacheClientApiKeyV2.sortedSetGetRank(cacheName, sortedSetName, one, null)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) .satisfies(hit -> assertThat(hit.rank()).isEqualTo(0)); // Add another element that changes the rank of the first one - assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) + assertThat(cacheClientApiKeyV2.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementResponse.Success.class); - assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, null)) + assertThat(cacheClientApiKeyV2.sortedSetGetRank(cacheName, sortedSetName, one, null)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) .satisfies(hit -> assertThat(hit.rank()).isEqualTo(1)); // Check the descending rank - assertThat(cacheClient.sortedSetGetRank(cacheName, sortedSetName, one, SortOrder.DESCENDING)) + assertThat( + cacheClientApiKeyV2.sortedSetGetRank( + cacheName, sortedSetName, one, SortOrder.DESCENDING)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetRankResponse.Hit.class)) .satisfies(hit -> assertThat(hit.rank()).isEqualTo(0)); @@ -1097,25 +1111,25 @@ public void sortedSetGetScoreStringHappyPath() { final String one = "1"; final String two = "2"; - assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + assertThat(cacheClientApiKeyV2.sortedSetGetScore(cacheName, sortedSetName, one)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetGetScoreResponse.Miss.class); - assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) + assertThat(cacheClientApiKeyV2.sortedSetPutElement(cacheName, sortedSetName, one, 1.0)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementResponse.Success.class); - assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + assertThat(cacheClientApiKeyV2.sortedSetGetScore(cacheName, sortedSetName, one)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetScoreResponse.Hit.class)) .satisfies(hit -> assertThat(hit.score()).isEqualTo(1.0)); // Add another element that changes the rank of the first one - assertThat(cacheClient.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) + assertThat(cacheClientApiKeyV2.sortedSetPutElement(cacheName, sortedSetName, two, 0.5)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementResponse.Success.class); - assertThat(cacheClient.sortedSetGetScore(cacheName, sortedSetName, one)) + assertThat(cacheClientApiKeyV2.sortedSetGetScore(cacheName, sortedSetName, one)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetGetScoreResponse.Hit.class)) .satisfies(hit -> assertThat(hit.score()).isEqualTo(1.0)); @@ -1126,12 +1140,12 @@ public void sortedSetIncrementScoreStringHappyPath() { final String sortedSetName = randomString(); final String one = "1"; - assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, 1.0)) + assertThat(cacheClientApiKeyV2.sortedSetIncrementScore(cacheName, sortedSetName, one, 1.0)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) .satisfies(success -> assertThat(success.score()).isEqualTo(1.0)); - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -1141,12 +1155,12 @@ public void sortedSetIncrementScoreStringHappyPath() { .map(ScoredElement::getScore) .containsOnly(1.0)); - assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, 14.5)) + assertThat(cacheClientApiKeyV2.sortedSetIncrementScore(cacheName, sortedSetName, one, 14.5)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) .satisfies(success -> assertThat(success.score()).isEqualTo(15.5)); - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( @@ -1156,7 +1170,7 @@ public void sortedSetIncrementScoreStringHappyPath() { .map(ScoredElement::getScore) .containsOnly(15.5)); - assertThat(cacheClient.sortedSetIncrementScore(cacheName, sortedSetName, one, -115.5)) + assertThat(cacheClientApiKeyV2.sortedSetIncrementScore(cacheName, sortedSetName, one, -115.5)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetIncrementScoreResponse.Success.class)) .satisfies(success -> assertThat(success.score()).isEqualTo(-100)); @@ -1170,21 +1184,23 @@ public void sortedSetRemoveElementsStringHappyPath() { final String three = "3"; final Map elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0); - assertThat(cacheClient.sortedSetRemoveElements(cacheName, sortedSetName, elements.keySet())) + assertThat( + cacheClientApiKeyV2.sortedSetRemoveElements( + cacheName, sortedSetName, elements.keySet())) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetRemoveElementsResponse.Success.class); - assertThat(cacheClient.sortedSetPutElements(cacheName, sortedSetName, elements)) + assertThat(cacheClientApiKeyV2.sortedSetPutElements(cacheName, sortedSetName, elements)) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetPutElementsResponse.Success.class); assertThat( - cacheClient.sortedSetRemoveElements( + cacheClientApiKeyV2.sortedSetRemoveElements( cacheName, sortedSetName, Sets.newHashSet(one, two))) .succeedsWithin(FIVE_SECONDS) .isInstanceOf(SortedSetRemoveElementsResponse.Success.class); - assertThat(cacheClient.sortedSetFetchByRank(cacheName, sortedSetName)) + assertThat(cacheClientApiKeyV2.sortedSetFetchByRank(cacheName, sortedSetName)) .succeedsWithin(FIVE_SECONDS) .asInstanceOf(InstanceOfAssertFactories.type(SortedSetFetchResponse.Hit.class)) .satisfies( From 37065e427e269c8681a0d31908f619d3ef425869 Mon Sep 17 00:00:00 2001 From: Anita Ruangrotsakun <138700973+anitarua@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:35:59 -0800 Subject: [PATCH 8/9] use correct credential provider for test cache client Co-authored-by: Nate Anderson --- .../src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java b/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java index 311bc4e9..6f5aad52 100644 --- a/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java +++ b/momento-sdk/src/intTest/java/momento/sdk/cache/BaseCacheTestClass.java @@ -39,7 +39,7 @@ static void beforeAll() { : CacheClient.builder(credentialProvider, config, DEFAULT_TTL_SECONDS).build(); cacheClientApiKeyV2 = - CacheClient.builder(credentialProvider, config, DEFAULT_TTL_SECONDS).build(); + CacheClient.builder(credentialProviderApiKeyV2, config, DEFAULT_TTL_SECONDS).build(); cacheName = testCacheName(); ensureTestCacheExists(cacheName); From 78d95bd4a7d76911b8edfda37866a474952d360e Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 19 Dec 2025 17:06:46 -0800 Subject: [PATCH 9/9] update contributing doc --- CONTRIBUTING.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8d4e263e..9cf31a5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,10 +7,11 @@ 1. Run gradle build * `./gradlew clean build` 1. To run integration tests: - * Generate API key using the [Momento Console](https://console.gomomento.com/api-keys) (if you don't already have one) - * `TEST_AUTH_TOKEN= TEST_CACHE_NAME= TEST_ENDPOINT= ./gradlew integrationTest` - * `TEST_CACHE_NAME` is required. Give it any string value for now. TODO - Add a way of getting this per environment - * `TEST_ENDPOINT` is optional and defaults to alpha. TEST_ENDPOINT must belong to the cell where the auth token was generated. + * Generate API keys using the [Momento Console](https://console.gomomento.com/api-keys) + * `V1_API_KEY= MOMENTO_API_KEY= MOMENTO_ENDPOINT= ./gradlew integrationTest` + * `V1_API_KEY` - required - v1 api key + * `MOMENTO_API_KEY` - required - v2 api key + * `MOMENTO_ENDPOINT` - required - Momento service [endpoint](https://docs.momentohq.com/platform/regions) ### Code Formatting [google-java-format](https://github.com/google/google-java-format) is used for code formatting.