From 5f9ef87d0cc82118bbac40bc49411c5e957165f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Hammarb=C3=A4ck?= Date: Tue, 15 Nov 2022 16:01:42 +0100 Subject: [PATCH] Introduced AggregateDefinitionClient. --- .../aggregate/AggregateDefinitionClient.java | 109 ++++++++++++++++++ .../aggregate/AggregateTypeDefinition.java | 83 +++++++++++++ .../aggregate/AggregateTypeDefinitions.java | 46 ++++++++ .../client/aggregate/AggregateTypeRule.java | 96 +++++++++++++++ .../projection/ProjectionDefinitions.java | 20 ++++ .../client/reaction/ReactionDefinitions.java | 20 ++++ 6 files changed, 374 insertions(+) create mode 100644 src/main/java/io/serialized/client/aggregate/AggregateDefinitionClient.java create mode 100644 src/main/java/io/serialized/client/aggregate/AggregateTypeDefinition.java create mode 100644 src/main/java/io/serialized/client/aggregate/AggregateTypeDefinitions.java create mode 100644 src/main/java/io/serialized/client/aggregate/AggregateTypeRule.java diff --git a/src/main/java/io/serialized/client/aggregate/AggregateDefinitionClient.java b/src/main/java/io/serialized/client/aggregate/AggregateDefinitionClient.java new file mode 100644 index 0000000..739fde4 --- /dev/null +++ b/src/main/java/io/serialized/client/aggregate/AggregateDefinitionClient.java @@ -0,0 +1,109 @@ +package io.serialized.client.aggregate; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.serialized.client.SerializedClientConfig; +import io.serialized.client.SerializedOkHttpClient; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; + +import java.io.IOException; +import java.util.function.Consumer; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; +import static com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS; + +public class AggregateDefinitionClient { + + private final SerializedOkHttpClient client; + private final HttpUrl apiRoot; + private final ObjectMapper objectMapper; + + private AggregateDefinitionClient(Builder builder) { + this.client = new SerializedOkHttpClient(builder.httpClient, builder.objectMapper); + this.apiRoot = builder.apiRoot; + this.objectMapper = builder.objectMapper; + } + + public static Builder aggregateClient(SerializedClientConfig config) { + return new Builder(config); + } + + /** + * Creates an aggregate type definition from a JSON String value. + * + * @param jsonString a JSON String with a valid definition + * @throws IOException if the given String is not a valid definition + */ + public void createDefinition(String jsonString) throws IOException { + AggregateTypeDefinition aggregateTypeDefinition = objectMapper.readValue(jsonString, AggregateTypeDefinition.class); + createDefinition(aggregateTypeDefinition); + } + + public void createDefinition(AggregateTypeDefinition aggregateTypeDefinition) { + HttpUrl url = pathForDefinitions().build(); + client.post(url, aggregateTypeDefinition); + } + + /** + * Get definition. + */ + public AggregateTypeDefinition getDefinition(String aggregateType) { + HttpUrl url = pathForDefinitions().addPathSegment(aggregateType).build(); + return client.get(url, AggregateTypeDefinition.class); + } + + /** + * List all definitions. + */ + public AggregateTypeDefinitions listDefinitions() { + HttpUrl url = pathForDefinitions().build(); + return client.get(url, AggregateTypeDefinitions.class); + } + + /** + * Delete the definition. + */ + public void deleteDefinition(String aggregateType) { + HttpUrl url = pathForDefinitions().addPathSegment(aggregateType).build(); + client.delete(url); + } + + private HttpUrl.Builder pathForDefinitions() { + return apiRoot.newBuilder() + .addPathSegment("aggregates") + .addPathSegment("definitions"); + } + + public static class Builder { + + private final ObjectMapper objectMapper = new ObjectMapper() + .disable(FAIL_ON_UNKNOWN_PROPERTIES) + .disable(FAIL_ON_EMPTY_BEANS) + .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) + .setSerializationInclusion(NON_NULL); + + private final HttpUrl apiRoot; + private final OkHttpClient httpClient; + + Builder(SerializedClientConfig config) { + this.apiRoot = config.apiRoot(); + this.httpClient = config.newHttpClient(); + } + + /** + * Allows object mapper customization. + */ + public Builder configureObjectMapper(Consumer consumer) { + consumer.accept(objectMapper); + return this; + } + + public AggregateDefinitionClient build() { + return new AggregateDefinitionClient(this); + } + } + +} diff --git a/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinition.java b/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinition.java new file mode 100644 index 0000000..abc3760 --- /dev/null +++ b/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinition.java @@ -0,0 +1,83 @@ +package io.serialized.client.aggregate; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Collections.unmodifiableList; +import static org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +public class AggregateTypeDefinition { + + private String aggregateType; + private String description; + private List rules; + + public String aggregateType() { + return aggregateType; + } + + public String description() { + return description; + } + + public List rules() { + return unmodifiableList(rules); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + + public static DefinitionBuilder newAggregateTypeDefinition(String aggregateType) { + return new DefinitionBuilder(aggregateType); + } + + public static class DefinitionBuilder { + private final String aggregateType; + private final List rules = new ArrayList<>(); + + private String description; + + DefinitionBuilder(String aggregateType) { + this.aggregateType = aggregateType; + } + + /** + * @param description Optional description + */ + public DefinitionBuilder description(String description) { + this.description = description; + return this; + } + + public DefinitionBuilder withRule(AggregateTypeRule rule) { + this.rules.add(rule); + return this; + } + + public AggregateTypeDefinition build() { + AggregateTypeDefinition definition = new AggregateTypeDefinition(); + definition.aggregateType = aggregateType; + definition.description = description; + definition.rules = rules; + return definition; + } + + } + +} diff --git a/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinitions.java b/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinitions.java new file mode 100644 index 0000000..e2e41bf --- /dev/null +++ b/src/main/java/io/serialized/client/aggregate/AggregateTypeDefinitions.java @@ -0,0 +1,46 @@ +package io.serialized.client.aggregate; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static java.util.Collections.emptyList; +import static java.util.Collections.unmodifiableList; +import static org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +public class AggregateTypeDefinitions { + + private List definitions; + private int totalCount; + private boolean hasMore; + + public static AggregateTypeDefinitions newDefinitionList(Collection definitions) { + AggregateTypeDefinitions reactionDefinitions = new AggregateTypeDefinitions(); + reactionDefinitions.definitions = new ArrayList<>(definitions); + return reactionDefinitions; + } + + public List definitions() { + return definitions == null ? emptyList() : unmodifiableList(definitions); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + +} diff --git a/src/main/java/io/serialized/client/aggregate/AggregateTypeRule.java b/src/main/java/io/serialized/client/aggregate/AggregateTypeRule.java new file mode 100644 index 0000000..95bd8f3 --- /dev/null +++ b/src/main/java/io/serialized/client/aggregate/AggregateTypeRule.java @@ -0,0 +1,96 @@ +package io.serialized.client.aggregate; + +import org.apache.commons.lang3.Validate; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.util.LinkedHashSet; +import java.util.Set; + +import static java.util.Collections.unmodifiableSet; +import static org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE; + +public class AggregateTypeRule { + + public enum Type { + UNIQUENESS + } + + private Type type; + private String eventType; + private final Set fields = new LinkedHashSet<>(); + + public static Builder rule(Type type) { + return new Builder(type); + } + + public static Builder newRule(Type type, String eventType, String... fields) { + Builder builder = new Builder(type).withEventType(eventType); + for (String field : fields) { + builder.addField(field); + } + return builder; + } + + public Type type() { + return type; + } + + public String eventType() { + return eventType; + } + + public Set fields() { + return unmodifiableSet(fields); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + + public static class Builder { + + private final Type type; + private final Set fields = new LinkedHashSet<>(); + private String eventType; + + public Builder(Type type) { + this.type = type; + } + + public Builder withEventType(String eventType) { + this.eventType = eventType; + return this; + } + + public Builder addField(String field) { + this.fields.add(field); + return this; + } + + public AggregateTypeRule build() { + Validate.notEmpty(eventType, "'eventType' must be set"); + Validate.notEmpty(fields, "At least one 'field' must be specified"); + + AggregateTypeRule aggregateTypeRule = new AggregateTypeRule(); + aggregateTypeRule.type = this.type; + aggregateTypeRule.eventType = this.eventType; + aggregateTypeRule.fields.addAll(this.fields); + return aggregateTypeRule; + } + + } + +} diff --git a/src/main/java/io/serialized/client/projection/ProjectionDefinitions.java b/src/main/java/io/serialized/client/projection/ProjectionDefinitions.java index 7bd6e95..b23f431 100644 --- a/src/main/java/io/serialized/client/projection/ProjectionDefinitions.java +++ b/src/main/java/io/serialized/client/projection/ProjectionDefinitions.java @@ -1,11 +1,16 @@ package io.serialized.client.projection; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + import java.util.ArrayList; import java.util.Collection; import java.util.List; import static java.util.Collections.emptyList; import static java.util.Collections.unmodifiableList; +import static org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE; public class ProjectionDefinitions { @@ -21,4 +26,19 @@ public List definitions() { return definitions == null ? emptyList() : unmodifiableList(definitions); } + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + } diff --git a/src/main/java/io/serialized/client/reaction/ReactionDefinitions.java b/src/main/java/io/serialized/client/reaction/ReactionDefinitions.java index d3aacc1..5ef3f61 100644 --- a/src/main/java/io/serialized/client/reaction/ReactionDefinitions.java +++ b/src/main/java/io/serialized/client/reaction/ReactionDefinitions.java @@ -1,11 +1,16 @@ package io.serialized.client.reaction; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + import java.util.ArrayList; import java.util.Collection; import java.util.List; import static java.util.Collections.emptyList; import static java.util.Collections.unmodifiableList; +import static org.apache.commons.lang3.builder.ToStringStyle.SHORT_PREFIX_STYLE; public class ReactionDefinitions { @@ -21,4 +26,19 @@ public List definitions() { return definitions == null ? emptyList() : unmodifiableList(definitions); } + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + }