Skip to content

Commit 5460d5e

Browse files
committed
Add base entity class, merge logic and test
1 parent f056298 commit 5460d5e

13 files changed

Lines changed: 444 additions & 86 deletions

File tree

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
11
Comparing source compatibility of opentelemetry-sdk-common-1.52.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.51.0.jar
2-
No changes.
2+
***! MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.resources.Resource (not serializable)
3+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
4+
+++ NEW INTERFACE: io.opentelemetry.sdk.resources.internal.Resource
5+
---! REMOVED METHOD: PUBLIC(-) java.lang.Object getAttribute(io.opentelemetry.api.common.AttributeKey<T>)
6+
--- REMOVED ANNOTATION: javax.annotation.Nullable
7+
GENERIC TEMPLATES: --- T:java.lang.Object
8+
---! REMOVED METHOD: PUBLIC(-) io.opentelemetry.sdk.resources.Resource merge(io.opentelemetry.sdk.resources.Resource)
9+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource merge(io.opentelemetry.sdk.resources.internal.Resource)
10+
*** MODIFIED CLASS: PUBLIC io.opentelemetry.sdk.resources.ResourceBuilder (not serializable)
11+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
12+
+++ NEW INTERFACE: io.opentelemetry.sdk.resources.internal.ResourceBuilder

exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/EntityRefMarshaler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public static EntityRefMarshaler createForEntity(Entity e) {
4646
return new EntityRefMarshaler(
4747
schemaUrlUtf8,
4848
e.getType().getBytes(StandardCharsets.UTF_8),
49-
e.getIdentifyingAttributes().asMap().keySet().stream()
49+
e.getId().asMap().keySet().stream()
5050
.map(key -> key.getKey().getBytes(StandardCharsets.UTF_8))
5151
.toArray(byte[][]::new),
52-
e.getAttributes().asMap().keySet().stream()
52+
e.getDescription().asMap().keySet().stream()
5353
.map(key -> key.getKey().getBytes(StandardCharsets.UTF_8))
5454
.toArray(byte[][]::new));
5555
}

exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/EntityRefMarshalerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ void toEntityRefs() {
2525
Entity e =
2626
Entity.builder("test")
2727
.setSchemaUrl("test-url")
28-
.withDescriptive(attr -> attr.put("desc.key", "desc.value"))
29-
.withIdentifying(attr -> attr.put("id.key", "id.value"))
28+
.withDescription(attr -> attr.put("desc.key", "desc.value"))
29+
.withId(attr -> attr.put("id.key", "id.value"))
3030
.build();
3131
EntityRef proto = parse(EntityRef.getDefaultInstance(), EntityRefMarshaler.createForEntity(e));
3232
assertThat(proto.getType()).isEqualTo("test");

exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ MetricSnapshots convert(@Nullable Collection<MetricData> metricDataCollection) {
123123
if (resource == null) {
124124
resource = metricData.getResource();
125125
}
126-
if (otelScopeEnabled && !metricData.getInstrumentationScopeInfo().getAttributes().isEmpty()) {
126+
if (otelScopeEnabled
127+
&& !metricData.getInstrumentationScopeInfo().getDescription().isEmpty()) {
127128
scopes.add(metricData.getInstrumentationScopeInfo());
128129
}
129130
}
@@ -207,7 +208,7 @@ private GaugeSnapshot convertLongGauge(
207208
data.add(
208209
new GaugeDataPointSnapshot(
209210
(double) longData.getValue(),
210-
convertAttributes(resource, scope, longData.getAttributes()),
211+
convertAttributes(resource, scope, longData.getDescription()),
211212
convertLongExemplar(longData.getExemplars())));
212213
}
213214
return new GaugeSnapshot(metadata, data);
@@ -223,7 +224,7 @@ private CounterSnapshot convertLongCounter(
223224
data.add(
224225
new CounterDataPointSnapshot(
225226
(double) longData.getValue(),
226-
convertAttributes(resource, scope, longData.getAttributes()),
227+
convertAttributes(resource, scope, longData.getDescription()),
227228
convertLongExemplar(longData.getExemplars()),
228229
longData.getStartEpochNanos() / NANOS_PER_MILLISECOND));
229230
}
@@ -240,7 +241,7 @@ private GaugeSnapshot convertDoubleGauge(
240241
data.add(
241242
new GaugeDataPointSnapshot(
242243
doubleData.getValue(),
243-
convertAttributes(resource, scope, doubleData.getAttributes()),
244+
convertAttributes(resource, scope, doubleData.getDescription()),
244245
convertDoubleExemplar(doubleData.getExemplars())));
245246
}
246247
return new GaugeSnapshot(metadata, data);
@@ -256,7 +257,7 @@ private CounterSnapshot convertDoubleCounter(
256257
data.add(
257258
new CounterDataPointSnapshot(
258259
doubleData.getValue(),
259-
convertAttributes(resource, scope, doubleData.getAttributes()),
260+
convertAttributes(resource, scope, doubleData.getDescription()),
260261
convertDoubleExemplar(doubleData.getExemplars()),
261262
doubleData.getStartEpochNanos() / NANOS_PER_MILLISECOND));
262263
}
@@ -277,7 +278,7 @@ private HistogramSnapshot convertHistogram(
277278
new HistogramDataPointSnapshot(
278279
ClassicHistogramBuckets.of(boundaries, histogramData.getCounts()),
279280
histogramData.getSum(),
280-
convertAttributes(resource, scope, histogramData.getAttributes()),
281+
convertAttributes(resource, scope, histogramData.getDescription()),
281282
convertDoubleExemplars(histogramData.getExemplars()),
282283
histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND));
283284
}
@@ -299,7 +300,7 @@ private HistogramSnapshot convertExponentialHistogram(
299300
"Dropping histogram "
300301
+ metadata.getName()
301302
+ " with attributes "
302-
+ histogramData.getAttributes()
303+
+ histogramData.getDescription()
303304
+ " because it has scale < -4 which is unsupported in Prometheus");
304305
return null;
305306
}
@@ -313,7 +314,7 @@ private HistogramSnapshot convertExponentialHistogram(
313314
convertExponentialHistogramBuckets(histogramData.getPositiveBuckets(), scaleDown),
314315
convertExponentialHistogramBuckets(histogramData.getNegativeBuckets(), scaleDown),
315316
histogramData.getSum(),
316-
convertAttributes(resource, scope, histogramData.getAttributes()),
317+
convertAttributes(resource, scope, histogramData.getDescription()),
317318
convertDoubleExemplars(histogramData.getExemplars()),
318319
histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND));
319320
}
@@ -357,7 +358,7 @@ private SummarySnapshot convertSummary(
357358
summaryData.getCount(),
358359
summaryData.getSum(),
359360
convertQuantiles(summaryData.getValues()),
360-
convertAttributes(resource, scope, summaryData.getAttributes()),
361+
convertAttributes(resource, scope, summaryData.getDescription()),
361362
Exemplars.EMPTY, // Exemplars for Summaries not implemented yet.
362363
summaryData.getStartEpochNanos() / NANOS_PER_MILLISECOND));
363364
}
@@ -435,7 +436,7 @@ private InfoSnapshot makeTargetInfo(Resource resource) {
435436
convertAttributes(
436437
null, // resource attributes are only copied for point's attributes
437438
null, // scope attributes are only needed for point's attributes
438-
resource.getAttributes()))));
439+
resource.getDescription()))));
439440
}
440441

441442
private InfoSnapshot makeScopeInfo(Set<InstrumentationScopeInfo> scopes) {
@@ -446,7 +447,7 @@ private InfoSnapshot makeScopeInfo(Set<InstrumentationScopeInfo> scopes) {
446447
convertAttributes(
447448
null, // resource attributes are only copied for point's attributes
448449
scope,
449-
scope.getAttributes())));
450+
scope.getDescription())));
450451
}
451452
return new InfoSnapshot(new MetricMetadata("otel_scope"), prometheusScopeInfos);
452453
}
@@ -491,7 +492,7 @@ private Labels convertAttributes(
491492
}
492493

