diff --git a/labels-config-service-api/src/main/proto/org/hypertrace/label/config/service/v1/labels_config_service.proto b/labels-config-service-api/src/main/proto/org/hypertrace/label/config/service/v1/labels_config_service.proto index be57bc20..9fad2811 100644 --- a/labels-config-service-api/src/main/proto/org/hypertrace/label/config/service/v1/labels_config_service.proto +++ b/labels-config-service-api/src/main/proto/org/hypertrace/label/config/service/v1/labels_config_service.proto @@ -11,6 +11,9 @@ service LabelsConfigService { // create label rpc CreateLabel(CreateLabelRequest) returns (CreateLabelResponse) {} + // get or create labels + rpc GetOrCreateLabels(GetOrCreateLabelsRequest) returns (GetOrCreateLabelsResponse) {} + // get label by id rpc GetLabel(GetLabelRequest) returns (GetLabelResponse) {} @@ -34,6 +37,19 @@ message CreateLabelResponse { Label label = 1; } +message GetOrCreateLabelsRequest { + repeated LabelRequest requests = 1; + + message LabelRequest { + LabelData data = 1; + optional string created_by_application_rule_id = 2; + } +} + +message GetOrCreateLabelsResponse { + repeated Label labels = 1; +} + message GetLabelRequest { string id = 1; } diff --git a/labels-config-service-impl/src/main/java/org/hypertrace/label/config/service/LabelsConfigServiceImpl.java b/labels-config-service-impl/src/main/java/org/hypertrace/label/config/service/LabelsConfigServiceImpl.java index a89e689f..c24f49ea 100644 --- a/labels-config-service-impl/src/main/java/org/hypertrace/label/config/service/LabelsConfigServiceImpl.java +++ b/labels-config-service-impl/src/main/java/org/hypertrace/label/config/service/LabelsConfigServiceImpl.java @@ -1,5 +1,7 @@ package org.hypertrace.label.config.service; +import static java.util.function.Function.identity; + import com.google.common.util.concurrent.Striped; import com.google.protobuf.Duration; import com.google.protobuf.util.JsonFormat; @@ -11,12 +13,12 @@ import io.grpc.stub.StreamObserver; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; -import java.util.function.Function; import java.util.stream.Collectors; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -33,6 +35,8 @@ import org.hypertrace.label.config.service.v1.GetLabelResponse; import org.hypertrace.label.config.service.v1.GetLabelsRequest; import org.hypertrace.label.config.service.v1.GetLabelsResponse; +import org.hypertrace.label.config.service.v1.GetOrCreateLabelsRequest; +import org.hypertrace.label.config.service.v1.GetOrCreateLabelsResponse; import org.hypertrace.label.config.service.v1.Label; import org.hypertrace.label.config.service.v1.LabelData; import org.hypertrace.label.config.service.v1.LabelsConfigServiceGrpc; @@ -71,13 +75,11 @@ public LabelsConfigServiceImpl( if (systemLabelsObjectList != null) { systemLabels = buildSystemLabelList(systemLabelsObjectList); systemLabelsIdLabelMap = - systemLabels.stream() - .collect(Collectors.toUnmodifiableMap(Label::getId, Function.identity())); + systemLabels.stream().collect(Collectors.toUnmodifiableMap(Label::getId, identity())); systemLabelsKeyLabelMap = systemLabels.stream() .collect( - Collectors.toUnmodifiableMap( - (label) -> label.getData().getKey(), Function.identity())); + Collectors.toUnmodifiableMap((label) -> label.getData().getKey(), identity())); } else { systemLabels = Collections.emptyList(); systemLabelsIdLabelMap = Collections.emptyMap(); @@ -108,8 +110,7 @@ public void createLabel( if (labelsLock.tryLock(WAIT_TIME.getSeconds(), TimeUnit.SECONDS)) { try { LabelData labelData = request.getData(); - if (systemLabelsKeyLabelMap.containsKey(labelData.getKey()) - || isDuplicateKey(labelData.getKey())) { + if (isDuplicateKey(requestContext, labelData.getKey())) { // Creating a label with a name that clashes with one of system labels name responseObserver.onError(new StatusRuntimeException(Status.ALREADY_EXISTS)); return; @@ -136,6 +137,66 @@ public void createLabel( } } + @Override + public void getOrCreateLabels( + GetOrCreateLabelsRequest request, + StreamObserver responseObserver) { + try { + RequestContext requestContext = RequestContext.CURRENT.get(); + Lock labelsLock = this.stripedLabelsLock.get(requestContext.getTenantId()); + if (labelsLock.tryLock(WAIT_TIME.getSeconds(), TimeUnit.SECONDS)) { + try { + final Map existingLabelsMap = getLabelsMap(requestContext); + List