Skip to content

Commit 6a1c623

Browse files
committed
Refactored MetricsDefinition to use a MetricBuilder and be based off a super class
1 parent 2713006 commit 6a1c623

File tree

9 files changed

+225
-85
lines changed

9 files changed

+225
-85
lines changed

gradle.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# The --add-exports flags work around a bug with spotless and JDK 17
2+
# https://github.com/diffplug/spotless/issues/834
3+
org.gradle.jvmargs=-Xmx2g \
4+
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
5+
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
6+
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
7+
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
8+
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricDefinition.java renamed to src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricBuilder.java

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,70 +16,65 @@
1616

1717
package software.amazon.cloudwatchlogs.emf.model;
1818

19-
import com.fasterxml.jackson.annotation.JsonIgnore;
2019
import com.fasterxml.jackson.annotation.JsonInclude;
2120
import com.fasterxml.jackson.annotation.JsonProperty;
2221
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2322
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
24-
import java.util.ArrayList;
25-
import java.util.Arrays;
26-
import java.util.List;
27-
import lombok.AllArgsConstructor;
2823
import lombok.Getter;
29-
import lombok.NonNull;
30-
import lombok.Setter;
3124
import software.amazon.cloudwatchlogs.emf.serializers.StorageResolutionFilter;
3225
import software.amazon.cloudwatchlogs.emf.serializers.StorageResolutionSerializer;
3326
import software.amazon.cloudwatchlogs.emf.serializers.UnitDeserializer;
3427
import software.amazon.cloudwatchlogs.emf.serializers.UnitSerializer;
3528

