Skip to content

Commit bc29e73

Browse files
Introduce update and delete methods to the AttributeStore (#122)
1 parent c3b3473 commit bc29e73

File tree

7 files changed

+133
-2
lines changed

7 files changed

+133
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.hypertrace.core.graphql.attributes;
2+
3+
import lombok.Builder;
4+
import lombok.Value;
5+
import lombok.experimental.Accessors;
6+
7+
@Value
8+
@Builder
9+
@Accessors(fluent = true)
10+
public class AttributeIdentifier {
11+
String scope;
12+
String key;
13+
}

hypertrace-core-graphql-attribute-store/src/main/java/org/hypertrace/core/graphql/attributes/AttributeStore.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,11 @@ Single<AttributeModel> getForeignIdAttribute(
1717
GraphQlRequestContext context, String scope, String foreignScope);
1818

1919
Completable create(final GraphQlRequestContext context, final List<AttributeMetadata> attributes);
20+
21+
Completable delete(final GraphQlRequestContext context, final AttributeIdentifier identifier);
22+
23+
Single<AttributeModel> update(
24+
final GraphQlRequestContext context,
25+
final AttributeIdentifier identifier,
26+
final AttributeUpdate update);
2027
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.hypertrace.core.graphql.attributes;
2+
3+
import static java.util.stream.Collectors.toUnmodifiableList;
4+
5+
import java.util.List;
6+
import java.util.Objects;
7+
import java.util.Optional;
8+
import java.util.function.BiFunction;
9+
import java.util.function.Function;
10+
import javax.annotation.Nullable;
11+
import lombok.Builder;
12+
import lombok.Value;
13+
import lombok.experimental.Accessors;
14+
import org.hypertrace.core.attribute.service.v1.Update;
15+
16+
@Value
17+
@Builder
18+
@Accessors(fluent = true)
19+
public class AttributeUpdate {
20+
private static final List<UpdateMapper<?>> MAPPER_LIST =
21+
List.of(new UpdateMapper<>(AttributeUpdate::displayName, Update.Builder::setDisplayName));
22+
23+
@Nullable String displayName;
24+
25+
List<Update> buildUpdates() {
26+
return MAPPER_LIST.stream()
27+
.map(mapper -> mapper.apply(this))
28+
.flatMap(Optional::stream)
29+
.collect(toUnmodifiableList());
30+
}
31+
32+
@Value
33+
private static class UpdateMapper<T> implements Function<AttributeUpdate, Optional<Update>> {
34+
Function<AttributeUpdate, T> valueAccessor;
35+
BiFunction<Update.Builder, T, Update.Builder> valueSetter;
36+
37+
@Override
38+
public Optional<Update> apply(final AttributeUpdate attributeUpdate) {
39+
final T value = valueAccessor.apply(attributeUpdate);
40+
if (Objects.isNull(value)) {
41+
return Optional.empty();
42+
}
43+
44+
final Update.Builder builder = Update.newBuilder();
45+
final Update update = valueSetter.apply(builder, value).build();
46+
return Optional.of(update);
47+
}
48+
}
49+
}

hypertrace-core-graphql-attribute-store/src/main/java/org/hypertrace/core/graphql/attributes/CachingAttributeStore.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import javax.inject.Singleton;
1010
import org.hypertrace.core.attribute.service.cachingclient.CachingAttributeClient;
1111
import org.hypertrace.core.attribute.service.v1.AttributeMetadata;
12+
import org.hypertrace.core.attribute.service.v1.AttributeMetadataFilter;
1213
import org.hypertrace.core.graphql.context.GraphQlRequestContext;
1314
import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig;
1415
import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry;
@@ -94,6 +95,32 @@ public Completable create(
9495
.call(() -> cachingAttributeClient.create(attributes));
9596
}
9697

98+
@Override
99+
public Completable delete(
100+
final GraphQlRequestContext context, final AttributeIdentifier identifier) {
101+
return this.grpcContextBuilder
102+
.build(context)
103+
.call(() -> cachingAttributeClient.delete(buildFilter(identifier)));
104+
}
105+
106+
@Override
107+
public Single<AttributeModel> update(
108+
final GraphQlRequestContext context,
109+
final AttributeIdentifier identifier,
110+
final AttributeUpdate update) {
111+
final Single<AttributeModel> metadataSingle =
112+
get(context, identifier.scope(), identifier.key());
113+
return metadataSingle.flatMap(
114+
metadata ->
115+
this.grpcContextBuilder
116+
.build(context)
117+
.call(() -> cachingAttributeClient.update(metadata.id(), update.buildUpdates()))
118+
.mapOptional(translator::translate)
119+
.switchIfEmpty(
120+
Single.error(
121+
this.buildErrorForMissingAttribute(identifier.scope(), identifier.key()))));
122+
}
123+
97124
private Single<String> getForeignIdKey(
98125
GraphQlRequestContext context, String scope, String foreignScope) {
99126
return this.idLookup
@@ -125,4 +152,11 @@ private NoSuchElementException buildErrorForMissingIdMapping(String scope) {
125152
return new NoSuchElementException(
126153
String.format("No id attribute registered for scope '%s'", scope));
127154
}
155+
156+
private AttributeMetadataFilter buildFilter(final AttributeIdentifier filter) {
157+
return AttributeMetadataFilter.newBuilder()
158+
.addKey(filter.key())
159+
.addScopeString(filter.scope())
160+
.build();
161+
}
128162
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.hypertrace.core.graphql.utils.gateway;
2+
3+
import io.reactivex.rxjava3.core.Single;
4+
import javax.inject.Inject;
5+
import org.hypertrace.core.graphql.attributes.AttributeModel;
6+
import org.hypertrace.core.graphql.common.utils.Converter;
7+
import org.hypertrace.gateway.service.v1.common.Expression;
8+
import org.hypertrace.gateway.service.v1.common.Expression.Builder;
9+
10+
class ColumnIdentifierExpressionConverter implements Converter<AttributeModel, Expression> {
11+
12+
private final ColumnIdentifierConverter constantConverter;
13+
14+
@Inject
15+
public ColumnIdentifierExpressionConverter(final ColumnIdentifierConverter constantConverter) {
16+
this.constantConverter = constantConverter;
17+
}
18+
19+
@Override
20+
public Single<Expression> convert(final AttributeModel model) {
21+
return this.constantConverter
22+
.convert(model)
23+
.map(Expression.newBuilder()::setColumnIdentifier)
24+
.map(Builder::build);
25+
}
26+
}

hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ protected void configure() {
6161

6262
bind(Key.get(new TypeLiteral<Converter<AttributeModel, ColumnIdentifier>>() {}))
6363
.to(ColumnIdentifierConverter.class);
64+
bind(Key.get(new TypeLiteral<Converter<AttributeModel, Expression>>() {}))
65+
.to(ColumnIdentifierExpressionConverter.class);
6466
bind(Key.get(
6567
new TypeLiteral<Converter<AttributeAssociation<AttributeExpression>, Expression>>() {}))
6668
.to(AttributeExpressionConverter.class);

hypertrace-core-graphql-platform/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ javaPlatform {
66
allowDependencies()
77
}
88

9-
val attributeServiceVersion: String = "0.14.13"
9+
val attributeServiceVersion: String = "0.14.14"
1010

1111
dependencies {
1212
api(platform("io.grpc:grpc-bom:1.47.0"))
@@ -16,7 +16,7 @@ dependencies {
1616
api("org.hypertrace.core.grpcutils:grpc-client-utils:0.8.2")
1717
api("org.hypertrace.core.grpcutils:grpc-client-rx-utils:0.8.2")
1818
api("org.hypertrace.core.grpcutils:grpc-client-rx-utils:0.8.2")
19-
api("org.hypertrace.gateway.service:gateway-service-api:0.2.15")
19+
api("org.hypertrace.gateway.service:gateway-service-api:0.2.20")
2020
api("org.hypertrace.core.attribute.service:caching-attribute-service-client:${attributeServiceVersion}")
2121
api("org.hypertrace.core.attribute.service:attribute-service-api:${attributeServiceVersion}")
2222

0 commit comments

Comments
 (0)