Skip to content

Commit

Permalink
Resource.Builder for convenient work with Resource class (#3065)
Browse files Browse the repository at this point in the history
* Resource.Builder for convenient work with Resource class

* Remove unused import

* Adding javadoc comment

* Spotless fix

* Code review fixes

* Adding Javadoc

* Call Resource.create instead of AutoValue
  • Loading branch information
piotr-sumo authored Mar 31, 2021
1 parent 2f2af19 commit 1a9c909
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
Expand Down Expand Up @@ -67,10 +66,9 @@ private static OpenTelemetry initOpenTelemetry() {
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
.setResource(
Resource.getDefault()
.merge(
Resource.create(
Attributes.of(ResourceAttributes.SERVICE_NAME, SERVICE_NAME))))
Resource.getDefault().toBuilder()
.put(ResourceAttributes.SERVICE_NAME, SERVICE_NAME)
.build())
.build())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
Expand Down Expand Up @@ -71,10 +70,9 @@ private static OpenTelemetry initOpenTelemetry() {
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
.setResource(
Resource.getDefault()
.merge(
Resource.create(
Attributes.of(ResourceAttributes.SERVICE_NAME, SERVICE_NAME))))
Resource.getDefault().toBuilder()
.put(ResourceAttributes.SERVICE_NAME, SERVICE_NAME)
.build())
.build())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
Expand Down Expand Up @@ -105,11 +104,9 @@ private static OpenTelemetry initOpenTelemetry(String ip, int port) {
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
.setResource(
Resource.getDefault()
.merge(
Resource.create(
Attributes.of(
ResourceAttributes.SERVICE_NAME, "integration test"))))
Resource.getDefault().toBuilder()
.put(ResourceAttributes.SERVICE_NAME, "integration test")
.build())
.build())
.buildAndRegisterGlobal();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,17 @@ private static boolean isValid(String name) {
private static boolean isValidAndNotEmpty(AttributeKey<?> name) {
return !name.getKey().isEmpty() && isValid(name.getKey());
}

/** Returns a new {@link ResourceBuilder} instance for creating arbitrary {@link Resource}. */
public static ResourceBuilder builder() {
return new ResourceBuilder();
}

/**
* Returns a new {@link ResourceBuilder} instance populated with the data of this {@link
* Resource}.
*/
public ResourceBuilder toBuilder() {
return builder().putAll(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.resources;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;

/**
* A builder of {@link Resource} that allows to add key-value pairs and copy attributes from other
* {@link Attributes} or {@link Resource}.
*/
public class ResourceBuilder {

private final AttributesBuilder attributesBuilder = Attributes.builder();

/**
* Puts a String attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, String value) {
if (key != null && value != null) {
attributesBuilder.put(key, value);
}
return this;
}

/**
* Puts a long attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, long value) {
if (key != null) {
attributesBuilder.put(key, value);
}
return this;
}

/**
* Puts a double attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, double value) {
if (key != null) {
attributesBuilder.put(key, value);
}
return this;
}

/**
* Puts a boolean attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, boolean value) {
if (key != null) {
attributesBuilder.put(key, value);
}
return this;
}

/**
* Puts a String array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, String... values) {
if (key != null && values != null) {
attributesBuilder.put(key, values);
}
return this;
}

/**
* Puts a Long array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, long... values) {
if (key != null && values != null) {
attributesBuilder.put(key, values);
}
return this;
}

/**
* Puts a Double array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, double... values) {
if (key != null && values != null) {
attributesBuilder.put(key, values);
}
return this;
}

/**
* Puts a Boolean array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public ResourceBuilder put(String key, boolean... values) {
if (key != null && values != null) {
attributesBuilder.put(key, values);
}
return this;
}

/** Puts a {@link AttributeKey} with associated value into this. */
public <T> ResourceBuilder put(AttributeKey<T> key, T value) {
if (key != null && key.getKey() != null && key.getKey().length() > 0 && value != null) {
attributesBuilder.put(key, value);
}
return this;
}

/** Puts a {@link AttributeKey} with associated value into this. */
public ResourceBuilder put(AttributeKey<Long> key, int value) {
if (key != null && key.getKey() != null) {
attributesBuilder.put(key, value);
}
return this;
}

/** Puts all {@link Attributes} into this. */
public ResourceBuilder putAll(Attributes attributes) {
if (attributes != null) {
attributesBuilder.putAll(attributes);
}
return this;
}

/** Puts all attributes from {@link Resource} into this. */
public ResourceBuilder putAll(Resource resource) {
if (resource != null) {
attributesBuilder.putAll(resource.getAttributes());
}
return this;
}

/** Create the {@link Resource} from this. */
public Resource build() {
return Resource.create(attributesBuilder.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,76 @@ void testDefaultResources() {
assertThat(attributes.get(ResourceAttributes.TELEMETRY_SDK_LANGUAGE)).isEqualTo("java");
assertThat(attributes.get(ResourceAttributes.TELEMETRY_SDK_VERSION)).isNotNull();
}

@Test
void shouldBuilderNotFailWithNullResource() {
// given
ResourceBuilder builder = Resource.getDefault().toBuilder();

// when
builder.putAll((Resource) null);

// then no exception is thrown
// and
assertThat(builder.build().getAttributes().get(ResourceAttributes.SERVICE_NAME))
.isEqualTo("unknown_service:java");
}

@Test
void shouldBuilderCopyResource() {
// given
ResourceBuilder builder = Resource.getDefault().toBuilder();

// when
builder.put("dog says what?", "woof");

// then
Resource resource = builder.build();
assertThat(resource).isNotSameAs(Resource.getDefault());
assertThat(resource.getAttributes().get(stringKey("dog says what?"))).isEqualTo("woof");
}

@Test
void shouldBuilderHelperMethodsBuildResource() {
// given
ResourceBuilder builder = Resource.getDefault().toBuilder();
Attributes sourceAttributes = Attributes.of(stringKey("hello"), "world");
Resource source = Resource.create(sourceAttributes);
Attributes sourceAttributes2 = Attributes.of(stringKey("OpenTelemetry"), "Java");

// when
Resource resource =
builder
.put("long", 42L)
.put("double", Math.E)
.put("boolean", true)
.put("string", "abc")
.put("long array", 1L, 2L, 3L)
.put("double array", Math.E, Math.PI)
.put("boolean array", true, false)
.put("string array", "first", "second")
.put(longKey("long key"), 4242L)
.put(longKey("int in disguise"), 21)
.putAll(source)
.putAll(sourceAttributes2)
.build();

// then
Attributes attributes = resource.getAttributes();
assertThat(attributes.get(longKey("long"))).isEqualTo(42L);
assertThat(attributes.get(doubleKey("double"))).isEqualTo(Math.E);
assertThat(attributes.get(booleanKey("boolean"))).isEqualTo(true);
assertThat(attributes.get(stringKey("string"))).isEqualTo("abc");
assertThat(attributes.get(longArrayKey("long array"))).isEqualTo(Arrays.asList(1L, 2L, 3L));
assertThat(attributes.get(doubleArrayKey("double array")))
.isEqualTo(Arrays.asList(Math.E, Math.PI));
assertThat(attributes.get(booleanArrayKey("boolean array")))
.isEqualTo(Arrays.asList(true, false));
assertThat(attributes.get(stringArrayKey("string array")))
.isEqualTo(Arrays.asList("first", "second"));
assertThat(attributes.get(longKey("long key"))).isEqualTo(4242L);
assertThat(attributes.get(longKey("int in disguise"))).isEqualTo(21);
assertThat(attributes.get(stringKey("hello"))).isEqualTo("world");
assertThat(attributes.get(stringKey("OpenTelemetry"))).isEqualTo("Java");
}
}

0 comments on commit 1a9c909

Please sign in to comment.