Skip to content

Commit 0a91baa

Browse files
Port CFEnv Removal
This change ports the CfEnv removal for the OTel Java Agent extension where it has been replaced by manual JSON parsing to keep the jar nice and tiny. It also ports the Spring Boot Sample application to use the SAP library to access VCAP_SERVICES. Signed-off-by: Karsten Schnitter <k.schnitter@sap.com>
1 parent e1027ab commit 0a91baa

30 files changed

+770
-348
lines changed

cf-java-logging-support-opentelemetry-agent-extension/pom.xml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,20 @@
5555
<artifactId>opentelemetry-exporter-otlp</artifactId>
5656
</dependency>
5757
<dependency>
58-
<groupId>io.pivotal.cfenv</groupId>
59-
<artifactId>java-cfenv</artifactId>
60-
<version>2.5.0</version>
58+
<groupId>io.opentelemetry.contrib</groupId>
59+
<artifactId>opentelemetry-cloudfoundry-resources</artifactId>
60+
<version>1.46.0-alpha</version>
61+
</dependency>
62+
<dependency>
63+
<groupId>com.fasterxml.jackson.core</groupId>
64+
<artifactId>jackson-core</artifactId>
65+
<version>${jackson-jr.version}</version>
66+
</dependency>
67+
<dependency>
68+
<groupId>uk.org.webcompere</groupId>
69+
<artifactId>system-stubs-jupiter</artifactId>
70+
<version>2.1.8</version>
71+
<scope>test</scope>
6172
</dependency>
6273
</dependencies>
6374

