Skip to content

Commit 3a2276f

Browse files
update exclude span rules apis to expose creation and last updated timestamp (#96)
* update exclude span rules apis to expose creation and last updated timestamp * impl changrs * cleanup * address review comments
1 parent 41ffc7f commit 3a2276f

File tree

5 files changed

+118
-21
lines changed

5 files changed

+118
-21
lines changed

span-processing-config-service-api/src/main/proto/org/hypertrace/span/processing/config/service/v1/span_processing_config_service.proto

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package org.hypertrace.span.processing.config.service.v1;
44

55
option java_multiple_files = true;
66

7+
import "google/protobuf/timestamp.proto";
8+
79
service SpanProcessingConfigService {
810
rpc CreateExcludeSpanRule(CreateExcludeSpanRuleRequest) returns (CreateExcludeSpanRuleResponse) {}
911

@@ -19,21 +21,21 @@ message CreateExcludeSpanRuleRequest {
1921
}
2022

2123
message CreateExcludeSpanRuleResponse {
22-
ExcludeSpanRule rule = 1;
24+
ExcludeSpanRuleDetails rule_details = 1;
2325
}
2426

2527
message GetAllExcludeSpanRulesRequest {}
2628

2729
message GetAllExcludeSpanRulesResponse {
28-
repeated ExcludeSpanRule rules = 1;
30+
repeated ExcludeSpanRuleDetails rule_details = 1;
2931
}
3032

3133
message UpdateExcludeSpanRuleRequest {
3234
UpdateExcludeSpanRule rule = 1;
3335
}
3436

3537
message UpdateExcludeSpanRuleResponse {
36-
ExcludeSpanRule rule = 1;
38+
ExcludeSpanRuleDetails rule_details = 1;
3739
}
3840

3941
message DeleteExcludeSpanRuleRequest {
@@ -47,11 +49,21 @@ message ExcludeSpanRule {
4749
ExcludeSpanRuleInfo rule_info = 2;
4850
}
4951

52+
message ExcludeSpanRuleDetails {
53+
ExcludeSpanRule rule = 1;
54+
ExcludeSpanRuleMetadata metadata = 2;
55+
}
56+
5057
message ExcludeSpanRuleInfo {
5158
string name = 1;
5259
SpanFilter filter = 2;
5360
}
5461

62+
message ExcludeSpanRuleMetadata {
63+
google.protobuf.Timestamp creation_timestamp = 1;
64+
google.protobuf.Timestamp last_updated_timestamp = 2;
65+
}
66+
5567
message UpdateExcludeSpanRule {
5668
string id = 1;
5769
string name = 2;

span-processing-config-service-impl/src/main/java/org/hypertrace/span/processing/config/service/SpanProcessingConfigServiceImpl.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
import io.grpc.stub.StreamObserver;
66
import java.util.UUID;
77
import lombok.extern.slf4j.Slf4j;
8+
import org.hypertrace.config.objectstore.ContextualConfigObject;
89
import org.hypertrace.core.grpcutils.context.RequestContext;
910
import org.hypertrace.span.processing.config.service.store.ExcludeSpanRulesConfigStore;
11+
import org.hypertrace.span.processing.config.service.utils.TimestampConverter;
1012
import org.hypertrace.span.processing.config.service.v1.CreateExcludeSpanRuleRequest;
1113
import org.hypertrace.span.processing.config.service.v1.CreateExcludeSpanRuleResponse;
1214
import org.hypertrace.span.processing.config.service.v1.DeleteExcludeSpanRuleRequest;
1315
import org.hypertrace.span.processing.config.service.v1.DeleteExcludeSpanRuleResponse;
1416
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRule;
17+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleDetails;
1518
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleInfo;
19+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleMetadata;
1620
import org.hypertrace.span.processing.config.service.v1.GetAllExcludeSpanRulesRequest;
1721
import org.hypertrace.span.processing.config.service.v1.GetAllExcludeSpanRulesResponse;
1822
import org.hypertrace.span.processing.config.service.v1.SpanProcessingConfigServiceGrpc;
@@ -26,13 +30,16 @@ class SpanProcessingConfigServiceImpl
2630
extends SpanProcessingConfigServiceGrpc.SpanProcessingConfigServiceImplBase {
2731
private final SpanProcessingConfigRequestValidator validator;
2832
private final ExcludeSpanRulesConfigStore ruleStore;
33+
private final TimestampConverter timestampConverter;
2934

3035
@Inject
3136
SpanProcessingConfigServiceImpl(
3237
ExcludeSpanRulesConfigStore ruleStore,
33-
SpanProcessingConfigRequestValidator requestValidator) {
38+
SpanProcessingConfigRequestValidator requestValidator,
39+
TimestampConverter timestampConverter) {
3440
this.validator = requestValidator;
3541
this.ruleStore = ruleStore;
42+
this.timestampConverter = timestampConverter;
3643
}
3744

3845
@Override
@@ -45,7 +52,7 @@ public void getAllExcludeSpanRules(
4552

4653
responseObserver.onNext(
4754
GetAllExcludeSpanRulesResponse.newBuilder()
48-
.addAllRules(ruleStore.getAllData(requestContext))
55+
.addAllRuleDetails(ruleStore.getAllData(requestContext))
4956
.build());
5057
responseObserver.onCompleted();
5158
} catch (Exception e) {
@@ -62,7 +69,7 @@ public void createExcludeSpanRule(
6269
RequestContext requestContext = RequestContext.CURRENT.get();
6370
this.validator.validateOrThrow(requestContext, request);
6471

65-
// TODO: need to handle prorities
72+
// TODO: need to handle priorities
6673
ExcludeSpanRule newRule =
6774
ExcludeSpanRule.newBuilder()
6875
.setId(UUID.randomUUID().toString())
@@ -71,7 +78,8 @@ public void createExcludeSpanRule(
7178

7279
responseObserver.onNext(
7380
CreateExcludeSpanRuleResponse.newBuilder()
74-
.setRule(this.ruleStore.upsertObject(requestContext, newRule).getData())
81+
.setRuleDetails(
82+
buildExcludeSpanRuleDetails(this.ruleStore.upsertObject(requestContext, newRule)))
7583
.build());
7684
responseObserver.onCompleted();
7785
} catch (Exception exception) {
@@ -97,7 +105,9 @@ public void updateExcludeSpanRule(
97105

98106
responseObserver.onNext(
99107
UpdateExcludeSpanRuleResponse.newBuilder()
100-
.setRule(this.ruleStore.upsertObject(requestContext, updatedRule).getData())
108+
.setRuleDetails(
109+
buildExcludeSpanRuleDetails(
110+
this.ruleStore.upsertObject(requestContext, updatedRule)))
101111
.build());
102112
responseObserver.onCompleted();
103113
} catch (Exception exception) {
@@ -137,4 +147,18 @@ private ExcludeSpanRule buildUpdatedRule(
137147
.build())
138148
.build();
139149
}
150+
151+
private ExcludeSpanRuleDetails buildExcludeSpanRuleDetails(
152+
ContextualConfigObject<ExcludeSpanRule> configObject) {
153+
return ExcludeSpanRuleDetails.newBuilder()
154+
.setRule(configObject.getData())
155+
.setMetadata(
156+
ExcludeSpanRuleMetadata.newBuilder()
157+
.setCreationTimestamp(
158+
timestampConverter.convert(configObject.getCreationTimestamp()))
159+
.setLastUpdatedTimestamp(
160+
timestampConverter.convert(configObject.getLastUpdatedTimestamp()))
161+
.build())
162+
.build();
163+
}
140164
}

span-processing-config-service-impl/src/main/java/org/hypertrace/span/processing/config/service/store/ExcludeSpanRulesConfigStore.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,49 @@
66
import java.util.Optional;
77
import java.util.stream.Collectors;
88
import lombok.SneakyThrows;
9-
import org.hypertrace.config.objectstore.ContextualConfigObject;
109
import org.hypertrace.config.objectstore.IdentifiedObjectStore;
1110
import org.hypertrace.config.proto.converter.ConfigProtoConverter;
1211
import org.hypertrace.config.service.v1.ConfigServiceGrpc;
1312
import org.hypertrace.core.grpcutils.context.RequestContext;
13+
import org.hypertrace.span.processing.config.service.utils.TimestampConverter;
1414
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRule;
15+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleDetails;
16+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleMetadata;
1517

1618
public class ExcludeSpanRulesConfigStore extends IdentifiedObjectStore<ExcludeSpanRule> {
1719

1820
private static final String EXCLUDE_SPAN_RULES_RESOURCE_NAME = "exclude-span-rules";
1921
private static final String EXCLUDE_SPAN_RULES_CONFIG_RESOURCE_NAMESPACE =
2022
"exclude-span-rules-config";
23+
private final TimestampConverter timestampConverter;
2124

2225
@Inject
2326
public ExcludeSpanRulesConfigStore(
24-
ConfigServiceGrpc.ConfigServiceBlockingStub configServiceBlockingStub) {
27+
ConfigServiceGrpc.ConfigServiceBlockingStub configServiceBlockingStub,
28+
TimestampConverter timestampConverter) {
2529
super(
2630
configServiceBlockingStub,
2731
EXCLUDE_SPAN_RULES_CONFIG_RESOURCE_NAMESPACE,
2832
EXCLUDE_SPAN_RULES_RESOURCE_NAME);
33+
this.timestampConverter = timestampConverter;
2934
}
3035

31-
public List<ExcludeSpanRule> getAllData(RequestContext requestContext) {
36+
public List<ExcludeSpanRuleDetails> getAllData(RequestContext requestContext) {
3237
return this.getAllObjects(requestContext).stream()
33-
.map(ContextualConfigObject::getData)
38+
.map(
39+
contextualConfigObject ->
40+
ExcludeSpanRuleDetails.newBuilder()
41+
.setRule(contextualConfigObject.getData())
42+
.setMetadata(
43+
ExcludeSpanRuleMetadata.newBuilder()
44+
.setCreationTimestamp(
45+
timestampConverter.convert(
46+
contextualConfigObject.getCreationTimestamp()))
47+
.setLastUpdatedTimestamp(
48+
timestampConverter.convert(
49+
contextualConfigObject.getLastUpdatedTimestamp()))
50+
.build())
51+
.build())
3452
.collect(Collectors.toUnmodifiableList());
3553
}
3654

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.hypertrace.span.processing.config.service.utils;
2+
3+
import com.google.protobuf.Timestamp;
4+
import java.time.Instant;
5+
6+
public class TimestampConverter {
7+
public Timestamp convert(Instant instant) {
8+
return Timestamp.newBuilder()
9+
.setSeconds(instant.toEpochMilli())
10+
.setNanos(instant.getNano())
11+
.build();
12+
}
13+
}

span-processing-config-service-impl/src/test/java/org/hypertrace/span/processing/config/service/SpanProcessingConfigServiceImplTest.java

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.when;
58

9+
import com.google.protobuf.Timestamp;
610
import java.util.List;
11+
import java.util.stream.Collectors;
712
import org.hypertrace.config.service.test.MockGenericConfigService;
813
import org.hypertrace.config.service.v1.ConfigServiceGrpc;
914
import org.hypertrace.span.processing.config.service.store.ExcludeSpanRulesConfigStore;
15+
import org.hypertrace.span.processing.config.service.utils.TimestampConverter;
1016
import org.hypertrace.span.processing.config.service.v1.CreateExcludeSpanRuleRequest;
1117
import org.hypertrace.span.processing.config.service.v1.DeleteExcludeSpanRuleRequest;
1218
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRule;
19+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleDetails;
1320
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleInfo;
1421
import org.hypertrace.span.processing.config.service.v1.Field;
1522
import org.hypertrace.span.processing.config.service.v1.GetAllExcludeSpanRulesRequest;
@@ -29,6 +36,7 @@ class SpanProcessingConfigServiceImplTest {
2936
SpanProcessingConfigServiceGrpc.SpanProcessingConfigServiceBlockingStub
3037
spanProcessingConfigServiceStub;
3138
MockGenericConfigService mockGenericConfigService;
39+
TimestampConverter timestampConverter;
3240

3341
@BeforeEach
3442
void beforeEach() {
@@ -43,15 +51,20 @@ void beforeEach() {
4351
ConfigServiceGrpc.ConfigServiceBlockingStub genericStub =
4452
ConfigServiceGrpc.newBlockingStub(this.mockGenericConfigService.channel());
4553

54+
this.timestampConverter = mock(TimestampConverter.class);
4655
this.mockGenericConfigService
4756
.addService(
4857
new SpanProcessingConfigServiceImpl(
49-
new ExcludeSpanRulesConfigStore(genericStub),
50-
new SpanProcessingConfigRequestValidator()))
58+
new ExcludeSpanRulesConfigStore(genericStub, this.timestampConverter),
59+
new SpanProcessingConfigRequestValidator(),
60+
this.timestampConverter))
5161
.start();
5262

5363
this.spanProcessingConfigServiceStub =
5464
SpanProcessingConfigServiceGrpc.newBlockingStub(this.mockGenericConfigService.channel());
65+
66+
when(this.timestampConverter.convert(any()))
67+
.thenReturn(Timestamp.newBuilder().setSeconds(100).build());
5568
}
5669

5770
@AfterEach
@@ -61,7 +74,7 @@ void afterEach() {
6174

6275
@Test
6376
void testCrud() {
64-
ExcludeSpanRule firstCreatedExcludeSpanRule =
77+
ExcludeSpanRuleDetails firstCreatedExcludeSpanRuleDetails =
6578
this.spanProcessingConfigServiceStub
6679
.createExcludeSpanRule(
6780
CreateExcludeSpanRuleRequest.newBuilder()
@@ -78,7 +91,14 @@ void testCrud() {
7891
.setRightOperand(
7992
SpanFilterValue.newBuilder().setStringValue("a")))))
8093
.build())
81-
.getRule();
94+
.getRuleDetails();
95+
ExcludeSpanRule firstCreatedExcludeSpanRule = firstCreatedExcludeSpanRuleDetails.getRule();
96+
Timestamp expectedTimestamp = Timestamp.newBuilder().setSeconds(100).build();
97+
assertEquals(
98+
expectedTimestamp, firstCreatedExcludeSpanRuleDetails.getMetadata().getCreationTimestamp());
99+
assertEquals(
100+
expectedTimestamp,
101+
firstCreatedExcludeSpanRuleDetails.getMetadata().getLastUpdatedTimestamp());
82102

83103
ExcludeSpanRule secondCreatedExcludeSpanRule =
84104
this.spanProcessingConfigServiceStub
@@ -97,13 +117,16 @@ void testCrud() {
97117
.setRightOperand(
98118
SpanFilterValue.newBuilder().setStringValue("a")))))
99119
.build())
120+
.getRuleDetails()
100121
.getRule();
101122

102123
List<ExcludeSpanRule> excludeSpanRules =
103124
this.spanProcessingConfigServiceStub
104-
.getAllExcludeSpanRules(
105-
GetAllExcludeSpanRulesRequest.newBuilder().build().newBuilder().build())
106-
.getRulesList();
125+
.getAllExcludeSpanRules(GetAllExcludeSpanRulesRequest.newBuilder().build())
126+
.getRuleDetailsList()
127+
.stream()
128+
.map(ExcludeSpanRuleDetails::getRule)
129+
.collect(Collectors.toUnmodifiableList());
107130
assertEquals(2, excludeSpanRules.size());
108131
assertTrue(excludeSpanRules.contains(firstCreatedExcludeSpanRule));
109132
assertTrue(excludeSpanRules.contains(secondCreatedExcludeSpanRule));
@@ -126,13 +149,17 @@ void testCrud() {
126149
.setRightOperand(
127150
SpanFilterValue.newBuilder().setStringValue("a")))))
128151
.build())
152+
.getRuleDetails()
129153
.getRule();
130154
assertEquals("updatedRuleName1", updatedFirstExcludeSpanRule.getRuleInfo().getName());
131155

132156
excludeSpanRules =
133157
this.spanProcessingConfigServiceStub
134158
.getAllExcludeSpanRules(GetAllExcludeSpanRulesRequest.newBuilder().build())
135-
.getRulesList();
159+
.getRuleDetailsList()
160+
.stream()
161+
.map(ExcludeSpanRuleDetails::getRule)
162+
.collect(Collectors.toUnmodifiableList());
136163
assertEquals(2, excludeSpanRules.size());
137164
assertTrue(excludeSpanRules.contains(updatedFirstExcludeSpanRule));
138165

@@ -144,7 +171,10 @@ void testCrud() {
144171
excludeSpanRules =
145172
this.spanProcessingConfigServiceStub
146173
.getAllExcludeSpanRules(GetAllExcludeSpanRulesRequest.newBuilder().build())
147-
.getRulesList();
174+
.getRuleDetailsList()
175+
.stream()
176+
.map(ExcludeSpanRuleDetails::getRule)
177+
.collect(Collectors.toUnmodifiableList());
148178
assertEquals(1, excludeSpanRules.size());
149179
assertEquals(secondCreatedExcludeSpanRule, excludeSpanRules.get(0));
150180
}

0 commit comments

Comments
 (0)