Skip to content

Commit

Permalink
feat: Add endpoint override for Momento (#43)
Browse files Browse the repository at this point in the history
* feat: Add endpoint override for Momento

The plan of record is to make endpoint available in the authToken. SDK will be parsing the authToken to determine the endpoint and then prefix it with `control.` to perform control operations and `cache.` to perform cache operations.

Currently, the endpoint isn't available in the authToken. Hence an endpointOverride option is added. Momento will prefer the endpointOverride option over the endpoint in the authToken.

The change also switches Momento construction from init() to Builder pattern which is more consistent with other standard Java SDKs like those of other cloud providers.

Now the object construction will be:
```
Momento momento = Momento.builder()
                    .authToken("authToken")
                    .endpointOverride("developer-gautam-dev.preprod.a.momentohq.com")
                    .build();
```

* update variable names
  • Loading branch information
gautamomento authored Sep 29, 2021
1 parent 369eceb commit 3f4326f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 13 deletions.
6 changes: 5 additions & 1 deletion momento-sdk/src/intTest/java/momento/sdk/MomentoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ static void beforeAll() {
@org.junit.jupiter.api.Test
void testHappyPath() {
try {
Momento m = Momento.init(System.getenv("TEST_AUTH_TOKEN"));
Momento m =
Momento.builder()
.authToken(System.getenv("TEST_AUTH_TOKEN"))
.endpointOverride("cell-alpha-dev.preprod.a.momentohq.com")
.build();
Cache cache = m.createCache(System.getenv("TEST_CACHE_NAME"));

String key = java.util.UUID.randomUUID().toString();
Expand Down
75 changes: 63 additions & 12 deletions momento-sdk/src/main/java/momento/sdk/Momento.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,19 @@

public final class Momento implements Closeable {

private static final String CONTROL_ENDPOINT_PREFIX = "control.";
private static final String CACHE_ENDPOINT_PREFIX = "cache.";

private final String authToken;
private final String hostedZone;
private final ScsControlBlockingStub blockingStub;
private final ManagedChannel channel;

public static Momento init(String authToken) {
if (authToken == null) {
throw new ClientSdkException("Auth Token is required to make a request.");
}
return new Momento(authToken);
}

private Momento(String authToken) {
private Momento(String authToken, String hostedZone) {
this.authToken = authToken;
// FIXME get endpoint from JWT claim
this.hostedZone = hostedZone;
NettyChannelBuilder channelBuilder =
NettyChannelBuilder.forAddress("control.cell-alpha-dev.preprod.a.momentohq.com", 443);
NettyChannelBuilder.forAddress(CONTROL_ENDPOINT_PREFIX + hostedZone, 443);
channelBuilder.useTransportSecurity();
channelBuilder.disableRetry();
List<ClientInterceptor> clientInterceptors = new ArrayList<>();
Expand All @@ -58,7 +55,7 @@ public Cache createCache(String cacheName) {
checkCacheNameValid(cacheName);
try {
this.blockingStub.createCache(buildCreateCacheRequest(cacheName));
return new Cache(this.authToken, cacheName);
return makeCacheClient(authToken, cacheName, hostedZone);
} catch (io.grpc.StatusRuntimeException e) {
if (e.getStatus() == Status.ALREADY_EXISTS) {
throw new CacheAlreadyExistsException(
Expand All @@ -72,7 +69,7 @@ public Cache createCache(String cacheName) {

public Cache getCache(String cacheName) {
checkCacheNameValid(cacheName);
return new Cache(this.authToken, cacheName);
return makeCacheClient(authToken, cacheName, hostedZone);
}

private CreateCacheRequest buildCreateCacheRequest(String cacheName) {
Expand All @@ -85,7 +82,61 @@ private static void checkCacheNameValid(String cacheName) {
}
}

private static Cache makeCacheClient(String authToken, String cacheName, String endpoint) {
return new Cache(authToken, cacheName, CACHE_ENDPOINT_PREFIX + endpoint);
}

public void close() {
this.channel.shutdown();
}

public static MomentoBuilder builder() {
return new MomentoBuilder();
}

// TODO: ParseJWT to determine the authToken
private static String extractEndpoint(String authToken) {
return null;
}

public static class MomentoBuilder {
private String authToken;
private String endpointOverride;

public MomentoBuilder authToken(String authToken) {
this.authToken = authToken;
return this;
}

/**
* Endpoint that will be used to perform Momento Cache Operations.
*
* @param endpointOverride
* @return
*/
// TODO: Write a better public facing doc, this is basically a hosted zone for the cell against
// which the requests
// will be made.
public MomentoBuilder endpointOverride(String endpointOverride) {
this.endpointOverride = endpointOverride;
return this;
}

public Momento build() {
if (authToken == null || authToken.isEmpty()) {
throw new ClientSdkException("Auth Token is required");
}
// Endpoint must be either available in the authToken or must be provided via
// endPointOverride.
String endpoint =
endpointOverride != null && !endpointOverride.isEmpty()
? endpointOverride
: extractEndpoint(authToken);

if (endpoint == null) {
throw new ClientSdkException("Endpoint for cache service is a required parameter.");
}
return new Momento(authToken, endpoint);
}
}
}

0 comments on commit 3f4326f

Please sign in to comment.