@@ -76,15 +87,18 @@
7687
<configuration>
7788
<filters>
7889
<filter>
79-
<artifact>io.pivotal.cfenv:java-cfenv</artifact>
90+
<artifact>io.opentelemetry.contrib:opentelemetry-cloudfoundry-resources</artifact>
8091
<includes>
81-
<include>io/pivotal/cfenv/**</include>
92+
<include>
93+
io/opentelemetry/contrib/cloudfoundry/resources/CloudFoundryResource.class
94+
</include>
8295
</includes>
8396
</filter>
8497
</filters>
8598
<artifactSet>
8699
<excludes>
87100
<exclude>io.opentelemetry</exclude>
101+
<exclude>io.opentelemetry.semconv</exclude>
88102
<exclude>com.fasterxml.jackson.core</exclude>
89103
<exclude>com.squareup.okhttp3</exclude>
90104
<exclude>com.squareup.okio</exclude>

cf-java-logging-support-opentelemetry-agent-extension/src/main/java/com/sap/hcf/cf/logging/opentelemetry/agent/ext/CloudFoundryResourceProvider.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,16 @@
22

33
import com.sap.hcf.cf.logging.opentelemetry.agent.ext.attributes.CloudFoundryResourceCustomizer;
44
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
5-
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
65
import io.opentelemetry.sdk.resources.Resource;
7-
import io.pivotal.cfenv.core.CfEnv;
86

9-
public class CloudFoundryResourceProvider implements ResourceProvider {
7+
public class CloudFoundryResourceProvider
8+
extends io.opentelemetry.contrib.cloudfoundry.resources.CloudFoundryResourceProvider {
109

11-
private final CloudFoundryResourceCustomizer customizer;
12-
13-
public CloudFoundryResourceProvider() {
14-
this(new CfEnv());
15-
}
16-
17-
public CloudFoundryResourceProvider(CfEnv cfEnv) {
18-
this.customizer = new CloudFoundryResourceCustomizer(cfEnv);
19-
}
10+
private final CloudFoundryResourceCustomizer customizer = new CloudFoundryResourceCustomizer();
2011

2112
@Override
2213
public Resource createResource(ConfigProperties configProperties) {
23-
return customizer.apply(null, configProperties);
14+
Resource original = super.createResource(configProperties);
15+
return customizer.apply(original, configProperties);
2416
}
2517
}

cf-java-logging-support-opentelemetry-agent-extension/src/main/java/com/sap/hcf/cf/logging/opentelemetry/agent/ext/CloudLoggingConfigurationCustomizerProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
import com.sap.hcf.cf.logging.opentelemetry.agent.ext.binding.CloudLoggingBindingPropertiesSupplier;
44
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
55
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
6-
import io.pivotal.cfenv.core.CfEnv;
76

87
import java.util.logging.Logger;
98

109
public class CloudLoggingConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider {
1110

1211
private static final Logger LOG = Logger.getLogger(CloudLoggingConfigurationCustomizerProvider.class.getName());
1312
private static final String VERSION = "4.0.0-RC1";
14-
private static final CfEnv cfEnv = new CfEnv();
1513

1614
@Override
1715
public void customize(AutoConfigurationCustomizer autoConfiguration) {
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
package com.sap.hcf.cf.logging.opentelemetry.agent.ext.attributes;
22

3+
import io.opentelemetry.api.common.AttributeKey;
34
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
45
import io.opentelemetry.sdk.resources.Resource;
56
import io.opentelemetry.sdk.resources.ResourceBuilder;
6-
import io.pivotal.cfenv.core.CfApplication;
7-
import io.pivotal.cfenv.core.CfEnv;
87

9-
import java.util.Optional;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.function.BiConsumer;
1011
import java.util.function.BiFunction;
1112
import java.util.logging.Logger;
1213

1314
public class CloudFoundryResourceCustomizer implements BiFunction<Resource, ConfigProperties, Resource> {
1415

1516
private static final String OTEL_JAVAAGENT_EXTENSION_SAP_CF_RESOURCE_ENABLED =
1617
"otel.javaagent.extension.sap.cf.resource.enabled";
18+
private static final String OTEL_JAVAAGENT_EXTENTION_CF_RESOURCE_FORMAT =
19+
"otel.javaagent.extension.sap.cf.resource.format";
1720
private static final Logger LOG = Logger.getLogger(CloudFoundryResourceCustomizer.class.getName());
18-
private final CfEnv cfEnv;
19-
20-
public CloudFoundryResourceCustomizer(CfEnv cfEnv) {
21-
this.cfEnv = cfEnv;
22-
}
21+
private static final Map<String, String> SAP_CF_RESOURCE_ATTRIBUTES = new HashMap<String, String>() {{
22+
put("cloudfoundry.app.id", "sap.cf.app_id");
23+
put("cloudfoundry.app.instance.id", "sap.cf.instance_id");
24+
put("cloudfoundry.app.name", "sap.cf.app_name");
25+
put("cloudfoundry.org.id", "sap.cf.org_id");
26+
put("cloudfoundry.org.name", "sap.cf.org_name");
27+
put("cloudfoundry.process.id", "sap.cf.process.id");
28+
put("cloudfoundry.process.type", "sap.cf.process.type");
29+
put("cloudfoundry.space.id", "sap.cf.space_id");
30+
put("cloudfoundry.space.name", "sap.cf.space_name");
31+
}};
2332

2433
@Override
2534
public Resource apply(Resource resource, ConfigProperties configProperties) {
@@ -28,28 +37,62 @@ public Resource apply(Resource resource, ConfigProperties configProperties) {
2837
LOG.config("CF resource attributes are disabled by configuration.");
2938
return Resource.empty();
3039
}
31-
if (!cfEnv.isInCf()) {
40+
41+
if (resource == null || resource.getAttributes().isEmpty()) {
3242
LOG.config("Not running in CF. Cannot obtain CF resource attributes.");
33-
return Resource.empty();
43+
return resource;
44+
}
45+
46+
String format = configProperties.getString(OTEL_JAVAAGENT_EXTENTION_CF_RESOURCE_FORMAT, "SAP");
47+
if (!format.equalsIgnoreCase("SAP")) {
48+
return resource;
49+
}
50+
51+
ResourceBuilder builder = Resource.builder();
52+
resource.getAttributes().asMap().forEach(addAttribute(builder));
53+
String appId = resource.getAttribute(AttributeKey.stringKey("cloudfoundry.app.id"));
54+
builder.put("sap.cf.source_id", appId);
55+
String appName = resource.getAttribute(AttributeKey.stringKey("cloudfoundry.app.name"));
56+
String serviceName = resource.getAttribute(AttributeKey.stringKey("service.name"));
57+
if (serviceName == null) {
58+
builder.put("service.name", appName);
3459
}
35-
CfApplication cfApp = cfEnv.getApp();
36-
ResourceBuilder rb = Resource.builder();
37-
rb.put("service.name", cfApp.getApplicationName());
38-
rb.put("sap.cf.source_id", cfApp.getApplicationId());
39-
rb.put("sap.cf.instance_id", cfApp.getInstanceIndex());
40-
rb.put("sap.cf.app_id", cfApp.getApplicationId());
41-
rb.put("sap.cf.app_name", cfApp.getApplicationName());
42-
rb.put("sap.cf.space_id", cfApp.getSpaceId());
43-
rb.put("sap.cf.space_name", cfApp.getSpaceName());
44-
rb.put("sap.cf.org_id", getString(cfApp, "organization_id"));
45-
rb.put("sap.cf.org_name", getString(cfApp, "organization_name"));
46-
rb.put("sap.cf.process.id", getString(cfApp, "process_id"));
47-
rb.put("sap.cf.process.type", getString(cfApp, "process_type"));
48-
return rb.build();
60+
return builder.build();
61+
}
62+
63+
private BiConsumer<AttributeKey<?>, Object> addAttribute(ResourceBuilder builder) {
64+
return (k, v) -> {
65+
switch (k.getType()) {
66+
case BOOLEAN:
67+
builder.put(rename(k), (boolean) v);
68+
break;
69+
case BOOLEAN_ARRAY:
70+
builder.put(rename(k), (boolean[]) v);
71+
break;
72+
case DOUBLE:
73+
builder.put(rename(k), (double) v);
74+
break;
75+
case DOUBLE_ARRAY:
76+
builder.put(rename(k), (double[]) v);
77+
break;
78+
case LONG:
79+
builder.put(rename(k), (long) v);
80+
break;
81+
case LONG_ARRAY:
82+
builder.put(rename(k), (long[]) v);
83+
break;
84+
case STRING:
85+
builder.put(rename(k), (String) v);
86+
break;
87+
case STRING_ARRAY:
88+
builder.put(rename(k), (String[]) v);
89+
break;
90+
}
91+
};
4992
}
5093

51-
private String getString(CfApplication cfApp, String key) {
52-
return Optional.ofNullable(cfApp).map(CfApplication::getMap).map(m -> m.get(key))
53-
.filter(String.class::isInstance).map(String.class::cast).orElse("");
94+
private String rename(AttributeKey<?> key) {
95+
String name = key.getKey();
96+
return SAP_CF_RESOURCE_ATTRIBUTES.getOrDefault(name, name);
5497
}
5598
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.sap.hcf.cf.logging.opentelemetry.agent.ext.binding;
2+
3+
import java.util.Map;
4+
import java.util.TreeMap;
5+
6+
public class CloudFoundryCredentials {
7+
8+
private final Map<String, String> properties;
9+
10+
private CloudFoundryCredentials(Builder builder) {
11+
this.properties = builder.properties;
12+
}
13+
14+
public String getString(String key) {
15+
return properties.get(key);
16+
}
17+
18+
public static Builder builder() {
19+
return new Builder();
20+
}
21+
22+
public static class Builder {
23+
24+
private final Map<String, String> properties = new TreeMap<>();
25+
26+
private Builder() {
27+
}
28+
29+
public CloudFoundryCredentials build() {
30+
return new CloudFoundryCredentials(this);
31+
}
32+
33+
public Builder add(String key, String value) {
34+
if (isNotBlank(key) && isNotBlank(value)) {
35+
properties.put(key, value);
36+
}
37+
return this;
38+
}
39+
40+
private boolean isNotBlank(String string) {
41+
return string != null && !string.trim().isEmpty();
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.sap.hcf.cf.logging.opentelemetry.agent.ext.binding;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class CloudFoundryServiceInstance {
7+
8+
private final String name;
9+
private final String label;
10+
private final List<String> tags;
11+
private final CloudFoundryCredentials credentials;
12+
13+
private CloudFoundryServiceInstance(String name, String label, CloudFoundryCredentials credentials,
14+
List<String> tags) {
15+
this.name = name;
16+
this.label = label;
17+
this.credentials = credentials;
18+
this.tags = tags;
19+
}
20+
21+
public String getName() {
22+
return name;
23+
}
24+
25+
public String getLabel() {
26+
return label;
27+
}
28+
29+
public CloudFoundryCredentials getCredentials() {
30+
return credentials;
31+
}
32+
33+
public List<String> getTags() {
34+
return tags;
35+
}
36+
37+
public static Builder builder() {
38+
return new Builder();
39+
}
40+
41+
public static class Builder {
42+
43+
private String name;
44+
private String label;
45+
private final List<String> tags = new ArrayList<>();
46+
private CloudFoundryCredentials credentials;
47+
48+
private Builder() {
49+
}
50+
51+
public Builder name(String name) {
52+
this.name = name;
53+
return this;
54+
}
55+
56+
public Builder label(String label) {
57+
this.label = label;
58+
return this;
59+
}
60+
61+
public Builder tag(String tag) {
62+
if (tag != null && !tag.trim().isEmpty()) {
63+
tags.add(tag);
64+
}
65+
return this;
66+
}
67+
68+
public Builder credentials(CloudFoundryCredentials credentials) {
69+
this.credentials = credentials;
70+
return this;
71+
}
72+
73+
public CloudFoundryServiceInstance build() {
74+
return new CloudFoundryServiceInstance(name, label, credentials, tags);
75+
}
76+
77+
}
78+
}

0 commit comments

Comments
 (0)