Skip to content

Commit

Permalink
feat: Add SDK id and version to requests (#66)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabrizio Demaria <[email protected]>
  • Loading branch information
fabriziodemaria authored Nov 9, 2023
1 parent 77ecd7d commit eb97dc7
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 11 deletions.
5 changes: 4 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@
</extension>
</extensions>
<resources>
<resource><directory>src/main/resources</directory></resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource><directory>src/main/proto</directory></resource>
</resources>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.spotify.confidence.flags.resolver.v1.ResolveFlagsRequest;
import com.spotify.confidence.flags.resolver.v1.ResolveFlagsResponse;
import com.spotify.confidence.flags.resolver.v1.ResolvedFlag;
import com.spotify.confidence.flags.resolver.v1.Sdk;
import com.spotify.confidence.flags.resolver.v1.SdkId;
import dev.openfeature.sdk.EvaluationContext;
import dev.openfeature.sdk.FeatureProvider;
import dev.openfeature.sdk.Metadata;
Expand All @@ -19,13 +21,14 @@
import dev.openfeature.sdk.exceptions.InvalidContextError;
import dev.openfeature.sdk.exceptions.TargetingKeyMissingError;
import dev.openfeature.sdk.exceptions.TypeMismatchError;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Status.Code;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.shaded.io.netty.util.internal.StringUtil;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.regex.Pattern;
Expand All @@ -38,6 +41,9 @@ public class ConfidenceFeatureProvider implements FeatureProvider {
private final FlagResolverServiceBlockingStub stub;
private final String clientSecret;

private final String SDK_VERSION;
private static final SdkId SDK_ID = SdkId.SDK_ID_JAVA_PROVIDER;

static final String TARGETING_KEY = "targeting_key";

/**
Expand All @@ -49,6 +55,18 @@ public class ConfidenceFeatureProvider implements FeatureProvider {
public ConfidenceFeatureProvider(String clientSecret, FlagResolverServiceBlockingStub stub) {
this.clientSecret = clientSecret;
this.stub = stub;

if (Strings.isNullOrEmpty(clientSecret)) {
throw new IllegalArgumentException("clientSecret must be a non-empty string.");
}

try {
final Properties prop = new Properties();
prop.load(this.getClass().getResourceAsStream("/version.properties"));
this.SDK_VERSION = prop.getProperty("version");
} catch (IOException e) {
throw new RuntimeException("Can't determine version of the SDK", e);
}
}

/**
Expand All @@ -57,14 +75,10 @@ public ConfidenceFeatureProvider(String clientSecret, FlagResolverServiceBlockin
* @param clientSecret generated from Confidence
*/
public ConfidenceFeatureProvider(String clientSecret) {
final ManagedChannel channel =
ManagedChannelBuilder.forAddress("edge-grpc.spotify.com", 443).build();
this.stub = FlagResolverServiceGrpc.newBlockingStub(channel);

if (Strings.isNullOrEmpty(clientSecret)) {
throw new IllegalArgumentException("clientSecret must be a non-empty string.");
}
this.clientSecret = clientSecret;
this(
clientSecret,
FlagResolverServiceGrpc.newBlockingStub(
ManagedChannelBuilder.forAddress("edge-grpc.spotify.com", 443).build()));
}

@Override
Expand Down Expand Up @@ -157,6 +171,7 @@ public ProviderEvaluation<Value> getObjectEvaluation(
.setClientSecret(clientSecret)
.addAllFlags(List.of(requestFlagName))
.setEvaluationContext(evaluationContext.build())
.setSdk(Sdk.newBuilder().setId(SDK_ID).setVersion(SDK_VERSION).build())
.setApply(true)
.build());

Expand Down
13 changes: 13 additions & 0 deletions src/main/proto/confidence/flags/resolver/v1/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ message ResolveFlagsRequest {
bool apply = 4 [
(google.api.field_behavior) = REQUIRED
];

// Information about the SDK used to initiate the request.
Sdk sdk = 5 [
(google.api.field_behavior) = OPTIONAL
];
}

message ResolveFlagsResponse {
Expand All @@ -82,6 +87,9 @@ message ResolveFlagsResponse {
// An opaque token that is used when `apply` is set to false in `ResolveFlags`.
// When `apply` is set to false, the token must be passed to `ApplyFlags`.
bytes resolve_token = 2;

// Unique identifier for this particular resolve request.
string resolve_id = 3;
}

message ApplyFlagsRequest {
Expand All @@ -104,6 +112,11 @@ message ApplyFlagsRequest {
google.protobuf.Timestamp send_time = 4 [
(google.api.field_behavior) = REQUIRED
];

// Information about the SDK used to initiate the request.
Sdk sdk = 5 [
(google.api.field_behavior) = OPTIONAL
];
}

message ApplyFlagsResponse {
Expand Down
42 changes: 41 additions & 1 deletion src/main/proto/confidence/flags/resolver/v1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,29 @@ syntax = "proto3";

package confidence.flags.resolver.v1;

import "google/api/field_behavior.proto";

option java_package = "com.spotify.confidence.flags.resolver.v1";
option java_multiple_files = true;
option java_outer_classname = "TypesProto";

// (-- api-linter: core::0123::resource-annotation=disabled
// aip.dev/not-precedent: SDKs are not internal Confidence resources. --)
message Sdk {
// Identifier of the SDK used to interact with the API.
oneof sdk {
// Name of a Confidence SDKs.
SdkId id = 1;
// Custom name for non-Confidence SDKs.
string custom_id = 2;
}

// Version of the SDK.
string version = 3 [
(google.api.field_behavior) = REQUIRED
];
}

enum ResolveReason {
// Unspecified enum.
RESOLVE_REASON_UNSPECIFIED = 0;
Expand All @@ -18,6 +37,27 @@ enum ResolveReason {
RESOLVE_REASON_NO_TREATMENT_MATCH = 3 [deprecated = true];
// The flag could not be resolved because it was archived.
RESOLVE_REASON_FLAG_ARCHIVED = 4;
// The flag could not be resolved because the targeting key field was invalid
RESOLVE_REASON_TARGETING_KEY_ERROR = 5;
// Unknown error occurred during the resolve
RESOLVE_REASON_ERROR = 5;
RESOLVE_REASON_ERROR = 6;
}

enum SdkId {
// Unspecified enum.
SDK_ID_UNSPECIFIED = 0;
// Confidence OpenFeature Java Provider.
SDK_ID_JAVA_PROVIDER = 1;
// Confidence OpenFeature Kotlin Provider.
SDK_ID_KOTLIN_PROVIDER = 2;
// Confidence OpenFeature Swift Provider.
SDK_ID_SWIFT_PROVIDER = 3;
// Confidence OpenFeature JavaScript Provider for Web (client).
SDK_ID_JS_WEB_PROVIDER = 4;
// Confidence OpenFeature JavaScript Provider for server.
SDK_ID_JS_SERVER_PROVIDER = 5;
// Confidence OpenFeature Python Provider.
SDK_ID_PYTHON_PROVIDER = 6;
// Confidence OpenFeature GO Provider.
SDK_ID_GO_PROVIDER = 7;
}
1 change: 1 addition & 0 deletions src/main/resources/version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = ${project.version}

0 comments on commit eb97dc7

Please sign in to comment.