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
4 changes: 4 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
</dependency>
<dependency>
<groupId>dev.failsafe</groupId>
<artifactId>failsafe</artifactId>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion client/prefab-cloud
Submodule prefab-cloud updated 1 files
+75 −0 prefab.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ public class ConfigValueUtils {

public static final Logger LOG = LoggerFactory.getLogger(ConfigValueUtils.class);

public static Prefab.ConfigValue fromString(String string) {
public static Prefab.ConfigValue from(String string) {
return Prefab.ConfigValue.newBuilder().setString(string).build();
}

public static Prefab.ConfigValue from(boolean bool) {
return Prefab.ConfigValue.newBuilder().setBool(bool).build();
}

public static Prefab.ConfigValue from(long number) {
return Prefab.ConfigValue.newBuilder().setInt(number).build();
}

public static Prefab.ConfigValue from(int number) {
return Prefab.ConfigValue.newBuilder().setInt(number).build();
}

public static Map<String, Prefab.ConfigValue> fromStringMap(
Map<String, String> stringStringMap
) {
Expand Down Expand Up @@ -80,4 +92,12 @@ public static Optional<Object> asObject(Prefab.ConfigValue configValue) {
return Optional.empty();
}
}

@Deprecated
/**
* @deprecated see {@link #from(String)}
*/
public static Prefab.ConfigValue fromString(String string) {
return from(string);
}
}
6 changes: 5 additions & 1 deletion client/src/main/java/cloud/prefab/client/config/Match.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@
import cloud.prefab.domain.Prefab;
import com.google.common.base.MoreObjects;
import java.util.List;
import java.util.Optional;

public class Match {

private final Prefab.ConfigValue configValue;
private final ConfigElement configElement;
private final List<EvaluatedCriterion> evaluatedCriterion;
private final Optional<Integer> weightedValueIndex;

public Match(
Prefab.ConfigValue configValue,
ConfigElement configElement,
List<EvaluatedCriterion> evaluatedCriterion
List<EvaluatedCriterion> evaluatedCriterion,
Optional<Integer> weightedValueIndex
) {
this.configValue = configValue;
this.configElement = configElement;
this.evaluatedCriterion = evaluatedCriterion;
this.weightedValueIndex = weightedValueIndex;
}

public Prefab.ConfigValue getConfigValue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import cloud.prefab.client.PrefabInitializationTimeoutException;
import cloud.prefab.client.config.ConfigChangeEvent;
import cloud.prefab.client.config.ConfigChangeListener;
import cloud.prefab.client.config.Match;
import cloud.prefab.client.config.logging.AbstractLoggingListener;
import cloud.prefab.client.value.LiveBoolean;
import cloud.prefab.client.value.LiveDouble;
Expand Down Expand Up @@ -79,6 +80,7 @@ public class ConfigClientImpl implements ConfigClient {
private final PrefabHttpClient prefabHttpClient;

private final ContextStore contextStore;
private MatchProcessingManager matchProcessingManager;

private ContextShapeAggregator contextShapeAggregator = null;

Expand Down Expand Up @@ -160,6 +162,8 @@ public ConfigClientImpl(
new EvaluatedKeysAggregator(options, prefabHttpClient, Clock.systemUTC());
evaluatedKeysAggregator.start();
}
matchProcessingManager = new MatchProcessingManager(prefabHttpClient, options);
matchProcessingManager.start();
}
}

Expand Down Expand Up @@ -204,7 +208,6 @@ public Optional<Prefab.ConfigValue> get(
PrefabContextSetReadable resolvedContext = resolveContext(prefabContext);
reportUsage(configKey, resolvedContext);
LookupContext lookupContext = new LookupContext(namespaceMaybe, resolvedContext);

return getInternal(configKey, lookupContext);
}

Expand Down Expand Up @@ -244,7 +247,25 @@ private Optional<Prefab.ConfigValue> getInternal(
LookupContext lookupContext
) {
waitForInitialization();
return updatingConfigResolver.getConfigValue(configKey, lookupContext);
Optional<Match> matchMaybe = getMatchInternal(configKey, lookupContext);

matchMaybe.ifPresent(match -> reportMatchResult(match, lookupContext));

return matchMaybe.map(Match::getConfigValue);
}

private void reportMatchResult(Match match, LookupContext lookupContext) {
if (matchProcessingManager != null) {
matchProcessingManager.reportMatch(match, lookupContext);
}
}

private Optional<Match> getMatchInternal(
String configKey,
LookupContext lookupContext
) {
waitForInitialization();
return updatingConfigResolver.getResolver().getMatch(configKey, lookupContext);
}

@Override
Expand Down Expand Up @@ -429,11 +450,6 @@ boolean loadAPI() {
return false;
}

private static String getBasicAuthenticationHeader(String username, String password) {
String valueToEncode = username + ":" + password;
return "Basic " + Base64.getEncoder().encodeToString(valueToEncode.getBytes());
}

private ScheduledExecutorService startStreamingExecutor() {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(
1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,32 +184,39 @@ private Optional<Match> evaluateConditionalValue(
evaluatedCriteria.add(evaluateCriterion);
}
}

Prefab.ConfigValue simplified = simplify(
conditionalValue,
configElement.getConfig().getKey(),
lookupContext
return Optional.of(
simplifyToMatch(conditionalValue, configElement, lookupContext, evaluatedCriteria)
);

return Optional.of(new Match(simplified, configElement, evaluatedCriteria));
}

/**
* A ConfigValue may be a WeightedValue. If so break it down so we can return a simpler form.
*/
private Prefab.ConfigValue simplify(
Prefab.ConditionalValue conditionalValue,
String key,
LookupContext lookupContext
private Match simplifyToMatch(
Prefab.ConditionalValue selectedConditionalValue,
ConfigElement configElement,
LookupContext lookupContext,
List<EvaluatedCriterion> evaluatedCriteria
) {
if (conditionalValue.getValue().hasWeightedValues()) {
return weightedValueEvaluator.toValue(
conditionalValue.getValue().getWeightedValues(),
key,
if (selectedConditionalValue.getValue().hasWeightedValues()) {
WeightedValueEvaluator.Result result = weightedValueEvaluator.toResult(
selectedConditionalValue.getValue().getWeightedValues(),
configElement.getConfig().getKey(),
lookupContext
);
return new Match(
result.getValue(),
configElement,
evaluatedCriteria,
Optional.of(result.getIndex())
);
} else {
return conditionalValue.getValue();
return new Match(
selectedConditionalValue.getValue(),
configElement,
evaluatedCriteria,
Optional.empty()
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public Optional<Prefab.ConfigValue> getValue(String name) {
return Optional.ofNullable(getExpandedProperties().get(name));
}

public PrefabContextSet getPrefabContextSet() {
return prefabContextSet;
}

public Map<String, Prefab.ConfigValue> getExpandedProperties() {
if (this.expandedProperties == null) {
int propertyCount =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cloud.prefab.client.internal;

import cloud.prefab.client.Options;
import cloud.prefab.client.config.Match;
import cloud.prefab.domain.Prefab;
import java.time.Clock;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;

public class MatchProcessingManager {

private static final int OUTPUT_QUEUE_SIZE = 10;

private final MatchProcessor matchProcessor;
private final TelemetryUploader uploader;

MatchProcessingManager(PrefabHttpClient prefabHttpClient, Options options) {
LinkedBlockingQueue<OutputBuffer> outputQueue = new LinkedBlockingQueue<>(
OUTPUT_QUEUE_SIZE
);
matchProcessor = new MatchProcessor(outputQueue, Clock.systemUTC(), options);
uploader = new TelemetryUploader(outputQueue, prefabHttpClient, options);
}

public void start() {
uploader.start();
matchProcessor.start();
}

public void reportMatch(Match match, LookupContext lookupContext) {
matchProcessor.reportMatch(match, lookupContext);
}

static class OutputBuffer {

Set<Prefab.ExampleContext> recentlySeenContexts;
MatchStatsAggregator.StatsAggregate statsAggregate;

public OutputBuffer(
Set<Prefab.ExampleContext> recentlySeenContexts,
MatchStatsAggregator.StatsAggregate statsAggregate
) {
this.recentlySeenContexts = recentlySeenContexts;
this.statsAggregate = statsAggregate;
}

Prefab.TelemetryEvents toTelemetryEvents() {
Prefab.TelemetryEvents.Builder telemetryEventsBuilder = Prefab.TelemetryEvents.newBuilder();
if (!recentlySeenContexts.isEmpty()) {
telemetryEventsBuilder.addEvents(
Prefab.TelemetryEvent
.newBuilder()
.setExampleContexts(
Prefab.ExampleContexts
.newBuilder()
.addAllExamples(recentlySeenContexts)
.build()
)
.build()
);
}
if (!statsAggregate.getCounterData().isEmpty()) {
telemetryEventsBuilder.addEvents(
Prefab.TelemetryEvent.newBuilder().setSummaries(statsAggregate.toProto())
);
}

return telemetryEventsBuilder.build();
}
}
}
Loading