Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions hypertrace-graphql-impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies {
implementation(project(":hypertrace-graphql-entity-type"))
implementation(project(":hypertrace-graphql-spaces-schema"))
implementation(project(":hypertrace-graphql-labels-schema"))
implementation(project(":hypertrace-graphql-label-application-rules-schema"))

implementation("org.slf4j:slf4j-api")
implementation("com.google.inject:guice")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.hypertrace.graphql.explorer.ExplorerSchemaModule;
import org.hypertrace.graphql.explorer.context.HypertraceExplorerContextModule;
import org.hypertrace.graphql.label.LabelSchemaModule;
import org.hypertrace.graphql.label.application.rules.LabelApplicationRuleSchemaModule;
import org.hypertrace.graphql.metric.MetricModule;
import org.hypertrace.graphql.spaces.SpacesSchemaModule;
import org.hypertrace.graphql.utils.metrics.gateway.GatewayMetricUtilsModule;
Expand Down Expand Up @@ -73,5 +74,6 @@ protected void configure() {
install(new SpacesSchemaModule());
install(new RequestTransformationModule());
install(new LabelSchemaModule());
install(new LabelApplicationRuleSchemaModule());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
plugins {
`java-library`
jacoco
id("org.hypertrace.jacoco-report-plugin")
}

dependencies {
api("com.google.inject:guice")
api("com.graphql-java:graphql-java")
api("org.hypertrace.core.graphql:hypertrace-core-graphql-spi")
api("io.github.graphql-java:graphql-java-annotations")
api("org.hypertrace.core.graphql:hypertrace-core-graphql-common-schema")

annotationProcessor("org.projectlombok:lombok")
compileOnly("org.projectlombok:lombok")

implementation("org.slf4j:slf4j-api")
implementation("io.reactivex.rxjava3:rxjava")
implementation("org.hypertrace.config.service:label-application-rule-config-service-api")
implementation("com.google.protobuf:protobuf-java-util")
implementation("com.google.guava:guava")

implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-context")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-grpc-utils")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-schema-utils")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-rx-utils")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-deserialization")

implementation(project(":hypertrace-graphql-service-config"))
}

