Skip to content

Commit

Permalink
chore: Add support for dynamic expression in label application rules (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
saxenakshitiz authored Jun 11, 2024
1 parent a02e74f commit 3697588
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface Action {
String OPERATION_KEY = "operation";
String STATIC_LABELS = "staticLabels";
String DYNAMIC_LABEL_KEY_KEY = "dynamicLabelKey";
String DYNAMIC_LABEL_EXPRESSION_KEY = "dynamicLabelExpression";
String ACTION_TYPE_KEY = "type";

@GraphQLName(Operation.TYPE_NAME)
Expand All @@ -25,7 +26,8 @@ enum Operation {
@GraphQLName(ActionType.TYPE_NAME)
enum ActionType {
STATIC_LABELS,
DYNAMIC_LABEL_KEY;
DYNAMIC_LABEL_KEY,
DYNAMIC_LABEL_EXPRESSION;
private static final String TYPE_NAME = "LabelApplicationActionType";
}

Expand All @@ -49,6 +51,11 @@ enum ActionType {
@GraphQLName(DYNAMIC_LABEL_KEY_KEY)
String dynamicLabelKey();

@GraphQLField
@Nullable
@GraphQLName(DYNAMIC_LABEL_EXPRESSION_KEY)
DynamicLabelExpression dynamicLabelExpression();

@GraphQLField
@GraphQLNonNull
@GraphQLName(ACTION_TYPE_KEY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.hypertrace.graphql.label.schema.rule;

import graphql.annotations.annotationTypes.GraphQLField;
import graphql.annotations.annotationTypes.GraphQLName;
import graphql.annotations.annotationTypes.GraphQLNonNull;
import java.util.List;

@GraphQLName(DynamicLabelExpression.TYPE_NAME)
public interface DynamicLabelExpression {
String TYPE_NAME = "DynamicLabelExpression";

String LABEL_EXPRESSION_KEY = "labelExpression";
String TOKEN_EXTRACTION_RULES_KEY = "tokenExtractionRules";

@GraphQLField
@GraphQLName(LABEL_EXPRESSION_KEY)
@GraphQLNonNull
String labelExpression();

@GraphQLField
@GraphQLNonNull
@GraphQLName(TOKEN_EXTRACTION_RULES_KEY)
List<TokenExtractionRule> tokenExtractionRules();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.hypertrace.graphql.label.schema.rule;

import graphql.annotations.annotationTypes.GraphQLField;
import graphql.annotations.annotationTypes.GraphQLName;
import graphql.annotations.annotationTypes.GraphQLNonNull;
import javax.annotation.Nullable;

@GraphQLName(TokenExtractionRule.TYPE_NAME)
public interface TokenExtractionRule {
String TYPE_NAME = "TokenExtractionRule";

String KEY_NAME = "key";
String ALIAS_KEY = "alias";
String REGEX_CAPTURE_KEY = "regexCapture";

@GraphQLField
@GraphQLName(KEY_NAME)
@GraphQLNonNull
String key();

@GraphQLField
@GraphQLName(ALIAS_KEY)
@Nullable
String alias();

@GraphQLField
@GraphQLName(REGEX_CAPTURE_KEY)
@Nullable
String regexCapture();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.hypertrace.label.application.rule.config.service.v1.DeleteLabelApplicationRuleRequest;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Action;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Action.DynamicLabel.TokenExtractionRule;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.CompositeCondition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Condition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.LeafCondition;
Expand Down Expand Up @@ -82,11 +83,34 @@ private Action convertLabelAction(org.hypertrace.graphql.label.schema.rule.Actio
.build();
case DYNAMIC_LABEL_KEY:
return actionBuilder.setDynamicLabelKey(action.dynamicLabelKey()).build();
case DYNAMIC_LABEL_EXPRESSION:
return actionBuilder
.setDynamicLabelExpression(
Action.DynamicLabel.newBuilder()
.setLabelExpression(action.dynamicLabelExpression().labelExpression())
.addAllTokenExtractionRules(
convertTokenExtractionRules(
action.dynamicLabelExpression().tokenExtractionRules())))
.build();
default:
throw new IllegalArgumentException("Unsupported action value");
}
}

private List<TokenExtractionRule> convertTokenExtractionRules(
List<org.hypertrace.graphql.label.schema.rule.TokenExtractionRule> tokenExtractionRules) {
return tokenExtractionRules.stream()
.map(
rule -> {
TokenExtractionRule.Builder builder =
TokenExtractionRule.newBuilder().setKey(rule.key());
Optional.ofNullable(rule.alias()).ifPresent(builder::setAlias);
Optional.ofNullable(rule.regexCapture()).ifPresent(builder::setRegexCapture);
return builder.build();
})
.collect(Collectors.toList());
}

Condition convertConditionList(
List<org.hypertrace.graphql.label.schema.rule.Condition> conditionList) {
if (conditionList.size() == 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import lombok.extern.slf4j.Slf4j;
import org.hypertrace.graphql.label.schema.rule.Action;
import org.hypertrace.graphql.label.schema.rule.Condition;
import org.hypertrace.graphql.label.schema.rule.DynamicLabelExpression;
import org.hypertrace.graphql.label.schema.rule.LabelApplicationRule;
import org.hypertrace.graphql.label.schema.rule.LabelApplicationRuleData;
import org.hypertrace.graphql.label.schema.rule.LabelApplicationRuleResultSet;
import org.hypertrace.graphql.label.schema.rule.LeafCondition;
import org.hypertrace.graphql.label.schema.rule.StaticLabels;
import org.hypertrace.graphql.label.schema.rule.StringCondition;
import org.hypertrace.graphql.label.schema.rule.TokenExtractionRule;
import org.hypertrace.graphql.label.schema.rule.UnaryCondition;
import org.hypertrace.graphql.label.schema.rule.ValueCondition;
import org.hypertrace.label.application.rule.config.service.v1.CreateLabelApplicationRuleResponse;
Expand Down Expand Up @@ -105,7 +107,7 @@ private Optional<Action> convertAction(
return operation.map(
op ->
new ConvertedAction(
entityTypes, op, staticLabels, null, Action.ActionType.STATIC_LABELS));
entityTypes, op, staticLabels, null, null, Action.ActionType.STATIC_LABELS));
case DYNAMIC_LABEL_KEY:
return operation.map(
op ->
Expand All @@ -114,7 +116,20 @@ private Optional<Action> convertAction(
op,
null,
action.getDynamicLabelKey(),
null,
Action.ActionType.DYNAMIC_LABEL_KEY));
case DYNAMIC_LABEL_EXPRESSION:
DynamicLabelExpression dynamicLabelExpression =
convertDynamicLabelExpression(action.getDynamicLabelExpression());
return operation.map(
op ->
new ConvertedAction(
entityTypes,
op,
null,
null,
dynamicLabelExpression,
Action.ActionType.DYNAMIC_LABEL_EXPRESSION));
default:
log.error("Unrecognized Value type in Action {}", action.getValueCase().name());
return Optional.empty();
Expand All @@ -128,6 +143,30 @@ private StaticLabels convertStaticLabels(
return new ConvertedStaticLabels(staticLabels.getIdsList());
}

private DynamicLabelExpression convertDynamicLabelExpression(
org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Action
.DynamicLabel
dynamicLabel) {
return new ConvertedDynamicLabelExpression(
dynamicLabel.getLabelExpression(),
convertTokenExtractionRules(dynamicLabel.getTokenExtractionRulesList()));
}

private List<TokenExtractionRule> convertTokenExtractionRules(
List<
org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData
.Action.DynamicLabel.TokenExtractionRule>
tokenExtractionRules) {
return tokenExtractionRules.stream()
.map(
rule ->
new ConvertedTokenExtractionRule(
rule.getKey(),
rule.hasAlias() ? rule.getAlias() : null,
rule.hasRegexCapture() ? rule.getRegexCapture() : null))
.collect(Collectors.toList());
}

private List<Condition> convertCondition(
org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Condition
condition) {
Expand Down Expand Up @@ -300,6 +339,7 @@ private static class ConvertedAction implements Action {
Operation operation;
StaticLabels staticLabels;
String dynamicLabelKey;
DynamicLabelExpression dynamicLabelExpression;
ActionType type;
}

Expand All @@ -309,6 +349,21 @@ private static class ConvertedStaticLabels implements StaticLabels {
List<String> ids;
}

@Value
@Accessors(fluent = true)
private static class ConvertedDynamicLabelExpression implements DynamicLabelExpression {
String labelExpression;
List<TokenExtractionRule> tokenExtractionRules;
}

@Value
@Accessors(fluent = true)
private static class ConvertedTokenExtractionRule implements TokenExtractionRule {
String key;
String alias;
String regexCapture;
}

@Value
@Accessors(fluent = true)
private static class ConvertedCondition implements Condition {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import org.hypertrace.core.graphql.deserialization.ArgumentDeserializationConfig;
import org.hypertrace.graphql.label.schema.rule.Action;
import org.hypertrace.graphql.label.schema.rule.Condition;
import org.hypertrace.graphql.label.schema.rule.DynamicLabelExpression;
import org.hypertrace.graphql.label.schema.rule.LabelApplicationRule;
import org.hypertrace.graphql.label.schema.rule.LabelApplicationRuleData;
import org.hypertrace.graphql.label.schema.rule.LeafCondition;
import org.hypertrace.graphql.label.schema.rule.StaticLabels;
import org.hypertrace.graphql.label.schema.rule.StringCondition;
import org.hypertrace.graphql.label.schema.rule.TokenExtractionRule;
import org.hypertrace.graphql.label.schema.rule.UnaryCondition;
import org.hypertrace.graphql.label.schema.rule.ValueCondition;

Expand All @@ -38,6 +40,9 @@ public List<Module> jacksonModules() {
LabelApplicationRuleData.class, LabelApplicationRuleDataArgument.class)
.addAbstractTypeMapping(Action.class, ActionArgument.class)
.addAbstractTypeMapping(StaticLabels.class, StaticLabelsArgument.class)
.addAbstractTypeMapping(
DynamicLabelExpression.class, DynamicLabelExpressionArgument.class)
.addAbstractTypeMapping(TokenExtractionRule.class, TokenExtractionRuleArgument.class)
.addAbstractTypeMapping(Condition.class, ConditionArgument.class)
.addAbstractTypeMapping(LeafCondition.class, LeafConditionArgument.class)
.addAbstractTypeMapping(ValueCondition.class, ValueConditionArgument.class)
Expand Down Expand Up @@ -92,6 +97,9 @@ private static class ActionArgument implements Action {
@JsonProperty(DYNAMIC_LABEL_KEY_KEY)
String dynamicLabelKey;

@JsonProperty(DYNAMIC_LABEL_EXPRESSION_KEY)
DynamicLabelExpression dynamicLabelExpression;

@JsonProperty(ACTION_TYPE_KEY)
ActionType type;
}
Expand All @@ -104,6 +112,31 @@ private static class StaticLabelsArgument implements StaticLabels {
List<String> ids;
}

@Value
@Accessors(fluent = true)
@NoArgsConstructor(force = true)
private static class DynamicLabelExpressionArgument implements DynamicLabelExpression {
@JsonProperty(LABEL_EXPRESSION_KEY)
String labelExpression;

@JsonProperty(TOKEN_EXTRACTION_RULES_KEY)
List<TokenExtractionRule> tokenExtractionRules;
}

@Value
@Accessors(fluent = true)
@NoArgsConstructor(force = true)
private static class TokenExtractionRuleArgument implements TokenExtractionRule {
@JsonProperty(KEY_NAME)
String key;

@JsonProperty(ALIAS_KEY)
String alias;

@JsonProperty(REGEX_CAPTURE_KEY)
String regexCapture;
}

@Value
@Accessors(fluent = true)
@NoArgsConstructor(force = true)
Expand Down

0 comments on commit 3697588

Please sign in to comment.