-
Notifications
You must be signed in to change notification settings - Fork 7
Allow user to update system labels #270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b8943d0
071d313
c3ba749
31d669c
17c91b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| import java.util.Optional; | ||
| import java.util.UUID; | ||
| import java.util.concurrent.TimeUnit; | ||
| import java.util.function.Function; | ||
| import java.util.stream.Collectors; | ||
| import lombok.SneakyThrows; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
@@ -52,7 +53,6 @@ public class LabelsConfigServiceImpl extends LabelsConfigServiceGrpc.LabelsConfi | |
| private final LabelStore labelStore; | ||
| private final List<Label> systemLabels; | ||
| private final Map<String, Label> systemLabelsIdLabelMap; | ||
| private final Map<String, Label> systemLabelsKeyLabelMap; | ||
|
|
||
| public LabelsConfigServiceImpl( | ||
| Channel configChannel, Config config, ConfigChangeEventGenerator configChangeEventGenerator) { | ||
|
|
@@ -74,13 +74,9 @@ public LabelsConfigServiceImpl( | |
| systemLabels = buildSystemLabelList(systemLabelsObjectList); | ||
| systemLabelsIdLabelMap = | ||
| systemLabels.stream().collect(Collectors.toUnmodifiableMap(Label::getId, identity())); | ||
| systemLabelsKeyLabelMap = | ||
| systemLabels.stream() | ||
| .collect(Collectors.toUnmodifiableMap(label -> label.getData().getKey(), identity())); | ||
| } else { | ||
| systemLabels = Collections.emptyList(); | ||
| systemLabelsIdLabelMap = Collections.emptyMap(); | ||
| systemLabelsKeyLabelMap = Collections.emptyMap(); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -194,15 +190,13 @@ public void getLabel(GetLabelRequest request, StreamObserver<GetLabelResponse> r | |
| RequestContext requestContext = RequestContext.CURRENT.get(); | ||
| String labelId = request.getId(); | ||
| try { | ||
| Label label; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would need to make changes in almost all the methods available in this api. So the flow would be like this
|
||
| if (systemLabelsIdLabelMap.containsKey(labelId)) { | ||
| label = systemLabelsIdLabelMap.get(labelId); | ||
| } else { | ||
| label = | ||
| labelStore | ||
| .getData(requestContext, labelId) | ||
| .orElseThrow(Status.NOT_FOUND::asRuntimeException); | ||
| } | ||
| Label label = | ||
| labelStore | ||
| .getData(requestContext, labelId) | ||
| .orElseGet( | ||
| () -> | ||
| Optional.ofNullable(systemLabelsIdLabelMap.get(labelId)) | ||
| .orElseThrow(Status.NOT_FOUND::asRuntimeException)); | ||
| responseObserver.onNext(GetLabelResponse.newBuilder().setLabel(label).build()); | ||
| responseObserver.onCompleted(); | ||
| } catch (Exception e) { | ||
|
|
@@ -214,12 +208,17 @@ public void getLabel(GetLabelRequest request, StreamObserver<GetLabelResponse> r | |
| public void getLabels( | ||
| GetLabelsRequest request, StreamObserver<GetLabelsResponse> responseObserver) { | ||
| RequestContext requestContext = RequestContext.CURRENT.get(); | ||
| List<Label> allLabels = new ArrayList<>(systemLabels); | ||
| List<Label> tenantLabels = | ||
| labelStore.getAllObjects(requestContext).stream() | ||
| .map(ContextualConfigObject::getData) | ||
| .collect(Collectors.toUnmodifiableList()); | ||
| allLabels.addAll(tenantLabels); | ||
| Map<String, Label> tenantLabelsMap = | ||
| tenantLabels.stream() | ||
| .collect(Collectors.toUnmodifiableMap(Label::getId, Function.identity())); | ||
| List<Label> allLabels = new ArrayList<>(tenantLabels); | ||
| systemLabels.stream() | ||
| .filter(label -> !tenantLabelsMap.containsKey(label.getId())) | ||
| .forEach(allLabels::add); | ||
| responseObserver.onNext(GetLabelsResponse.newBuilder().addAllLabels(allLabels).build()); | ||
| responseObserver.onCompleted(); | ||
| } | ||
|
|
@@ -230,19 +229,18 @@ public void updateLabel( | |
| try { | ||
| LabelData updateLabelData = request.getData(); | ||
| RequestContext requestContext = RequestContext.CURRENT.get(); | ||
| if (systemLabelsIdLabelMap.containsKey(request.getId())) { | ||
| // Updating a system label will error | ||
| responseObserver.onError(new StatusRuntimeException(Status.INVALID_ARGUMENT)); | ||
| return; | ||
| } | ||
|
|
||
| if (isDuplicateKey(requestContext, request.getId(), updateLabelData.getKey())) { | ||
| responseObserver.onError(new StatusRuntimeException(Status.ALREADY_EXISTS)); | ||
| return; | ||
| } | ||
| Label oldLabel = | ||
| labelStore | ||
| .getData(requestContext, request.getId()) | ||
| .orElseThrow(Status.NOT_FOUND::asRuntimeException); | ||
| .orElseGet( | ||
| () -> | ||
| Optional.ofNullable(systemLabelsIdLabelMap.get(request.getId())) | ||
| .orElseThrow(Status.NOT_FOUND::asRuntimeException)); | ||
| Label updateLabel = oldLabel.toBuilder().setData(updateLabelData).build(); | ||
| Label updateLabelInRes = labelStore.upsertObject(requestContext, updateLabel).getData(); | ||
| responseObserver.onNext(UpdateLabelResponse.newBuilder().setLabel(updateLabelInRes).build()); | ||
|
|
@@ -284,10 +282,11 @@ private boolean isDuplicateKey(RequestContext requestContext, String key) { | |
| } | ||
|
|
||
| private Map<String, Label> getLabelsMap(RequestContext requestContext) { | ||
| Map<String, Label> existingLabelsMap = new HashMap<>(systemLabelsKeyLabelMap); | ||
| Map<String, Label> mergedLabels = new HashMap<>(systemLabelsIdLabelMap); | ||
| labelStore.getAllObjects(requestContext).stream() | ||
| .map(ContextualConfigObject::getData) | ||
| .forEach(label -> existingLabelsMap.put(label.getData().getKey(), label)); | ||
| return Collections.unmodifiableMap(existingLabelsMap); | ||
| .forEach(label -> mergedLabels.put(label.getId(), label)); | ||
| return mergedLabels.values().stream() | ||
| .collect(Collectors.toUnmodifiableMap(label -> label.getData().getKey(), identity())); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package org.hypertrace.label.config.service; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | ||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| import static org.junit.jupiter.api.Assertions.assertThrows; | ||
| import static org.mockito.Mockito.mock; | ||
|
|
@@ -329,25 +330,22 @@ void test_updateLabel() { | |
| @Test | ||
| void test_system_updateLabel() { | ||
| List<Label> createdLabelsList = createLabels(); | ||
| // updating system label key, should not throw error. | ||
| for (Label systemLabel : systemLabels) { | ||
| UpdateLabelRequest updateLabelRequest = | ||
| UpdateLabelRequest.newBuilder() | ||
| .setId(systemLabel.getId()) | ||
| .setData(LabelData.newBuilder().setKey("1").build()) | ||
| .setData(LabelData.newBuilder().setKey(systemLabel.getData().getKey() + "_1").build()) | ||
| .build(); | ||
| Throwable exception = | ||
| assertThrows( | ||
| StatusRuntimeException.class, | ||
| () -> { | ||
| labelConfigStub.updateLabel(updateLabelRequest); | ||
| }); | ||
| assertEquals(Status.INVALID_ARGUMENT, Status.fromThrowable(exception)); | ||
| assertDoesNotThrow(() -> labelConfigStub.updateLabel(updateLabelRequest)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this test case is wrong. we should add necessary validations |
||
| } | ||
|
|
||
| // updating existing label with updated system label key, should throw error. | ||
| for (Label systemLabel : systemLabels) { | ||
| UpdateLabelRequest updateLabelRequest = | ||
| UpdateLabelRequest.newBuilder() | ||
| .setId(createdLabelsList.get(0).getId()) | ||
| .setData(LabelData.newBuilder().setKey(systemLabel.getData().getKey()).build()) | ||
| .setData(LabelData.newBuilder().setKey(systemLabel.getData().getKey() + "_1").build()) | ||
| .build(); | ||
| Throwable exception = | ||
| assertThrows( | ||
|
|
@@ -357,6 +355,16 @@ void test_system_updateLabel() { | |
| }); | ||
| assertEquals(Status.ALREADY_EXISTS, Status.fromThrowable(exception)); | ||
| } | ||
|
|
||
| // updating existing label with system label keys present in config, should not throw error. | ||
| for (Label systemLabel : systemLabels) { | ||
| UpdateLabelRequest updateLabelRequest = | ||
| UpdateLabelRequest.newBuilder() | ||
| .setId(createdLabelsList.get(0).getId()) | ||
| .setData(LabelData.newBuilder().setKey(systemLabel.getData().getKey()).build()) | ||
| .build(); | ||
| assertDoesNotThrow(() -> labelConfigStub.updateLabel(updateLabelRequest)); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should fix isDuplicateKey function, Existing labels , id should be used to find duplicates, and then name should be unique. We need to fix this