tasks.test {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.hypertrace.graphql.label.application.rules;

import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
import org.hypertrace.graphql.label.application.rules.schema.mutation.LabelApplicationRuleMutationSchema;
import org.hypertrace.graphql.label.application.rules.schema.query.LabelApplicationRuleQuerySchema;

public class LabelApplicationRuleSchemaFragment implements GraphQlSchemaFragment {

@Override
public String fragmentName() {
return "Label Application Rules Schema";
}

@Override
public Class<LabelApplicationRuleQuerySchema> annotatedQueryClass() {
return LabelApplicationRuleQuerySchema.class;
}

@Override
public Class<?> annotatedMutationClass() {
return LabelApplicationRuleMutationSchema.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.hypertrace.graphql.label.application.rules;

import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
import org.hypertrace.graphql.label.application.rules.dao.LabelApplicationRuleDaoModule;
import org.hypertrace.graphql.label.application.rules.deserialization.LabelApplicationRuleDeserializationModule;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleRequestModule;

public class LabelApplicationRuleSchemaModule extends AbstractModule {
@Override
protected void configure() {
Multibinder.newSetBinder(binder(), GraphQlSchemaFragment.class)
.addBinding()
.to(LabelApplicationRuleSchemaFragment.class);

install(new LabelApplicationRuleDaoModule());
install(new LabelApplicationRuleRequestModule());
install(new LabelApplicationRuleDeserializationModule());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.hypertrace.graphql.label.application.rules.dao;

import io.grpc.CallCredentials;
import io.reactivex.rxjava3.core.Single;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import org.hypertrace.core.graphql.common.request.ContextualRequest;
import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry;
import org.hypertrace.core.graphql.utils.grpc.GrpcContextBuilder;
import org.hypertrace.graphql.config.HypertraceGraphQlServiceConfig;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleCreateRequest;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleUpdateRequest;
import org.hypertrace.graphql.label.application.rules.schema.query.LabelApplicationRuleResultSet;
import org.hypertrace.graphql.label.application.rules.schema.shared.LabelApplicationRule;
import org.hypertrace.label.application.rule.config.service.v1.GetLabelApplicationRulesRequest;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleConfigServiceGrpc;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleConfigServiceGrpc.LabelApplicationRuleConfigServiceFutureStub;

class LabelApplicationRuleConfigServiceDao implements LabelApplicationRuleDao {

private final LabelApplicationRuleConfigServiceFutureStub
labelApplicationRuleConfigServiceFutureStub;
private final GrpcContextBuilder grpcContextBuilder;
private final HypertraceGraphQlServiceConfig serviceConfig;
private final LabelApplicationRuleRequestConverter requestConverter;
private final LabelApplicationRuleResponseConverter responseConverter;

@Inject
LabelApplicationRuleConfigServiceDao(
HypertraceGraphQlServiceConfig serviceConfig,
CallCredentials credentials,
GrpcContextBuilder grpcContextBuilder,
GrpcChannelRegistry grpcChannelRegistry,
LabelApplicationRuleRequestConverter requestConverter,
LabelApplicationRuleResponseConverter responseConverter) {
this.grpcContextBuilder = grpcContextBuilder;
this.serviceConfig = serviceConfig;
this.requestConverter = requestConverter;
this.responseConverter = responseConverter;
this.labelApplicationRuleConfigServiceFutureStub =
LabelApplicationRuleConfigServiceGrpc.newFutureStub(
grpcChannelRegistry.forAddress(
serviceConfig.getConfigServiceHost(), serviceConfig.getConfigServicePort()))
.withCallCredentials(credentials);
}

@Override
public Single<LabelApplicationRule> createLabelApplicationRule(
LabelApplicationRuleCreateRequest request) {
return Single.fromFuture(
this.grpcContextBuilder
.build(request.context())
.call(
() ->
this.labelApplicationRuleConfigServiceFutureStub
.withDeadlineAfter(
serviceConfig.getConfigServiceTimeout().toMillis(),
TimeUnit.MILLISECONDS)
.createLabelApplicationRule(
this.requestConverter.convertCreationRequest(request))))
.flatMap(this.responseConverter::convertCreateLabelApplicationRuleResponse);
}

@Override
public Single<LabelApplicationRuleResultSet> getLabelApplicationRules(ContextualRequest request) {
return Single.fromFuture(
this.grpcContextBuilder
.build(request.context())
.call(
() ->
this.labelApplicationRuleConfigServiceFutureStub
.withDeadlineAfter(
serviceConfig.getConfigServiceTimeout().toMillis(),
TimeUnit.MILLISECONDS)
.getLabelApplicationRules(
GetLabelApplicationRulesRequest.getDefaultInstance())))
.flatMap(this.responseConverter::convertGetLabelApplicationsRuleResponse);
}

@Override
public Single<LabelApplicationRule> updateLabelApplicationRule(
LabelApplicationRuleUpdateRequest request) {
return Single.error(new UnsupportedOperationException("Not yet implemented"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.hypertrace.graphql.label.application.rules.dao;

import io.reactivex.rxjava3.core.Single;
import org.hypertrace.core.graphql.common.request.ContextualRequest;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleCreateRequest;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleUpdateRequest;
import org.hypertrace.graphql.label.application.rules.schema.query.LabelApplicationRuleResultSet;
import org.hypertrace.graphql.label.application.rules.schema.shared.LabelApplicationRule;

public interface LabelApplicationRuleDao {
Single<LabelApplicationRule> createLabelApplicationRule(
LabelApplicationRuleCreateRequest request);

Single<LabelApplicationRuleResultSet> getLabelApplicationRules(ContextualRequest request);

Single<LabelApplicationRule> updateLabelApplicationRule(
LabelApplicationRuleUpdateRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.hypertrace.graphql.label.application.rules.dao;

import com.google.inject.AbstractModule;
import io.grpc.CallCredentials;
import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig;
import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry;
import org.hypertrace.core.graphql.utils.grpc.GrpcContextBuilder;

public class LabelApplicationRuleDaoModule extends AbstractModule {
@Override
protected void configure() {
bind(LabelApplicationRuleDao.class).to(LabelApplicationRuleConfigServiceDao.class);
requireBinding(CallCredentials.class);
requireBinding(GraphQlServiceConfig.class);
requireBinding(GrpcChannelRegistry.class);
requireBinding(GrpcContextBuilder.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package org.hypertrace.graphql.label.application.rules.dao;

import java.util.stream.Collectors;
import org.hypertrace.graphql.label.application.rules.request.LabelApplicationRuleCreateRequest;
import org.hypertrace.label.application.rule.config.service.v1.CreateLabelApplicationRuleRequest;
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.CompositeCondition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.Condition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.LeafCondition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.StringCondition;
import org.hypertrace.label.application.rule.config.service.v1.LabelApplicationRuleData.UnaryCondition;

class LabelApplicationRuleRequestConverter {
CreateLabelApplicationRuleRequest convertCreationRequest(
LabelApplicationRuleCreateRequest labelApplicationRuleCreateRequest) {
org.hypertrace.graphql.label.application.rules.schema.shared.LabelApplicationRuleData data =
labelApplicationRuleCreateRequest
.createLabelApplicationRuleRequest()
.labelApplicationRuleData();
return CreateLabelApplicationRuleRequest.newBuilder()
.setData(
LabelApplicationRuleData.newBuilder()
.setName(data.name())
.setMatchingCondition(convertMatchingCondition(data.condition()))
.setLabelAction(convertLabelAction(data.action())))
.build();
}

Condition convertMatchingCondition(
org.hypertrace.graphql.label.application.rules.schema.shared.Condition condition) {
switch (condition.conditionType()) {
case LEAF_CONDITION:
return Condition.newBuilder()
.setLeafCondition(convertLeafCondition(condition.leafCondition()))
.build();
case COMPOSITE_CONDITION:
return Condition.newBuilder()
.setCompositeCondition(convertCompositeCondition(condition.compositeCondition()))
.build();
default:
throw new IllegalArgumentException("Error when parsing matching condition");
}
}

Action convertLabelAction(
org.hypertrace.graphql.label.application.rules.schema.shared.Action action) {
Action.Builder actionBuilder = Action.newBuilder().addAllEntityTypes(action.entityTypes());

switch (action.operation()) {
case OPERATION_MERGE:
actionBuilder.setOperation(Action.Operation.OPERATION_MERGE);
break;
default:
throw new IllegalArgumentException("Unsupported Operation");
}

switch (action.valueType()) {
case STATIC_LABELS:
return actionBuilder
.setStaticLabels(
Action.StaticLabels.newBuilder().addAllIds(action.staticLabels().ids()).build())
.build();
case DYNAMIC_LABEL_KEY:
return actionBuilder.setDynamicLabelKey(action.dynamicLabelKey()).build();
default:
throw new IllegalArgumentException("Unsupported action value");
}
}

CompositeCondition convertCompositeCondition(
org.hypertrace.graphql.label.application.rules.schema.shared.CompositeCondition
compositeCondition) {
CompositeCondition.Builder compositeConditionBuilder =
CompositeCondition.newBuilder()
.addAllChildren(
compositeCondition.children().stream()
.map(this::convertLeafCondition)
.map(
leafCondition ->
Condition.newBuilder().setLeafCondition(leafCondition).build())
.collect(Collectors.toList()));
switch (compositeCondition.operator()) {
case LOGICAL_OPERATOR_AND:
return compositeConditionBuilder
.setOperator(CompositeCondition.LogicalOperator.LOGICAL_OPERATOR_AND)
.build();
case LOGICAL_OPERATOR_OR:
return compositeConditionBuilder
.setOperator(CompositeCondition.LogicalOperator.LOGICAL_OPERATOR_OR)
.build();
default:
throw new IllegalArgumentException("Composite Condition Conversion Failed");
}
}

LeafCondition convertLeafCondition(
org.hypertrace.graphql.label.application.rules.schema.shared.LeafCondition leafCondition) {
LeafCondition.Builder leafConditionBuilder =
LeafCondition.newBuilder()
.setKeyCondition(convertStringCondition(leafCondition.keyCondition()));
switch (leafCondition.valueCondition().valueConditionType()) {
case STRING_CONDITION:
return leafConditionBuilder
.setStringCondition(
convertStringCondition(leafCondition.valueCondition().stringCondition()))
.build();
case UNARY_CONDITION:
return leafConditionBuilder
.setUnaryCondition(
convertUnaryCondition(leafCondition.valueCondition().unaryCondition()))
.build();
default:
throw new IllegalArgumentException("Unsupported Leaf Condition");
}
}

StringCondition convertStringCondition(
org.hypertrace.graphql.label.application.rules.schema.shared.StringCondition
stringCondition) {
return StringCondition.newBuilder()
.setOperator(convertStringConditionOperator(stringCondition.operator()))
.setValue(stringCondition.value())
.build();
}

UnaryCondition convertUnaryCondition(
org.hypertrace.graphql.label.application.rules.schema.shared.UnaryCondition unaryCondition) {
return UnaryCondition.newBuilder()
.setOperator(convertUnaryOperator(unaryCondition.operator()))
.build();
}

StringCondition.Operator convertStringConditionOperator(
org.hypertrace.graphql.label.application.rules.schema.shared.StringCondition.Operator
operator) {
switch (operator) {
case OPERATOR_EQUALS:
return StringCondition.Operator.OPERATOR_EQUALS;
case OPERATOR_MATCHES_REGEX:
return StringCondition.Operator.OPERATOR_MATCHES_REGEX;
default:
throw new IllegalArgumentException("Unsupported String Condition Operator");
}
}

UnaryCondition.Operator convertUnaryOperator(
org.hypertrace.graphql.label.application.rules.schema.shared.UnaryCondition.Operator
operator) {
switch (operator) {
case OPERATOR_EXISTS:
return UnaryCondition.Operator.OPERATOR_EXISTS;
default:
throw new IllegalArgumentException("Unsupported Unary Condition Operator");
}
}
}
Loading