36-
/** Represents the MetricDefinition of the EMF schema. */
37-
@AllArgsConstructor
38-
class MetricDefinition {
39-
@NonNull
29+
/** Abstract immutable (except for name) class that all Metrics are based on. */
30+
abstract class Metric {
4031
@Getter
4132
@JsonProperty("Name")
42-
private String name;
33+
protected String name;
4334

4435
@Getter
4536
@JsonProperty("Unit")
4637
@JsonSerialize(using = UnitSerializer.class)
4738
@JsonDeserialize(using = UnitDeserializer.class)
48-
private Unit unit;
39+
protected Unit unit;
4940

5041
@Getter
51-
@Setter
5242
@JsonProperty("StorageResolution")
5343
@JsonInclude(
5444
value = JsonInclude.Include.CUSTOM,
5545
valueFilter =
5646
StorageResolutionFilter.class) // Do not serialize when valueFilter is true
5747
@JsonSerialize(using = StorageResolutionSerializer.class)
58-
public StorageResolution storageResolution;
48+
protected StorageResolution storageResolution;
5949

60-
@JsonIgnore @NonNull @Getter private List<Double> values;
61-
62-
MetricDefinition(String name) {
63-
this(name, Unit.NONE, StorageResolution.STANDARD, new ArrayList<>());
64-
}
65-
66-
MetricDefinition(String name, double value) {
67-
this(name, Unit.NONE, StorageResolution.STANDARD, value);
68-
}
69-
70-
MetricDefinition(String name, Unit unit, double value) {
71-
this(name, unit, StorageResolution.STANDARD, new ArrayList<>(Arrays.asList(value)));
50+
/**
51+
* Change the name of this metric. Should only be used within this package in MetricContext when
52+
* recieving an unnamed metric from a user.
53+
*
54+
* @param name The new metric name.
55+
*/
56+
protected void setName(String name) {
57+
if (name == null) {
58+
throw new NullPointerException("Metric name cannot be null");
59+
}
60+
this.name = name;
7261
}
62+
}
7363

74-
MetricDefinition(String name, StorageResolution storageResolution, double value) {
75-
this(name, Unit.NONE, storageResolution, new ArrayList<>(Arrays.asList(value)));
76-
}
64+
/** Interface that allows metrics to be built from. */
65+
interface MetricBuilder {
7766

78-
MetricDefinition(String name, Unit unit, StorageResolution storageResolution, double value) {
79-
this(name, unit, storageResolution, new ArrayList<>(Arrays.asList(value)));
80-
}
67+
/**
68+
* Adds a value to the metric.
69+
*
70+
* @param value the value to be added to this metric
71+
*/
72+
void addValue(double value);
8173

82-
void addValue(double value) {
83-
values.add(value);
84-
}
74+
/**
75+
* Builds the metric.
76+
*
77+
* @return the built metric
78+
*/
79+
Metric build();
8580
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package software.amazon.cloudwatchlogs.emf.model;
18+
19+
import com.fasterxml.jackson.annotation.JsonIgnore;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.List;
23+
import lombok.Getter;
24+
import lombok.NonNull;
25+
26+
/** Represents the MetricDefinition of the EMF schema. */
27+
class MetricDefinition extends Metric {
28+
@JsonIgnore @NonNull @Getter protected List<Double> values;
29+
30+
MetricDefinition(Unit unit, StorageResolution storageResolution, List<Double> values) {
31+
this.unit = unit;
32+
this.storageResolution = storageResolution;
33+
this.values = values;
34+
}
35+
36+
MetricDefinition(
37+
String name, Unit unit, StorageResolution storageResolution, List<Double> values) {
38+
this.unit = unit;
39+
this.storageResolution = storageResolution;
40+
this.values = values;
41+
this.name = name;
42+
}
43+
44+
MetricDefinition(String name, Unit unit, StorageResolution storageResolution, Double value) {
45+
this.unit = unit;
46+
this.storageResolution = storageResolution;
47+
this.values = Arrays.asList(value);
48+
this.name = name;
49+
}
50+
}
51+
52+
/** Builds MetricDefinition */
53+
public class MetricDefinitionBuilder extends MetricDefinition implements MetricBuilder {
54+
55+
MetricDefinitionBuilder(Unit unit, StorageResolution storageResolution, List<Double> values) {
56+
super(unit, storageResolution, values);
57+
}
58+
59+
protected MetricDefinitionBuilder(
60+
String Name, Unit unit, StorageResolution storageResolution, Double value) {
61+
this(unit, storageResolution, Arrays.asList(value));
62+
setName(name);
63+
}
64+
65+
MetricDefinitionBuilder(Unit unit, StorageResolution storageResolution) {
66+
this(unit, storageResolution, new ArrayList<>());
67+
}
68+
69+
MetricDefinitionBuilder() {
70+
this(Unit.NONE, StorageResolution.STANDARD, new ArrayList<>());
71+
}
72+
73+
MetricDefinitionBuilder(double value) {
74+
this(Unit.NONE, StorageResolution.STANDARD, value);
75+
}
76+
77+
MetricDefinitionBuilder(Unit unit, double value) {
78+
this(unit, StorageResolution.STANDARD, new ArrayList<>(Arrays.asList(value)));
79+
}
80+
81+
MetricDefinitionBuilder(StorageResolution storageResolution, double value) {
82+
this(Unit.NONE, storageResolution, new ArrayList<>(Arrays.asList(value)));
83+
}
84+
85+
MetricDefinitionBuilder(Unit unit, StorageResolution storageResolution, double value) {
86+
this(unit, storageResolution, new ArrayList<>(Arrays.asList(value)));
87+
}
88+
89+
/** @return a built version of this metric. */
90+
public MetricDefinition build() {
91+
return (MetricDefinition) this;
92+
}
93+
94+
/** @param value a value to add to the metric. */
95+
public void addValue(double value) {
96+
this.values.add(value);
97+
}
98+
}

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricDirective.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class MetricDirective {
3232
@JsonProperty("Namespace")
3333
private String namespace;
3434

35-
@JsonIgnore @Setter @Getter @With private Map<String, MetricDefinition> metrics;
35+
@JsonIgnore @Setter @Getter @With private Map<String, Metric> metrics;
3636

3737
@JsonIgnore
3838
@Getter(AccessLevel.PROTECTED)
@@ -85,16 +85,23 @@ void putMetric(String key, double value, Unit unit, StorageResolution storageRes
8585
metrics.compute(
8686
key,
8787
(k, v) -> {
88-
if (v == null) return new MetricDefinition(key, unit, storageResolution, value);
89-
else {
90-
v.addValue(value);
88+
if (v == null) {
89+
MetricDefinitionBuilder tmp =
90+
new MetricDefinitionBuilder(unit, storageResolution, value);
91+
tmp.setName(key);
92+
return (Metric) tmp;
93+
} else if (v instanceof MetricBuilder) {
94+
((MetricBuilder) v).addValue(value);
9195
return v;
96+
} else {
97+
throw new IllegalStateException("Metric already exists and is Immuatble");
9298
}
9399
});
94100
}
95101

96102
@JsonProperty("Metrics")
97-
Collection<MetricDefinition> getAllMetrics() {
103+
Collection<Metric> getAllMetrics() {
104+
Collection<Metric> collection = new ArrayList<Metric>();
98105
return metrics.values();
99106
}
100107

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricsContext.java

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -323,40 +323,46 @@ public List<String> serialize() throws JsonProcessingException {
323323
return Arrays.asList(this.rootNode.serialize());
324324
} else {
325325
List<RootNode> nodes = new ArrayList<>();
326-
Map<String, MetricDefinition> metrics = new HashMap<>();
327-
Queue<MetricDefinition> metricDefinitions =
328-
new LinkedList<>(rootNode.metrics().values());
326+
Map<String, Metric> metrics = new HashMap<>();
327+
Queue<Metric> metricDefinitions = new LinkedList<>(rootNode.metrics().values());
329328
while (!metricDefinitions.isEmpty()) {
330-
MetricDefinition metric = metricDefinitions.poll();
329+
Metric metric = metricDefinitions.poll();
331330

332331
if (metrics.size() == Constants.MAX_METRICS_PER_EVENT
333332
|| metrics.containsKey(metric.getName())) {
334333
nodes.add(buildRootNode(metrics));
335334
metrics = new HashMap<>();
336335
}
337336

338-
if (metric.getValues().size() <= Constants.MAX_DATAPOINTS_PER_METRIC) {
339-
metrics.put(metric.getName(), metric);
340-
} else {
341-
metrics.put(
342-
metric.getName(),
343-
new MetricDefinition(
344-
metric.getName(),
345-
metric.getUnit(),
346-
metric.getStorageResolution(),
347-
metric.getValues()
348-
.subList(0, Constants.MAX_DATAPOINTS_PER_METRIC)));
349-
metricDefinitions.offer(
350-
new MetricDefinition(
351-
metric.getName(),
352-
metric.getUnit(),
353-
metric.getStorageResolution(),
354-
metric.getValues()
355-
.subList(
356-
Constants.MAX_DATAPOINTS_PER_METRIC,
357-
metric.getValues().size())));
337+
if (metric instanceof MetricDefinition) {
338+
MetricDefinition metricDefinition = (MetricDefinition) metric;
339+
if (metricDefinition.getValues().size()
340+
<= Constants.MAX_DATAPOINTS_PER_METRIC) {
341+
metrics.put(metricDefinition.getName(), metricDefinition);
342+
} else {
343+
metrics.put(
344+
metricDefinition.getName(),
345+
new MetricDefinition(
346+
metricDefinition.getName(),
347+
metricDefinition.getUnit(),
348+
metricDefinition.getStorageResolution(),
349+
metricDefinition
350+
.getValues()
351+
.subList(0, Constants.MAX_DATAPOINTS_PER_METRIC)));
352+
metricDefinitions.offer(
353+
new MetricDefinition(
354+
metricDefinition.getName(),
355+
metricDefinition.getUnit(),
356+
metricDefinition.getStorageResolution(),
357+
metricDefinition
358+
.getValues()
359+
.subList(
360+
Constants.MAX_DATAPOINTS_PER_METRIC,
361+
metricDefinition.getValues().size())));
362+
}
358363
}
359364
}
365+
360366
if (!metrics.isEmpty()) {
361367
nodes.add(buildRootNode(metrics));
362368
}
@@ -368,7 +374,7 @@ public List<String> serialize() throws JsonProcessingException {
368374
}
369375
}
370376

371-
private RootNode buildRootNode(Map<String, MetricDefinition> metrics) {
377+
private RootNode buildRootNode(Map<String, Metric> metrics) {
372378
Metadata metadata = rootNode.getAws();
373379
MetricDirective md = metadata.getCloudWatchMetrics().get(0);
374380
Metadata clonedMetadata =
@@ -379,6 +385,9 @@ private RootNode buildRootNode(Map<String, MetricDefinition> metrics) {
379385
private boolean anyMetricWithTooManyDataPoints(RootNode node) {
380386
return node.metrics().values().stream()
381387
.anyMatch(
382-
metric -> metric.getValues().size() > Constants.MAX_DATAPOINTS_PER_METRIC);
388+
metric ->
389+
metric instanceof MetricDefinition
390+
&& ((MetricDefinition) metric).getValues().size()
391+
> Constants.MAX_DATAPOINTS_PER_METRIC);
383392
}
384393
}

src/main/java/software/amazon/cloudwatchlogs/emf/model/RootNode.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,16 @@ Map<String, Object> getTargetMembers() throws DimensionSetExceededException {
6666
targetMembers.putAll(properties);
6767
targetMembers.putAll(getDimensions());
6868
for (MetricDirective metricDirective : aws.getCloudWatchMetrics()) {
69-
for (MetricDefinition metric : metricDirective.getMetrics().values()) {
70-
List<Double> values = metric.getValues();
71-
targetMembers.put(metric.getName(), values.size() == 1 ? values.get(0) : values);
69+
for (Metric metric : metricDirective.getMetrics().values()) {
70+
if (metric instanceof MetricDefinition) {
71+
List<Double> values = ((MetricDefinition) metric).getValues();
72+
targetMembers.put(
73+
metric.getName(), values.size() == 1 ? values.get(0) : values);
74+
} else if (metric instanceof MetricDefinitionBuilder) {
75+
List<Double> values = ((MetricDefinitionBuilder) metric).getValues();
76+
targetMembers.put(
77+
metric.getName(), values.size() == 1 ? values.get(0) : values);
78+
}
7279
}
7380
}
7481
return targetMembers;
@@ -85,7 +92,7 @@ Map<String, String> getDimensions() throws DimensionSetExceededException {
8592
return dimensions;
8693
}
8794

88-
Map<String, MetricDefinition> metrics() {
95+
Map<String, Metric> metrics() {
8996
return aws.getCloudWatchMetrics().get(0).getMetrics();
9097
}
9198

0 commit comments

Comments
 (0)