493494
if (resource != null) {
494-
Attributes resourceAttributes = resource.getAttributes();
495+
Attributes resourceAttributes = resource.getDescription();
495496
for (AttributeKey attributeKey : allowedAttributeKeys) {
496497
Object attributeValue = resourceAttributes.get(attributeKey);
497498
if (attributeValue != null) {
@@ -524,7 +525,7 @@ private List<AttributeKey<?>> filterAllowedResourceAttributeKeys(@Nullable Resou
524525

525526
List<AttributeKey<?>> allowedAttributeKeys =
526527
resourceAttributesToAllowedKeysCache.computeIfAbsent(
527-
resource.getAttributes(),
528+
resource.getDescription(),
528529
resourceAttributes ->
529530
resourceAttributes.asMap().keySet().stream()
530531
.filter(o -> allowedResourceAttributesFilter.test(o.getKey()))

exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,19 @@ void endToEnd() {
140140
// Resource attributes from the metric SDK resource translated to target_info
141141
stringKeyValue(
142142
"service_name",
143-
Objects.requireNonNull(resource.getAttributes().get(stringKey("service.name")))),
143+
Objects.requireNonNull(resource.getDescription().get(stringKey("service.name")))),
144144
stringKeyValue(
145145
"telemetry_sdk_name",
146146
Objects.requireNonNull(
147-
resource.getAttributes().get(stringKey("telemetry.sdk.name")))),
147+
resource.getDescription().get(stringKey("telemetry.sdk.name")))),
148148
stringKeyValue(
149149
"telemetry_sdk_language",
150150
Objects.requireNonNull(
151-
resource.getAttributes().get(stringKey("telemetry.sdk.language")))),
151+
resource.getDescription().get(stringKey("telemetry.sdk.language")))),
152152
stringKeyValue(
153153
"telemetry_sdk_version",
154154
Objects.requireNonNull(
155-
resource.getAttributes().get(stringKey("telemetry.sdk.version")))));
155+
resource.getDescription().get(stringKey("telemetry.sdk.version")))));
156156

157157
assertThat(resourceMetrics.getScopeMetricsCount()).isEqualTo(2);
158158
ScopeMetrics testScopeMetrics =

