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
21 changes: 21 additions & 0 deletions client/src/main/java/cloud/prefab/client/config/Match.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,38 @@ public class Match {
private final Prefab.ConfigValue configValue;
private final ConfigElement configElement;
private final List<EvaluatedCriterion> evaluatedCriterion;
private final int rowIndex;
private final int conditionalValueIndex;
private final Optional<Integer> weightedValueIndex;

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

public int getRowIndex() {
return rowIndex;
}

public int getConditionalValueIndex() {
return conditionalValueIndex;
}

public Optional<Integer> getWeightedValueIndex() {
return weightedValueIndex;
}

public Prefab.ConfigValue getConfigValue() {
return configValue;
}
Expand Down Expand Up @@ -53,6 +71,9 @@ public String toString() {
.add("configElement", configElement)
.add("configValue", configValue)
.add("evaluatedCriterion", evaluatedCriterion)
.add("rowIndex", rowIndex)
.add("conditionalValueIndex", conditionalValueIndex)
.add("weightedValueIndex", weightedValueIndex)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import cloud.prefab.client.config.logging.AbstractLoggingListener;
import cloud.prefab.domain.Prefab;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -114,30 +115,36 @@ private Optional<Match> evalConfigElementMatch(
// Prefer rows that have a projEnvId to ones that don't
// There will be 0-1 rows with projenv and 0-1 rows without (the default row)

return configElement
.getRowsProjEnvFirst(projectEnvId)
.map(configRow -> {
if (!configRow.getPropertiesMap().isEmpty()) {
rowPropertiesStack.push(configRow.getPropertiesMap());
}
// Return the value of the first matching set of criteria
for (Prefab.ConditionalValue conditionalValue : configRow.getValuesList()) {
Optional<Match> optionalMatch = evaluateConditionalValue(
conditionalValue,
lookupContext,
rowPropertiesStack,
configElement
);
return Streams
.mapWithIndex(
configElement.getRowsProjEnvFirst(projectEnvId),
(configRow, rowIndex) -> {
if (!configRow.getPropertiesMap().isEmpty()) {
rowPropertiesStack.push(configRow.getPropertiesMap());
}
// Return the value of the first matching set of criteria
int conditionalValueIndex = 0;
for (Prefab.ConditionalValue conditionalValue : configRow.getValuesList()) {
Optional<Match> optionalMatch = evaluateConditionalValue(
rowIndex,
conditionalValue,
conditionalValueIndex,
lookupContext,
rowPropertiesStack,
configElement
);

if (optionalMatch.isPresent()) {
return optionalMatch.get();
if (optionalMatch.isPresent()) {
return optionalMatch.get();
}
conditionalValueIndex++;
}
if (!configRow.getPropertiesMap().isEmpty()) {
rowPropertiesStack.pop();
}
return null;
}
if (!configRow.getPropertiesMap().isEmpty()) {
rowPropertiesStack.pop();
}
return null;
})
)
.filter(Objects::nonNull)
.findFirst();
}
Expand Down Expand Up @@ -165,13 +172,14 @@ Optional<Match> evalConfigElementMatch(
* @return
*/
private Optional<Match> evaluateConditionalValue(
long rowIndex,
Prefab.ConditionalValue conditionalValue,
int conditionalValueIndex,
LookupContext lookupContext,
Deque<Map<String, Prefab.ConfigValue>> rowProperties,
ConfigElement configElement
) {
List<EvaluatedCriterion> evaluatedCriteria = new ArrayList<>();

for (Prefab.Criterion criterion : conditionalValue.getCriteriaList()) {
for (EvaluatedCriterion evaluateCriterion : evaluateCriterionMatch(
criterion,
Expand All @@ -185,15 +193,24 @@ private Optional<Match> evaluateConditionalValue(
}
}
return Optional.of(
simplifyToMatch(conditionalValue, configElement, lookupContext, evaluatedCriteria)
simplifyToMatch(
rowIndex,
conditionalValue,
conditionalValueIndex,
configElement,
lookupContext,
evaluatedCriteria
)
);
}

/**
* A ConfigValue may be a WeightedValue. If so break it down so we can return a simpler form.
*/
private Match simplifyToMatch(
long rowIndex,
Prefab.ConditionalValue selectedConditionalValue,
int conditionalValueIndex,
ConfigElement configElement,
LookupContext lookupContext,
List<EvaluatedCriterion> evaluatedCriteria
Expand All @@ -208,13 +225,17 @@ private Match simplifyToMatch(
result.getValue(),
configElement,
evaluatedCriteria,
(int) rowIndex,
conditionalValueIndex,
Optional.of(result.getIndex())
);
} else {
return new Match(
selectedConditionalValue.getValue(),
configElement,
evaluatedCriteria,
(int) rowIndex,
conditionalValueIndex,
Optional.empty()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

public class MatchStatsAggregator {

Expand Down Expand Up @@ -68,11 +69,14 @@ void recordMatch(Match match, long timeStamp) {

CountKey countKey = new CountKey(
match.getConfigElement().getConfig().getId(),
match.getConfigValue(),
indexOfMatch(
match.getConfigValue(),
match.getConfigElement().getConfig().getAllowableValuesList()
),
match.getConfigValue()
match.getRowIndex(),
match.getConditionalValueIndex(),
match.getWeightedValueIndex()
);
innerMap.computeIfAbsent(countKey, c -> new Counter(0)).inc();
}
Expand Down Expand Up @@ -112,6 +116,11 @@ Prefab.ConfigEvaluationSummaries toProto() {
if (countKey.selectedIndex >= 0) {
counterProtoBuilder.setSelectedIndex(countKey.selectedIndex);
}
counterProtoBuilder.setConfigRowIndex(countKey.rowIndex);
counterProtoBuilder.setConditionalValueIndex(countKey.valueIndex);
countKey.weightedValueIndex.ifPresent(
counterProtoBuilder::setWeightedValueIndex
);
counterProtoBuilder.setSelectedValue(countKey.configValue);
summaryBuilder.addCounters(counterProtoBuilder);
}
Expand Down Expand Up @@ -162,11 +171,24 @@ static class CountKey {

final long configId;
final int selectedIndex;
private final int rowIndex;
private final int valueIndex;
private final Optional<Integer> weightedValueIndex;
final Prefab.ConfigValue configValue;

CountKey(long configId, int selectedIndex, Prefab.ConfigValue configValue) {
CountKey(
long configId,
Prefab.ConfigValue configValue,
int selectedIndex,
int rowIndex,
int valueIndex,
Optional<Integer> weightedValueIndex
) {
this.configId = configId;
this.selectedIndex = selectedIndex;
this.rowIndex = rowIndex;
this.valueIndex = valueIndex;
this.weightedValueIndex = weightedValueIndex;
this.configValue = configValue;
}

Expand All @@ -182,13 +204,23 @@ public boolean equals(Object o) {
return (
configId == countKey.configId &&
selectedIndex == countKey.selectedIndex &&
rowIndex == countKey.rowIndex &&
valueIndex == countKey.valueIndex &&
Objects.equals(weightedValueIndex, countKey.weightedValueIndex) &&
Objects.equals(configValue, countKey.configValue)
);
}

@Override
public int hashCode() {
return Objects.hash(configId, selectedIndex, configValue);
return Objects.hash(
configId,
selectedIndex,
rowIndex,
valueIndex,
weightedValueIndex,
configValue
);
}

@Override
Expand All @@ -197,6 +229,9 @@ public String toString() {
.toStringHelper(this)
.add("configId", configId)
.add("selectedIndex", selectedIndex)
.add("rowIndex", rowIndex)
.add("valueIndex", valueIndex)
.add("weightedValueIndex", weightedValueIndex)
.add("configValue", configValue)
.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ void itWorks() throws InterruptedException {
ConfigValueUtils.from(false),
new ConfigElement(TF_CONFIG, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
1,
2,
Optional.empty()
),
new LookupContext(
Expand All @@ -74,6 +76,8 @@ void itWorks() throws InterruptedException {
ConfigValueUtils.from(true),
new ConfigElement(TF_CONFIG, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
1,
2,
Optional.empty()
),
new LookupContext(
Expand All @@ -90,6 +94,8 @@ void itWorks() throws InterruptedException {
ConfigValueUtils.from(true),
new ConfigElement(TF_CONFIG, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
1,
2,
Optional.empty()
),
new LookupContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ void itAggregates() {
ConfigValueUtils.from(true),
new ConfigElement(TF_CONFIG_1, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
0,
2,
Optional.empty()
),
101
Expand All @@ -77,6 +79,8 @@ void itAggregates() {
ConfigValueUtils.from(false),
new ConfigElement(TF_CONFIG_1, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
0,
2,
Optional.empty()
),
102
Expand All @@ -87,6 +91,8 @@ void itAggregates() {
ConfigValueUtils.from(false),
new ConfigElement(TF_CONFIG_2, new Provenance(ConfigClient.Source.STREAMING)),
Collections.emptyList(),
0,
2,
Optional.empty()
),
102
Expand All @@ -100,6 +106,8 @@ void itAggregates() {
new Provenance(ConfigClient.Source.STREAMING)
),
Collections.emptyList(),
0,
3,
Optional.empty()
),
107
Expand All @@ -117,19 +125,47 @@ void itAggregates() {
Prefab.ConfigType.FEATURE_FLAG
),
Map.of(
new MatchStatsAggregator.CountKey(1, 0, ConfigValueUtils.from(1)),
new MatchStatsAggregator.CountKey(
1,
ConfigValueUtils.from(1),
0,
0,
3,
Optional.empty()
),
new MatchStatsAggregator.Counter(1)
),
new MatchStatsAggregator.ConfigKeyAndTypeKey(
"the.key",
Prefab.ConfigType.FEATURE_FLAG
),
Map.of(
new MatchStatsAggregator.CountKey(1, 0, ConfigValueUtils.from(true)),
new MatchStatsAggregator.CountKey(
1,
ConfigValueUtils.from(true),
0,
0,
2,
Optional.empty()
),
new MatchStatsAggregator.Counter(1),
new MatchStatsAggregator.CountKey(1, 1, ConfigValueUtils.from(false)),
new MatchStatsAggregator.CountKey(
1,
ConfigValueUtils.from(false),
1,
0,
2,
Optional.empty()
),
new MatchStatsAggregator.Counter(1),
new MatchStatsAggregator.CountKey(2, 1, ConfigValueUtils.from(false)),
new MatchStatsAggregator.CountKey(
2,
ConfigValueUtils.from(false),
1,
0,
2,
Optional.empty()
),
new MatchStatsAggregator.Counter(1)
)
)
Expand Down