Skip to content

Commit c7391e5

Browse files
authored
Remove AWS SDK v1 Dependency from X-Ray SDK Core (#428)
The X-Ray SDK Core previously relied on AWS SDK v1 solely to support AWS Remote Sampling. However, the SDK does not use the SDK’s client to call the sampling service directly. Instead, it composes REST requests manually and sends them through an AWS proxy. The only part of AWS SDK v1 being used was the data model types for serialization into JSON. This change removes the AWS SDK v1 dependency by reimplementing the necessary data types internally, eliminating the need to rely on the external SDK. Test Plan: Unit tests: Pass E2E tests with X-Ray Daemon: Pass E2E tests with CloudWatch Agent: Pass
1 parent 11bc8b8 commit c7391e5

File tree

21 files changed

+664
-330
lines changed

21 files changed

+664
-330
lines changed

aws-xray-recorder-sdk-aws-sdk/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies {
1818
testImplementation("com.amazonaws:aws-java-sdk-lambda:1.12.228")
1919
testImplementation("com.amazonaws:aws-java-sdk-s3:1.12.228")
2020
testImplementation("com.amazonaws:aws-java-sdk-sns:1.12.228")
21+
testImplementation("com.amazonaws:aws-java-sdk-xray:1.12.228")
2122
testImplementation("org.skyscreamer:jsonassert:1.3.0")
2223
testImplementation("org.powermock:powermock-module-junit4:2.0.7")
2324
testImplementation("org.powermock:powermock-api-mockito2:2.0.7")

aws-xray-recorder-sdk-core/build.gradle.kts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ plugins {
44
}
55

66
dependencies {
7-
api("com.amazonaws:aws-java-sdk-xray:1.12.767")
7+
api("commons-logging:commons-logging:1.3.5")
8+
9+
implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0")
10+
implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")
11+
implementation("com.google.auto.value:auto-value-annotations:1.10.4")
12+
implementation("com.google.auto.service:auto-service-annotations:1.1.1")
13+
implementation("org.apache.httpcomponents:httpclient:4.5.14")
14+
15+
annotationProcessor("com.google.auto.value:auto-value:1.10.4")
816

917
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
1018
compileOnly("javax.servlet:javax.servlet-api:3.1.0")

aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/internal/UnsignedXrayClient.java

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515

1616
package com.amazonaws.xray.internal;
1717

18-
import com.amazonaws.AmazonWebServiceRequest;
19-
import com.amazonaws.AmazonWebServiceResult;
20-
import com.amazonaws.SdkClientException;
21-
import com.amazonaws.services.xray.model.GetSamplingRulesRequest;
22-
import com.amazonaws.services.xray.model.GetSamplingRulesResult;
23-
import com.amazonaws.services.xray.model.GetSamplingTargetsRequest;
24-
import com.amazonaws.services.xray.model.GetSamplingTargetsResult;
2518
import com.amazonaws.xray.config.DaemonConfiguration;
19+
import com.amazonaws.xray.strategy.sampling.GetSamplingRulesRequest;
20+
import com.amazonaws.xray.strategy.sampling.GetSamplingRulesResponse;
21+
import com.amazonaws.xray.strategy.sampling.GetSamplingTargetsRequest;
22+
import com.amazonaws.xray.strategy.sampling.GetSamplingTargetsResponse;
2623
import com.fasterxml.jackson.annotation.JsonInclude.Include;
2724
import com.fasterxml.jackson.core.JsonParser;
2825
import com.fasterxml.jackson.databind.DeserializationContext;
@@ -32,7 +29,6 @@
3229
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
3330
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
3431
import com.fasterxml.jackson.databind.introspect.Annotated;
35-
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
3632
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
3733
import com.fasterxml.jackson.databind.module.SimpleModule;
3834
import java.io.ByteArrayOutputStream;
@@ -67,18 +63,6 @@ public class UnsignedXrayClient {
6763
.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE)
6864
.registerModule(new SimpleModule().addDeserializer(Date.class, new FloatDateDeserializer()))
6965
.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
70-
@Override
71-
public boolean hasIgnoreMarker(AnnotatedMember m) {
72-
// This is a somewhat hacky way of having ObjectMapper only serialize the fields in our
73-
// model classes instead of the base class that comes from the SDK. In the future, we will
74-
// remove the SDK dependency itself and the base classes and this hack will go away.
75-
if (m.getDeclaringClass() == AmazonWebServiceRequest.class ||
76-
m.getDeclaringClass() == AmazonWebServiceResult.class) {
77-
return true;
78-
}
79-
return super.hasIgnoreMarker(m);
80-
}
81-
8266
@Override
8367
public PropertyName findNameForDeserialization(Annotated a) {
8468
if (a.getName().equals("hTTPMethod")) {
@@ -109,12 +93,12 @@ public UnsignedXrayClient() {
10993
}
11094
}
11195

112-
public GetSamplingRulesResult getSamplingRules(GetSamplingRulesRequest request) {
113-
return sendRequest(getSamplingRulesEndpoint, request, GetSamplingRulesResult.class);
96+
public GetSamplingRulesResponse getSamplingRules(GetSamplingRulesRequest request) {
97+
return sendRequest(getSamplingRulesEndpoint, request, GetSamplingRulesResponse.class);
11498
}
11599

116-
public GetSamplingTargetsResult getSamplingTargets(GetSamplingTargetsRequest request) {
117-
return sendRequest(getSamplingTargetsEndpoint, request, GetSamplingTargetsResult.class);
100+
public GetSamplingTargetsResponse getSamplingTargets(GetSamplingTargetsRequest request) {
101+
return sendRequest(getSamplingTargetsEndpoint, request, GetSamplingTargetsResponse.class);
118102
}
119103

120104
private <T> T sendRequest(URL endpoint, Object request, Class<T> responseClass) {
@@ -216,7 +200,7 @@ private static Date parseServiceSpecificDate(String dateString) {
216200
BigDecimal dateValue = new BigDecimal(dateString);
217201
return new Date(dateValue.scaleByPowerOfTen(AWS_DATE_MILLI_SECOND_PRECISION).longValue());
218202
} catch (NumberFormatException nfe) {
219-
throw new SdkClientException("Unable to parse date : " + dateString, nfe);
203+
throw new IllegalArgumentException("Unable to parse date : " + dateString, nfe);
220204
}
221205
}
222206
}

aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/strategy/DefaultThrowableSerializationStrategy.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
package com.amazonaws.xray.strategy;
1717

18-
import com.amazonaws.AmazonServiceException;
1918
import com.amazonaws.xray.AWSXRay;
2019
import com.amazonaws.xray.entities.Entity;
2120
import com.amazonaws.xray.entities.Subsegment;
@@ -29,15 +28,16 @@
2928
import java.util.Set;
3029
import org.checkerframework.checker.nullness.qual.Nullable;
3130

31+
3232
/**
3333
* Default implementation of {@code ThrowableSerializationStrategy}.
34-
* This class auto-registers the {@code AmazonServiceException} class as a remote exception class if no set of remote exception
34+
* This class auto-registers the java.io.UncheckedIOException class as a remote exception class if no set of remote exception
3535
* classes is provided in the constructor.
3636
*/
3737
public class DefaultThrowableSerializationStrategy implements ThrowableSerializationStrategy {
3838
private static final int DEFAULT_MAX_STACK_TRACE_LENGTH = 50;
3939
private static final Set<Class<? extends Throwable>> DEFAULT_REMOTE_EXCEPTION_CLASSES =
40-
Collections.singleton(AmazonServiceException.class);
40+
Collections.singleton(java.io.UncheckedIOException.class);
4141

4242
private final int maxStackTraceLength;
4343
private final Set<Class<? extends Throwable>> remoteExceptionClasses;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazonaws.xray.strategy.sampling;
17+
18+
import com.fasterxml.jackson.annotation.JsonProperty;
19+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
20+
import com.google.auto.value.AutoValue;
21+
import javax.annotation.Nullable;
22+
23+
@AutoValue
24+
@JsonSerialize(as = GetSamplingRulesRequest.class)
25+
public abstract class GetSamplingRulesRequest {
26+
27+
public static GetSamplingRulesRequest create(@Nullable String nextToken) {
28+
return new AutoValue_GetSamplingRulesRequest(nextToken);
29+
}
30+
31+
@JsonProperty("NextToken")
32+
@Nullable
33+
abstract String getNextToken();
34+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazonaws.xray.strategy.sampling;
17+
18+
import com.fasterxml.jackson.annotation.JsonCreator;
19+
import com.fasterxml.jackson.annotation.JsonProperty;
20+
import com.google.auto.value.AutoValue;
21+
import java.util.List;
22+
import java.util.Map;
23+
import javax.annotation.Nullable;
24+
25+
@AutoValue
26+
public abstract class GetSamplingRulesResponse {
27+
28+
@JsonCreator
29+
static GetSamplingRulesResponse create(
30+
@JsonProperty("NextToken") String nextToken,
31+
@JsonProperty("SamplingRuleRecords") List<SamplingRuleRecord> samplingRuleRecords) {
32+
return new AutoValue_GetSamplingRulesResponse(nextToken, samplingRuleRecords);
33+
}
34+
35+
@Nullable
36+
abstract String getNextToken();
37+
38+
public abstract List<SamplingRuleRecord> getSamplingRuleRecords();
39+
40+
@AutoValue
41+
public abstract static class SamplingRuleRecord {
42+
43+
@JsonCreator
44+
static SamplingRuleRecord create(
45+
@JsonProperty("CreatedAt") String createdAt,
46+
@JsonProperty("ModifiedAt") String modifiedAt,
47+
@JsonProperty("SamplingRule") SamplingRule samplingRule) {
48+
return new AutoValue_GetSamplingRulesResponse_SamplingRuleRecord(createdAt, modifiedAt, samplingRule);
49+
}
50+
51+
public abstract String getCreatedAt();
52+
53+
public abstract String getModifiedAt();
54+
55+
public abstract SamplingRule getSamplingRule();
56+
}
57+
58+
@AutoValue
59+
public abstract static class SamplingRule {
60+
61+
@JsonCreator
62+
public static SamplingRule create(
63+
@JsonProperty("Attributes") Map<String, String> attributes,
64+
@JsonProperty("FixedRate") Double fixedRate,
65+
@JsonProperty("Host") String host,
66+
@JsonProperty("HTTPMethod") String httpMethod,
67+
@JsonProperty("Priority") Integer priority,
68+
@JsonProperty("ReservoirSize") Integer reservoirSize,
69+
@JsonProperty("ResourceARN") String resourceArn,
70+
@JsonProperty("RuleARN") @Nullable String ruleArn,
71+
@JsonProperty("RuleName") @Nullable String ruleName,
72+
@JsonProperty("ServiceName") String serviceName,
73+
@JsonProperty("ServiceType") String serviceType,
74+
@JsonProperty("URLPath") String urlPath,
75+
@JsonProperty("Version") Integer version) {
76+
return new AutoValue_GetSamplingRulesResponse_SamplingRule(
77+
attributes,
78+
fixedRate,
79+
host,
80+
httpMethod,
81+
priority,
82+
reservoirSize,
83+
resourceArn,
84+
ruleArn,
85+
ruleName,
86+
serviceName,
87+
serviceType,
88+
urlPath,
89+
version);
90+
}
91+
92+
@Nullable
93+
public abstract Map<String, String> getAttributes();
94+
95+
public abstract Double getFixedRate();
96+
97+
@Nullable
98+
public abstract String getHost();
99+
100+
@Nullable
101+
public abstract String getHttpMethod();
102+
103+
public abstract Integer getPriority();
104+
105+
public abstract Integer getReservoirSize();
106+
107+
@Nullable
108+
public abstract String getResourceArn();
109+
110+
@Nullable
111+
public abstract String getRuleArn();
112+
113+
@Nullable
114+
public abstract String getRuleName();
115+
116+
@Nullable
117+
public abstract String getServiceName();
118+
119+
@Nullable
120+
public abstract String getServiceType();
121+
122+
@Nullable
123+
public abstract String getUrlPath();
124+
125+
@Nullable
126+
public abstract Integer getVersion();
127+
}
128+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazonaws.xray.strategy.sampling;
17+
18+
import com.fasterxml.jackson.annotation.JsonProperty;
19+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
20+
import com.google.auto.value.AutoValue;
21+
import java.util.Date;
22+
import java.util.List;
23+
import javax.annotation.Nullable;
24+
25+
@AutoValue
26+
@JsonSerialize(as = GetSamplingTargetsRequest.class)
27+
public abstract class GetSamplingTargetsRequest {
28+
29+
public static GetSamplingTargetsRequest create(List<SamplingStatisticsDocument> documents) {
30+
return new AutoValue_GetSamplingTargetsRequest(documents);
31+
}
32+
33+
// Limit of 25 items
34+
@JsonProperty("SamplingStatisticsDocuments")
35+
abstract List<SamplingStatisticsDocument> getDocuments();
36+
37+
@AutoValue
38+
@JsonSerialize(as = SamplingStatisticsDocument.class)
39+
public abstract static class SamplingStatisticsDocument {
40+
41+
public static SamplingStatisticsDocument.Builder newBuilder() {
42+
return new AutoValue_GetSamplingTargetsRequest_SamplingStatisticsDocument.Builder();
43+
}
44+
45+
@JsonProperty("BorrowCount")
46+
public abstract long getBorrowCount();
47+
48+
@Nullable
49+
@JsonProperty("ClientID")
50+
public abstract String getClientId();
51+
52+
@JsonProperty("RequestCount")
53+
public abstract long getRequestCount();
54+
55+
@JsonProperty("RuleName")
56+
public abstract String getRuleName();
57+
58+
@JsonProperty("SampledCount")
59+
public abstract long getSampledCount();
60+
61+
@JsonProperty("Timestamp")
62+
public abstract Date getTimestamp();
63+
64+
@AutoValue.Builder
65+
public abstract static class Builder {
66+
public abstract Builder setBorrowCount(long borrowCount);
67+
68+
public abstract Builder setClientId(String clientId);
69+
70+
public abstract Builder setRequestCount(long requestCount);
71+
72+
public abstract Builder setRuleName(String ruleName);
73+
74+
public abstract Builder setSampledCount(long sampledCount);
75+
76+
public abstract Builder setTimestamp(Date timestamp);
77+
78+
public abstract SamplingStatisticsDocument build();
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)