sdk/common/src/main/java/io/opentelemetry/sdk/resources/Resource.java

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
import io.opentelemetry.api.common.AttributeKey;
1010
import io.opentelemetry.api.common.Attributes;
1111
import io.opentelemetry.api.common.AttributesBuilder;
12-
import io.opentelemetry.api.internal.StringUtils;
13-
import io.opentelemetry.api.internal.Utils;
1412
import io.opentelemetry.sdk.common.internal.OtelVersion;
13+
import io.opentelemetry.sdk.resources.internal.AttributeCheckUtil;
1514
import java.util.Objects;
1615
import java.util.logging.Logger;
1716
import javax.annotation.Nullable;
@@ -34,13 +33,6 @@ public abstract class Resource {
3433
private static final AttributeKey<String> TELEMETRY_SDK_VERSION =
3534
AttributeKey.stringKey("telemetry.sdk.version");
3635

37-
private static final int MAX_LENGTH = 255;
38-
private static final String ERROR_MESSAGE_INVALID_CHARS =
39-
" should be a ASCII string with a length greater than 0 and not exceed "
40-
+ MAX_LENGTH
41-
+ " characters.";
42-
private static final String ERROR_MESSAGE_INVALID_VALUE =
43-
" should be a ASCII string with a length not exceed " + MAX_LENGTH + " characters.";
4436
private static final Resource EMPTY = create(Attributes.empty());
4537
private static final Resource TELEMETRY_SDK;
4638

@@ -91,7 +83,7 @@ public static Resource empty() {
9183
* @return a {@code Resource}.
9284
* @throws NullPointerException if {@code attributes} is null.
9385
* @throws IllegalArgumentException if attribute key or attribute value is not a valid printable
94-
* ASCII string or exceed {@link #MAX_LENGTH} characters.
86+
* ASCII string or exceed {@link AttributeCheckUtil#MAX_LENGTH} characters.
9587
*/
9688
public static Resource create(Attributes attributes) {
9789
return create(attributes, null);
@@ -105,10 +97,10 @@ public static Resource create(Attributes attributes) {
10597
* @return a {@code Resource}.
10698
* @throws NullPointerException if {@code attributes} is null.
10799
* @throws IllegalArgumentException if attribute key or attribute value is not a valid printable
108-
* ASCII string or exceed {@link #MAX_LENGTH} characters.
100+
* ASCII string or exceed {@link AttributeCheckUtil#MAX_LENGTH} characters.
109101
*/
110102
public static Resource create(Attributes attributes, @Nullable String schemaUrl) {
111-
checkAttributes(Objects.requireNonNull(attributes, "attributes"));
103+
AttributeCheckUtil.checkAttributes(Objects.requireNonNull(attributes, "attributes"));
112104
return new AutoValue_Resource(schemaUrl, attributes);
113105
}
114106

@@ -174,37 +166,6 @@ public Resource merge(@Nullable Resource other) {
174166
return create(attrBuilder.build(), getSchemaUrl());
175167
}
176168

177-
private static void checkAttributes(Attributes attributes) {
178-
attributes.forEach(
179-
(key, value) -> {
180-
Utils.checkArgument(
181-
isValidAndNotEmpty(key), "Attribute key" + ERROR_MESSAGE_INVALID_CHARS);
182-
Objects.requireNonNull(value, "Attribute value" + ERROR_MESSAGE_INVALID_VALUE);
183-
});
184-
}
185-
186-
/**
187-
* Determines whether the given {@code String} is a valid printable ASCII string with a length not
188-
* exceed {@link #MAX_LENGTH} characters.
189-
*
190-
* @param name the name to be validated.
191-
* @return whether the name is valid.
192-
*/
193-
private static boolean isValid(String name) {
194-
return name.length() <= MAX_LENGTH && StringUtils.isPrintableString(name);
195-
}
196-
197-
/**
198-
* Determines whether the given {@code String} is a valid printable ASCII string with a length
199-
* greater than 0 and not exceed {@link #MAX_LENGTH} characters.
200-
*
201-
* @param name the name to be validated.
202-
* @return whether the name is valid.
203-
*/
204-
private static boolean isValidAndNotEmpty(AttributeKey<?> name) {
205-
return !name.getKey().isEmpty() && isValid(name.getKey());
206-
}
207-
208169
/**
209170
* Returns a new {@link ResourceBuilder} instance for creating arbitrary {@link Resource}.
210171
*
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.resources.internal;
7+
8+
import io.opentelemetry.api.common.AttributeKey;
9+
import io.opentelemetry.api.common.Attributes;
10+
import io.opentelemetry.api.internal.StringUtils;
11+
import io.opentelemetry.api.internal.Utils;
12+
import java.util.Objects;
13+
14+
/**
15+
* Helpers to check resource attributes.
16+
*
17+
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
18+
* at any time.
19+
*/
20+
public final class AttributeCheckUtil {
21+
private AttributeCheckUtil() {}
22+
23+
// Note: Max length is actually configurable by specification.
24+
private static final int MAX_LENGTH = 255;
25+
private static final String ERROR_MESSAGE_INVALID_CHARS =
26+
" should be a ASCII string with a length greater than 0 and not exceed "
27+
+ MAX_LENGTH
28+
+ " characters.";
29+
private static final String ERROR_MESSAGE_INVALID_VALUE =
30+
" should be a ASCII string with a length not exceed " + MAX_LENGTH + " characters.";
31+
32+
/** Determine if the set of attributes if valid for Resource / Entity. */
33+
public static void checkAttributes(Attributes attributes) {
34+
attributes.forEach(
35+
(key, value) -> {
36+
Utils.checkArgument(
37+
isValidAndNotEmpty(key), "Attribute key" + ERROR_MESSAGE_INVALID_CHARS);
38+
Objects.requireNonNull(value, "Attribute value" + ERROR_MESSAGE_INVALID_VALUE);
39+
});
40+
}
41+
42+
/**
43+
* Determines whether the given {@code String} is a valid printable ASCII string with a length
44+
* greater than 0 and not exceed {@link #MAX_LENGTH} characters.
45+
*
46+
* @param name the name to be validated.
47+
* @return whether the name is valid.
48+
*/
49+
public static boolean isValidAndNotEmpty(AttributeKey<?> name) {
50+
return !name.getKey().isEmpty() && isValid(name.getKey());
51+
}
52+
53+
/**
54+
* Determines whether the given {@code String} is a valid printable ASCII string with a length not
55+
* exceed {@link #MAX_LENGTH} characters.
56+
*
57+
* @param name the name to be validated.
58+
* @return whether the name is valid.
59+
*/
60+
public static boolean isValid(String name) {
61+
return name.length() <= MAX_LENGTH && StringUtils.isPrintableString(name);
62+
}
63+
}

sdk/common/src/main/java/io/opentelemetry/sdk/resources/internal/Entity.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ public abstract class Entity {
4141
*
4242
* @return a map of attributes.
4343
*/
44-
public abstract Attributes getIdentifyingAttributes();
44+
public abstract Attributes getId();
4545

4646
/**
4747
* Returns a map of attributes that describe the entity.
4848
*
4949
* @return a map of attributes.
5050
*/
51-
public abstract Attributes getAttributes();
51+
public abstract Attributes getDescription();
5252

5353
/**
5454
* Returns the URL of the OpenTelemetry schema used by this resource. May be null if this entity
@@ -60,18 +60,37 @@ public abstract class Entity {
6060
@Nullable
6161
public abstract String getSchemaUrl();
6262

63+
/**
64+
* Returns a {@link Entity}.
65+
*
66+
* @param entityType the entity type string of this entity.
67+
* @param id a map of attributes that identify the entity.
68+
* @param description a map of attributes that describe the entity.
69+
* @return a {@code Entity}.
70+
* @throws NullPointerException if {@code id} or {@code description} is null.
71+
* @throws IllegalArgumentException if entityType string, attribute key or attribute value is not
72+
* a valid printable ASCII string or exceed {@link AttributeCheckUtil#MAX_LENGTH} characters.
73+
*/
6374
static final Entity create(
64-
String entityType,
65-
Attributes identifying,
66-
Attributes descriptive,
67-
@Nullable String schemaUrl) {
68-
return new AutoValue_Entity(entityType, identifying, descriptive, schemaUrl);
75+
String entityType, Attributes id, Attributes description, @Nullable String schemaUrl) {
76+
AttributeCheckUtil.isValid(entityType);
77+
AttributeCheckUtil.checkAttributes(id);
78+
AttributeCheckUtil.checkAttributes(description);
79+
return new AutoValue_Entity(entityType, id, description, schemaUrl);
6980
}
7081

82+
/**
83+
* Returns a new {@link EntityBuilder} instance populated with the data of this {@link Entity}.
84+
*/
7185
public final EntityBuilder toBuilder() {
7286
return new EntityBuilder(this);
7387
}
7488

89+
/**
90+
* Returns a new {@link EntityBuilder} instance for creating arbitrary {@link Entity}.
91+
*
92+
* @param entityType the entity type string of this entity.
93+
*/
7594
public static final EntityBuilder builder(String entityType) {
7695
return new EntityBuilder(entityType);
7796
}

0 commit comments

Comments
 (0)