Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public <T> Variable<T> variable(DevCycleUser user, String key, T defaultValue) {
}

variable.setIsDefaulted(false);
evalHooksRunner.executeAfter(reversedHooks, context, variable);
evalHooksRunner.executeAfter(reversedHooks, context, variable, null);
} catch (Throwable exception) {
if (!(exception instanceof BeforeHookError || exception instanceof AfterHookError)) {
variable = (Variable<T>) Variable.builder()
Expand All @@ -170,7 +170,7 @@ public <T> Variable<T> variable(DevCycleUser user, String key, T defaultValue) {

evalHooksRunner.executeError(reversedHooks, context, exception);
} finally {
evalHooksRunner.executeFinally(reversedHooks, context, Optional.ofNullable(variable));
evalHooksRunner.executeFinally(reversedHooks, context, Optional.ofNullable(variable), null);
}
return variable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import java.util.Optional;

import com.devcycle.sdk.server.local.model.VariableMetadata;

public interface EvalHook<T> {

default Optional<HookContext<T>> before(HookContext<T> ctx) {
return Optional.empty();
}
default void after(HookContext<T> ctx, Variable<T> variable) {}
default void after(HookContext<T> ctx, Variable<T> variable, VariableMetadata variableMetadata) {}
default void error(HookContext<T> ctx, Throwable e) {}
default void onFinally(HookContext<T> ctx, Optional<Variable<T>> variable) {}
default void onFinally(HookContext<T> ctx, Optional<Variable<T>> variable, VariableMetadata variableMetadata) {}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.devcycle.sdk.server.common.model;

import com.devcycle.sdk.server.common.exception.AfterHookError;
import com.devcycle.sdk.server.common.exception.BeforeHookError;
import com.devcycle.sdk.server.common.logging.DevCycleLogger;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import com.devcycle.sdk.server.common.exception.AfterHookError;
import com.devcycle.sdk.server.common.exception.BeforeHookError;
import com.devcycle.sdk.server.common.logging.DevCycleLogger;
import com.devcycle.sdk.server.local.model.VariableMetadata;

/**
* A class that manages evaluation hooks for the DevCycle SDK.
* Provides functionality to add and clear hooks, storing them in an array.
Expand Down Expand Up @@ -81,16 +82,16 @@ public <T> HookContext<T> executeBefore(ArrayList<EvalHook<T>> hooks, HookContex
* @param variable The variable result to pass to the hooks
* @param <T> The type of the variable value
*/
public void executeAfter(ArrayList<EvalHook<T>> hooks, HookContext<T> context, Variable<T> variable) {
public void executeAfter(ArrayList<EvalHook<T>> hooks, HookContext<T> context, Variable<T> variable, VariableMetadata variableMetadata) {
for (EvalHook<T> hook : hooks) {
try {
hook.after(context, variable);
hook.after(context, variable, variableMetadata);
} catch (Exception e) {
throw new AfterHookError("After hook failed", e);
}
}
}

/**
* Runs all error hooks in reverse order.
*
Expand All @@ -115,10 +116,10 @@ public void executeError(ArrayList<EvalHook<T>> hooks, HookContext<T> context, T
* @param context The context to pass to the hooks
* @param variable The variable result to pass to the hooks (may be null)
*/
public void executeFinally(ArrayList<EvalHook<T>> hooks, HookContext<T> context, Optional<Variable<T>> variable) {
public void executeFinally(ArrayList<EvalHook<T>> hooks, HookContext<T> context, Optional<Variable<T>> variable, VariableMetadata variableMetadata) {
for (EvalHook<T> hook : hooks) {
try {
hook.onFinally(context, variable);
hook.onFinally(context, variable, variableMetadata);
} catch (Exception e) {
// Log finally hook error but don't throw
DevCycleLogger.error("Finally hook failed: " + e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package com.devcycle.sdk.server.common.model;

import java.net.InetAddress;
import java.net.UnknownHostException;

import com.devcycle.sdk.server.common.logging.DevCycleLogger;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;

import java.net.InetAddress;
import java.net.UnknownHostException;

@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
Expand All @@ -34,6 +35,7 @@ public class PlatformData {
private String sdkVersion = "2.8.1";

@Schema(description = "DevCycle SDK Platform")
@Builder.Default
private String sdkPlatform = null;

@Schema(description = "Hostname where the SDK is running")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.devcycle.sdk.server.local.model.BucketedUserConfig;
import com.devcycle.sdk.server.local.model.ConfigMetadata;
import com.devcycle.sdk.server.local.model.DevCycleLocalOptions;
import com.devcycle.sdk.server.local.model.VariableMetadata;
import com.devcycle.sdk.server.local.protobuf.SDKVariable_PB;
import com.devcycle.sdk.server.local.protobuf.VariableForUserParams_PB;
import com.devcycle.sdk.server.local.protobuf.VariableType_PB;
Expand Down Expand Up @@ -181,6 +182,7 @@ public <T> Variable<T> variable(DevCycleUser user, String key, T defaultValue) {

HookContext<T> hookContext = new HookContext<T>(user, key, defaultValue, getMetadata());
Variable<T> variable = null;
VariableMetadata variableMetadata = null;
ArrayList<EvalHook<T>> hooks = new ArrayList<EvalHook<T>>(evalHooksRunner.getHooks());
ArrayList<EvalHook<T>> reversedHooks = new ArrayList<EvalHook<T>>(evalHooksRunner.getHooks());
Collections.reverse(reversedHooks);
Expand All @@ -207,12 +209,13 @@ public <T> Variable<T> variable(DevCycleUser user, String key, T defaultValue) {
variable.setEval(EvalReason.defaultReason(EvalReason.DefaultReasonDetailsEnum.VARIABLE_TYPE_MISMATCH));
} else {
variable = ProtobufUtils.createVariable(sdkVariable, defaultValue);
variableMetadata = new VariableMetadata(sdkVariable.getFeature().getValue());
}
}
if (beforeError != null) {
throw beforeError;
}
evalHooksRunner.executeAfter(reversedHooks, hookContext, variable);
evalHooksRunner.executeAfter(reversedHooks, hookContext, variable, variableMetadata);
} catch (Throwable e) {
if (!(e instanceof BeforeHookError)) {
DevCycleLogger.error("Unable to evaluate Variable " + key + " due to error: " + e, e);
Expand All @@ -225,7 +228,7 @@ public <T> Variable<T> variable(DevCycleUser user, String key, T defaultValue) {
variable = defaultVariable;
variable.setEval(EvalReason.defaultReason(EvalReason.DefaultReasonDetailsEnum.USER_NOT_TARGETED));
}
evalHooksRunner.executeFinally(reversedHooks, hookContext, Optional.of(variable));
evalHooksRunner.executeFinally(reversedHooks, hookContext, Optional.ofNullable(variable), variableMetadata);
}
return variable;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.devcycle.sdk.server.local.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.AllArgsConstructor;

@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class VariableMetadata {

public final String featureId;

}
Loading
Loading