diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java index 246951e104..99a1732834 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java @@ -37,7 +37,7 @@ public abstract class AwsSdkBaseTest extends ContractTestBase { private final LocalStackContainer localstack = - new LocalStackContainer(DockerImageName.parse("localstack/localstack:2.1.0")) + new LocalStackContainer(DockerImageName.parse("localstack/localstack:3.5.0")) .withServices( LocalStackContainer.Service.S3, LocalStackContainer.Service.DYNAMODB, @@ -45,6 +45,7 @@ public abstract class AwsSdkBaseTest extends ContractTestBase { LocalStackContainer.Service.KINESIS) .withEnv("DEFAULT_REGION", "us-west-2") .withNetwork(network) + .withEnv("LOCALSTACK_HOST", "127.0.0.1") .withNetworkAliases( "localstack", "s3.localstack", @@ -75,7 +76,8 @@ protected List getApplicationNetworkAliases() { // aliases used for the case there are errors or fault. In this case the target of the http // requests in the aws sdk is the instrumented service itself. We have to do this because // we cannot force localstack to return specific error codes. - return List.of("error-bucket.s3.test", "fault-bucket.s3.test", "error.test", "fault.test"); + return List.of( + "error-bucket.s3.test", "fault-bucket.s3.test", "error.test", "fault.test", "bedrock.test"); } @Override @@ -92,6 +94,14 @@ protected String getApplicationWaitPattern() { protected abstract String getKinesisSpanNamePrefix(); + protected abstract String getBedrockSpanNamePrefix(); + + protected abstract String getBedrockAgentSpanNamePrefix(); + + protected abstract String getBedrockRuntimeSpanNamePrefix(); + + protected abstract String getBedrockAgentRuntimeSpanNamePrefix(); + protected abstract String getS3RpcServiceName(); protected abstract String getDynamoDbRpcServiceName(); @@ -100,6 +110,14 @@ protected String getApplicationWaitPattern() { protected abstract String getKinesisRpcServiceName(); + protected abstract String getBedrockRpcServiceName(); + + protected abstract String getBedrockAgentRpcServiceName(); + + protected abstract String getBedrockRuntimeRpcServiceName(); + + protected abstract String getBedrockAgentRuntimeRpcServiceName(); + private String getS3ServiceName() { return "AWS::S3"; } @@ -116,6 +134,22 @@ private String getKinesisServiceName() { return "AWS::Kinesis"; } + private String getBedrockServiceName() { + return "AWS::Bedrock"; + } + + private String getBedrockAgentServiceName() { + return "AWS::Bedrock"; + } + + private String getBedrockAgentRuntimeServiceName() { + return "AWS::Bedrock"; + } + + private String getBedrockRuntimeServiceName() { + return "AWS::BedrockRuntime"; + } + private String s3SpanName(String operation) { return String.format("%s.%s", getS3SpanNamePrefix(), operation); } @@ -132,6 +166,22 @@ private String kinesisSpanName(String operation) { return String.format("%s.%s", getKinesisSpanNamePrefix(), operation); } + private String bedrockSpanName(String operation) { + return String.format("%s.%s", getBedrockSpanNamePrefix(), operation); + } + + private String bedrockAgentSpanName(String operation) { + return String.format("%s.%s", getBedrockAgentSpanNamePrefix(), operation); + } + + private String bedrockRuntimeSpanName(String operation) { + return String.format("%s.%s", getBedrockRuntimeSpanNamePrefix(), operation); + } + + private String bedrockAgentRuntimeSpanName(String operation) { + return String.format("%s.%s", getBedrockAgentRuntimeSpanNamePrefix(), operation); + } + protected ThrowingConsumer assertAttribute(String key, String value) { return (attribute) -> { assertThat(attribute.getKey()).isEqualTo(key); @@ -1559,4 +1609,443 @@ protected void doTestKinesisFault() throws Exception { identifier, 0.0); } + + protected void doTestBedrockAgentKnowledgeBaseId() { + var response = + appClient.get("/bedrockagent/getknowledgeBase/knowledge-base-id").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockagent/getknowledgeBase/:knowledgeBaseId"; + String type = "AWS::Bedrock::KnowledgeBase"; + String identifier = "knowledge-base-id"; + assertSpanClientAttributes( + traces, + bedrockAgentSpanName("GetKnowledgeBase"), + getBedrockAgentRpcServiceName(), + localService, + localOperation, + getBedrockAgentServiceName(), + "GetKnowledgeBase", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of( + assertAttribute( + SemanticConventionsConstants.AWS_KNOWLEDGE_BASE_ID, "knowledge-base-id"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetKnowledgeBase", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetKnowledgeBase", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetKnowledgeBase", + type, + identifier, + 0.0); + } + + protected void doTestBedrockAgentAgentId() { + var response = appClient.get("/bedrockagent/getagent/test-agent-id").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockagent/getagent/:agentId"; + String type = "AWS::Bedrock::Agent"; + String identifier = "test-agent-id"; + assertSpanClientAttributes( + traces, + bedrockAgentSpanName("GetAgent"), + getBedrockAgentRpcServiceName(), + localService, + localOperation, + getBedrockAgentServiceName(), + "GetAgent", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of(assertAttribute(SemanticConventionsConstants.AWS_AGENT_ID, "test-agent-id"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetAgent", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetAgent", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetAgent", + type, + identifier, + 0.0); + } + + protected void doTestBedrockAgentDataSourceId() { + var response = appClient.get("/bedrockagent/get-data-source").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockagent/get-data-source"; + String type = "AWS::Bedrock::DataSource"; + String identifier = "nonExistDatasourceId"; + assertSpanClientAttributes( + traces, + bedrockAgentSpanName("GetDataSource"), + getBedrockAgentRpcServiceName(), + localService, + localOperation, + getBedrockAgentServiceName(), + "GetDataSource", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of( + assertAttribute( + SemanticConventionsConstants.AWS_DATA_SOURCE_ID, "nonExistDatasourceId"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetDataSource", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetDataSource", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockAgentServiceName(), + "GetDataSource", + type, + identifier, + 0.0); + } + + protected void doTestBedrockRuntimeModelId() { + var response = appClient.get("/bedrockruntime/invokeModel").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockruntime/invokeModel"; + String type = "AWS::Bedrock::Model"; + String identifier = "anthropic.claude-v2"; + assertSpanClientAttributes( + traces, + bedrockRuntimeSpanName("InvokeModel"), + getBedrockRuntimeRpcServiceName(), + localService, + localOperation, + getBedrockRuntimeServiceName(), + "InvokeModel", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of( + assertAttribute( + SemanticConventionsConstants.GEN_AI_REQUEST_MODEL, "anthropic.claude-v2"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockRuntimeServiceName(), + "InvokeModel", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockRuntimeServiceName(), + "InvokeModel", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockRuntimeServiceName(), + "InvokeModel", + type, + identifier, + 0.0); + } + + protected void doTestBedrockGuardrailId() { + var response = appClient.get("/bedrock/getguardrail").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrock/getguardrail"; + String type = "AWS::Bedrock::Guardrail"; + String identifier = "test-bedrock-guardrail"; + assertSpanClientAttributes( + traces, + bedrockSpanName("GetGuardrail"), + getBedrockRpcServiceName(), + localService, + localOperation, + getBedrockServiceName(), + "GetGuardrail", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of( + assertAttribute( + SemanticConventionsConstants.AWS_GUARDRAIL_ID, "test-bedrock-guardrail"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockServiceName(), + "GetGuardrail", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockServiceName(), + "GetGuardrail", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockServiceName(), + "GetGuardrail", + type, + identifier, + 0.0); + } + + protected void doTestBedrockAgentRuntimeAgentId() { + var response = appClient.get("/bedrockagentruntime/getmemory/test-agent-id").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockagentruntime/getmemory/:agentId"; + String type = "AWS::Bedrock::Agent"; + String identifier = "test-agent-id"; + assertSpanClientAttributes( + traces, + bedrockAgentRuntimeSpanName("GetAgentMemory"), + getBedrockAgentRuntimeRpcServiceName(), + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "GetAgentMemory", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of(assertAttribute(SemanticConventionsConstants.AWS_AGENT_ID, "test-agent-id"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "GetAgentMemory", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "GetAgentMemory", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "GetAgentMemory", + type, + identifier, + 0.0); + } + + protected void doTestBedrockAgentRuntimeKnowledgeBaseId() { + var response = + appClient.get("/bedrockagentruntime/retrieve/test-knowledge-base-id").aggregate().join(); + var traces = mockCollectorClient.getTraces(); + var metrics = + mockCollectorClient.getMetrics( + Set.of( + AppSignalsConstants.ERROR_METRIC, + AppSignalsConstants.FAULT_METRIC, + AppSignalsConstants.LATENCY_METRIC)); + + var localService = getApplicationOtelServiceName(); + var localOperation = "GET /bedrockagentruntime/retrieve/:knowledgeBaseId"; + String type = "AWS::Bedrock::KnowledgeBase"; + String identifier = "test-knowledge-base-id"; + assertSpanClientAttributes( + traces, + bedrockAgentRuntimeSpanName("Retrieve"), + getBedrockAgentRuntimeRpcServiceName(), + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "Retrieve", + type, + identifier, + "bedrock.test", + 8080, + "http://bedrock.test:8080", + 200, + List.of( + assertAttribute( + SemanticConventionsConstants.AWS_KNOWLEDGE_BASE_ID, "test-knowledge-base-id"))); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.LATENCY_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "Retrieve", + type, + identifier, + 5000.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.FAULT_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "Retrieve", + type, + identifier, + 0.0); + assertMetricClientAttributes( + metrics, + AppSignalsConstants.ERROR_METRIC, + localService, + localOperation, + getBedrockAgentRuntimeServiceName(), + "Retrieve", + type, + identifier, + 0.0); + } } diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java index b2be003658..3cf5a8982e 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java @@ -57,6 +57,25 @@ protected String getKinesisSpanNamePrefix() { return "Kinesis"; } + protected String getBedrockSpanNamePrefix() { + return "Bedrock"; + } + + @Override + protected String getBedrockAgentSpanNamePrefix() { + return "AWSBedrockAgent"; + } + + @Override + protected String getBedrockRuntimeSpanNamePrefix() { + return "BedrockRuntime"; + } + + @Override + protected String getBedrockAgentRuntimeSpanNamePrefix() { + return "AWSBedrockAgentRuntime"; + } + protected String getS3RpcServiceName() { return "Amazon S3"; } @@ -75,6 +94,22 @@ protected String getKinesisRpcServiceName() { return "AmazonKinesis"; } + protected String getBedrockRpcServiceName() { + return "AmazonBedrock"; + } + + protected String getBedrockAgentRpcServiceName() { + return "AWSBedrockAgent"; + } + + protected String getBedrockRuntimeRpcServiceName() { + return "AmazonBedrockRuntime"; + } + + protected String getBedrockAgentRuntimeRpcServiceName() { + return "AWSBedrockAgentRuntime"; + } + @Test void testS3CreateBucket() throws Exception { doTestS3CreateBucket(); @@ -165,4 +200,39 @@ void testKinsesisError() throws Exception { void testKinesisFault() throws Exception { doTestKinesisFault(); } + + @Test + void testBedrockAgentGetKnowledgeBaseId() { + doTestBedrockAgentKnowledgeBaseId(); + } + + @Test + void testBedrockAgentAgentId() { + doTestBedrockAgentAgentId(); + } + + @Test + void testBedrockAgentDataSourceId() { + doTestBedrockAgentDataSourceId(); + } + + @Test + void testBedrockRuntimeModelId() { + doTestBedrockRuntimeModelId(); + } + + @Test + void testBedrockGuardrailId() { + doTestBedrockGuardrailId(); + } + + @Test + void testBedrockAgentRuntimeAgentId() { + doTestBedrockAgentRuntimeAgentId(); + } + + @Test + void testBedrockAgentRuntimeKnowledgeBaseId() { + doTestBedrockAgentRuntimeKnowledgeBaseId(); + } } diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java index 1e99836d6b..a76736daf3 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java @@ -56,6 +56,25 @@ protected String getKinesisSpanNamePrefix() { return "Kinesis"; } + protected String getBedrockSpanNamePrefix() { + return "Bedrock"; + } + + @Override + protected String getBedrockAgentSpanNamePrefix() { + return "BedrockAgent"; + } + + @Override + protected String getBedrockRuntimeSpanNamePrefix() { + return "BedrockRuntime"; + } + + @Override + protected String getBedrockAgentRuntimeSpanNamePrefix() { + return "BedrockAgentRuntime"; + } + @Override protected String getS3RpcServiceName() { return "S3"; @@ -75,6 +94,26 @@ protected String getKinesisRpcServiceName() { return "Kinesis"; } + @Override + protected String getBedrockRpcServiceName() { + return "Bedrock"; + } + + @Override + protected String getBedrockAgentRpcServiceName() { + return "BedrockAgent"; + } + + @Override + protected String getBedrockRuntimeRpcServiceName() { + return "BedrockRuntime"; + } + + @Override + protected String getBedrockAgentRuntimeRpcServiceName() { + return "BedrockAgentRuntime"; + } + @Test void testS3CreateBucket() throws Exception { doTestS3CreateBucket(); @@ -164,4 +203,41 @@ void testKinesisError() throws Exception { void testKinesisFault() throws Exception { doTestKinesisFault(); } + + @Test + void testBedrockAgentGetKnowlesgeBaseId() { + doTestBedrockAgentKnowledgeBaseId(); + } + + @Test + void testBedrockAgentAgentId() { + doTestBedrockAgentAgentId(); + } + + @Test + void testBedrockAgentDataSourceId() { + doTestBedrockAgentDataSourceId(); + } + + @Test + void testBedrockRuntimeModelId() { + doTestBedrockRuntimeModelId(); + } + + @Test + void testBedrockGuardrailId() { + doTestBedrockGuardrailId(); + } + + @Test + void testBedrockAgentRuntimeAgentId() { + doTestBedrockAgentRuntimeAgentId(); + } + + // TODO: Enable testBedrockAgentRuntimeKnowledgeBaseId test after KnowledgeBaseId is supported in + // OTEL BedrockAgentRuntime instrumentation + // @Test + // void testBedrockAgentRuntimeKnowledgeBaseId() { + // doTestBedrockAgentRuntimeKnowledgeBaseId(); + // } } diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/SemanticConventionsConstants.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/SemanticConventionsConstants.java index 17c801dcbd..3fe1644dd5 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/SemanticConventionsConstants.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/SemanticConventionsConstants.java @@ -58,6 +58,11 @@ public class SemanticConventionsConstants { public static final String AWS_QUEUE_URL = "aws.queue.url"; public static final String AWS_QUEUE_NAME = "aws.queue.name"; public static final String AWS_STREAM_NAME = "aws.stream.name"; + public static final String AWS_KNOWLEDGE_BASE_ID = "aws.bedrock.knowledge_base.id"; + public static final String AWS_DATA_SOURCE_ID = "aws.bedrock.data_source.id"; + public static final String AWS_AGENT_ID = "aws.bedrock.agent.id"; + public static final String AWS_GUARDRAIL_ID = "aws.bedrock.guardrail.id"; + public static final String GEN_AI_REQUEST_MODEL = "gen_ai.request.model"; // kafka public static final String MESSAGING_CLIENT_ID = "messaging.client_id"; diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-base/build.gradle.kts b/appsignals-tests/images/aws-sdk/aws-sdk-base/build.gradle.kts new file mode 100644 index 0000000000..0912622bc3 --- /dev/null +++ b/appsignals-tests/images/aws-sdk/aws-sdk-base/build.gradle.kts @@ -0,0 +1,29 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +plugins { + `java-library` +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + implementation("com.google.code.gson:gson:2.10.1") + implementation("com.sparkjava:spark-core") + implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") +} diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-base/src/main/java/com/amazon/sampleapp/Utils.java b/appsignals-tests/images/aws-sdk/aws-sdk-base/src/main/java/com/amazon/sampleapp/Utils.java new file mode 100644 index 0000000000..f8f5313b26 --- /dev/null +++ b/appsignals-tests/images/aws-sdk/aws-sdk-base/src/main/java/com/amazon/sampleapp/Utils.java @@ -0,0 +1,201 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.amazon.sampleapp; + +import static spark.Spark.get; +import static spark.Spark.post; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +public class Utils { + private static ObjectMapper objectMapper = new ObjectMapper(); + + // Response with BedrockAgent GetKnowledgeBaseRequest. + public static void setupGetKnowledgeBaseRoute(int status) { + get( + "/knowledgebases/:knowledgeBaseId", + (req, res) -> { + String knowledgeBaseId = req.params(":knowledgeBaseId"); + String createdAt = + Instant.ofEpochSecond(1720600797L) + .atOffset(ZoneOffset.UTC) + .format(DateTimeFormatter.ISO_INSTANT); + String updatedAt = + Instant.ofEpochSecond(1720773597L) + .atOffset(ZoneOffset.UTC) + .format(DateTimeFormatter.ISO_INSTANT); + ObjectNode knowledgeBase = objectMapper.createObjectNode(); + knowledgeBase.put("createdAt", createdAt); + knowledgeBase.put( + "knowledgeBaseArn", + "arn:aws:bedrock:us-west-2:000000000000:knowledge-base/" + knowledgeBaseId); + ObjectNode knowledgeBaseConfiguration = objectMapper.createObjectNode(); + knowledgeBaseConfiguration.put("type", "VECTOR"); + knowledgeBase.set("knowledgeBaseConfiguration", knowledgeBaseConfiguration); + knowledgeBase.put("knowledgeBaseId", knowledgeBaseId); + knowledgeBase.put("name", "test-knowledge-base"); + knowledgeBase.put("roleArn", "arn:aws:iam::000000000000:role/TestKnowledgeBase"); + knowledgeBase.put("status", "ACTIVE"); + ObjectNode storageConfiguration = objectMapper.createObjectNode(); + storageConfiguration.put("type", "OPENSEARCH_SERVERLESS"); + knowledgeBase.set("storageConfiguration", storageConfiguration); + knowledgeBase.put("updatedAt", updatedAt); + ObjectNode responseBody = objectMapper.createObjectNode(); + responseBody.set("knowledgeBase", knowledgeBase); + String jsonResponse = objectMapper.writeValueAsString(responseBody); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with BedrockAgent GetAgentRequest. + public static void setupGetAgentRoute(int status) { + get( + "/agents/:agentId/", + (req, res) -> { + String agentId = req.params(":agentId"); + ObjectNode agentNode = objectMapper.createObjectNode(); + agentNode.put("agentArn", "arn:aws:bedrock:us-east-1:000000000000:agent/" + agentId); + agentNode.put("agentId", agentId); + agentNode.put("agentName", "test-bedrock-agent"); + agentNode.put("agentResourceRoleArn", "arn:aws:iam::000000000000:role/TestAgent"); + agentNode.put("agentStatus", "PREPARED"); + agentNode.put("agentVersion", "DRAFT"); + agentNode.put("createdAt", "2024-07-17T12:00:00Z"); + agentNode.put("idleSessionTTLInSeconds", 60); + agentNode.put("updatedAt", "2024-07-17T12:30:00Z"); + ObjectNode responseBody = objectMapper.createObjectNode(); + responseBody.set("agent", agentNode); + String jsonResponse = responseBody.toString(); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with BedrockAgent GetDataSourceRequest. + public static void setupGetDataSourceRoute(int status) { + get( + "/knowledgebases/:knowledgeBaseId/datasources/:dataSourceId", + (req, res) -> { + String dataSourceId = req.params(":dataSourceId"); + String knowledgeBaseId = req.params(":knowledgeBaseId"); + ObjectNode dataSourceNode = objectMapper.createObjectNode(); + dataSourceNode.put("createdAt", "2024-07-17T12:00:00Z"); // Example value + dataSourceNode.put("dataSourceId", dataSourceId); + dataSourceNode.put("knowledgeBaseId", knowledgeBaseId); + dataSourceNode.put("name", "example-data-source-name"); + dataSourceNode.put("status", "ACTIVE"); + dataSourceNode.put("updatedAt", "2024-07-17T12:30:00Z"); // Example value + ObjectNode dataSourceConfigurationNode = objectMapper.createObjectNode(); + dataSourceConfigurationNode.put("type", "EXAMPLE_TYPE"); + dataSourceNode.set("dataSourceConfiguration", dataSourceConfigurationNode); + ObjectNode responseBody = objectMapper.createObjectNode(); + responseBody.set("dataSource", dataSourceNode); + String jsonResponse = responseBody.toString(); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with Bedrock GetGuardrailRequest. + public static void setupGetGuardrailRoute(int status) { + get( + "/guardrails/:guardrailIdentifier", + (req, res) -> { + String guardrailId = "test-bedrock-guardrail"; + ObjectNode jsonResponse = objectMapper.createObjectNode(); + jsonResponse.put( + "guardrailArn", "arn:aws:bedrock:us-east-1:000000000000:guardrail/" + guardrailId); + jsonResponse.put("guardrailId", guardrailId); + jsonResponse.put("version", "DRAFT"); + jsonResponse.put("createdAt", "2024-07-17T12:00:00Z"); + jsonResponse.put("updatedAt", "2024-07-17T12:30:00Z"); + jsonResponse.put("blockedInputMessaging", "InputBlocked"); + jsonResponse.put("blockedOutputsMessaging", "OutputBlocked"); + jsonResponse.put("name", "test-guardrail"); + jsonResponse.put("status", "READY"); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with bedrockAgentRuntime GetAgentMemoryRequest. + public static void setupGetAgentMemoryRoute(int status) { + get( + "/agents/:agentId/agentAliases/:agentAliasId/memories", + (req, res) -> { + ObjectNode jsonResponse = objectMapper.createObjectNode(); + jsonResponse.put("nextToken", "testToken"); + + ArrayNode memoryContents = objectMapper.createArrayNode(); + jsonResponse.set("memoryContents", memoryContents); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with bedrockAgentRuntime RetrieveRequest. + public static void setupRetrieveRoute(int status) { + post( + "/knowledgebases/:knowledgeBaseId/retrieve", + (req, res) -> { + ObjectNode jsonResponse = objectMapper.createObjectNode(); + jsonResponse.put("nextToken", "TestNextToken"); + ArrayNode retrievalResults = objectMapper.createArrayNode(); + ObjectNode content = objectMapper.createObjectNode(); + content.put("text", "An example of text content."); + ObjectNode contentWrapper = objectMapper.createObjectNode(); + contentWrapper.set("content", content); + retrievalResults.add(contentWrapper); + jsonResponse.set("retrievalResults", retrievalResults); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } + + // Response with bedrockRuntime InvokeModelRequest. + public static void setupInvokeModelRoute(int status) { + post( + "/model/:modelId/invoke", + (req, res) -> { + ObjectNode jsonResponse = objectMapper.createObjectNode(); + jsonResponse.put("completion", "A simple completion token."); + jsonResponse.put("stop_reason", "stop_sequence"); + jsonResponse.put("stop", "stop_token"); + + res.status(status); + res.type("application/json"); + return jsonResponse; + }); + } +} diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-v1/build.gradle.kts b/appsignals-tests/images/aws-sdk/aws-sdk-v1/build.gradle.kts index 6d0ef5608a..6ee3f0cae1 100644 --- a/appsignals-tests/images/aws-sdk/aws-sdk-v1/build.gradle.kts +++ b/appsignals-tests/images/aws-sdk/aws-sdk-v1/build.gradle.kts @@ -27,13 +27,19 @@ dependencies { implementation("com.sparkjava:spark-core") implementation("com.google.code.gson:gson:2.10.1") implementation("org.slf4j:slf4j-simple") - implementation(enforcedPlatform("com.amazonaws:aws-java-sdk-bom:1.12.514")) + implementation(project(":appsignals-tests:images:aws-sdk:aws-sdk-base")) + implementation(enforcedPlatform("com.amazonaws:aws-java-sdk-bom:1.12.761")) implementation("com.amazonaws:aws-java-sdk-s3") implementation("com.amazonaws:aws-java-sdk-dynamodb") implementation("com.amazonaws:aws-java-sdk-sqs") implementation("com.amazonaws:aws-java-sdk-kinesis") + implementation("com.amazonaws:aws-java-sdk-bedrock") + implementation("com.amazonaws:aws-java-sdk-bedrockagent") + implementation("com.amazonaws:aws-java-sdk-bedrockruntime") + implementation("com.amazonaws:aws-java-sdk-bedrockagentruntime") implementation("commons-logging:commons-logging") implementation("com.linecorp.armeria:armeria") + implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") } java { diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-v1/src/main/java/com/amazon/sampleapp/App.java b/appsignals-tests/images/aws-sdk/aws-sdk-v1/src/main/java/com/amazon/sampleapp/App.java index ad5249b510..0a7498bf2a 100644 --- a/appsignals-tests/images/aws-sdk/aws-sdk-v1/src/main/java/com/amazon/sampleapp/App.java +++ b/appsignals-tests/images/aws-sdk/aws-sdk-v1/src/main/java/com/amazon/sampleapp/App.java @@ -25,6 +25,17 @@ import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; import com.amazonaws.regions.Regions; +import com.amazonaws.services.bedrock.AmazonBedrockClient; +import com.amazonaws.services.bedrock.model.GetGuardrailRequest; +import com.amazonaws.services.bedrockagent.AWSBedrockAgentClient; +import com.amazonaws.services.bedrockagent.model.GetAgentRequest; +import com.amazonaws.services.bedrockagent.model.GetDataSourceRequest; +import com.amazonaws.services.bedrockagent.model.GetKnowledgeBaseRequest; +import com.amazonaws.services.bedrockagentruntime.AWSBedrockAgentRuntimeClient; +import com.amazonaws.services.bedrockagentruntime.model.GetAgentMemoryRequest; +import com.amazonaws.services.bedrockagentruntime.model.RetrieveRequest; +import com.amazonaws.services.bedrockruntime.AmazonBedrockRuntimeClient; +import com.amazonaws.services.bedrockruntime.model.InvokeModelRequest; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; import com.amazonaws.services.dynamodbv2.model.AttributeValue; @@ -49,6 +60,7 @@ import java.io.IOException; import java.net.http.HttpClient; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Map; import org.slf4j.Logger; @@ -109,6 +121,7 @@ public static void main(String[] args) throws IOException, InterruptedException setupS3(); setupSqs(); setupKinesis(); + setupBedrock(); // Add this log line so that we only start testing after all routes are configured. awaitInitialization(); @@ -206,7 +219,6 @@ private static void setupSqs() { try { errorClient.sendMessage(sendMessageRequest); } catch (Exception ex) { - } return ""; }); @@ -501,4 +513,122 @@ private static void setupS3() { return ""; }); } + + private static void setupBedrock() { + // Localstack does not support Bedrock related services. + // We point all Bedrock related request endpoints to the local app, + // and then specifically handle each request to return the expected response. + // For the full list of services supported by Localstack, see: + // https://github.com/testcontainers/testcontainers-java/blob/1f38f0d9604edb9e89fd3b3ee1eff6728e2d1e07/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java#L402 + var bedrockAgentClient = + AWSBedrockAgentClient.builder() + .withCredentials(CREDENTIALS_PROVIDER) + .withEndpointConfiguration( + new EndpointConfiguration("http://bedrock.test:8080", Regions.US_WEST_2.getName())) + .build(); + var bedrockClient = + AmazonBedrockClient.builder() + .withCredentials(CREDENTIALS_PROVIDER) + .withEndpointConfiguration( + new EndpointConfiguration("http://bedrock.test:8080", Regions.US_WEST_2.getName())) + .build(); + var bedrockAgentRuntimeClient = + AWSBedrockAgentRuntimeClient.builder() + .withCredentials(CREDENTIALS_PROVIDER) + .withEndpointConfiguration( + new EndpointConfiguration("http://bedrock.test:8080", Regions.US_WEST_2.getName())) + .build(); + var bedrockRuntimeClient = + AmazonBedrockRuntimeClient.builder() + .withCredentials(CREDENTIALS_PROVIDER) + .withEndpointConfiguration( + new EndpointConfiguration("http://bedrock.test:8080", Regions.US_WEST_2.getName())) + .build(); + + // Setup API routes for Bedrockļ¼Œ BedrockAgent, BedrockAgentRuntime, and BedrockRuntime services. + Utils.setupGetKnowledgeBaseRoute(mainStatus); + Utils.setupGetAgentRoute(mainStatus); + Utils.setupGetGuardrailRoute(mainStatus); + Utils.setupGetAgentMemoryRoute(mainStatus); + Utils.setupGetDataSourceRoute(mainStatus); + Utils.setupInvokeModelRoute(mainStatus); + Utils.setupRetrieveRoute(mainStatus); + + get( + "/bedrockagent/getknowledgeBase/:knowledgeBaseId", + (req, res) -> { + setMainStatus(200); + String knowledgeBaseId = req.params(":knowledgeBaseId"); + GetKnowledgeBaseRequest request = + new GetKnowledgeBaseRequest().withKnowledgeBaseId(knowledgeBaseId); + bedrockAgentClient.getKnowledgeBase(request); + return ""; + }); + get( + "/bedrockruntime/invokeModel", + (req, res) -> { + setMainStatus(200); + String modelId = "anthropic.claude-v2"; + InvokeModelRequest invokeModelRequest = + new InvokeModelRequest() + .withModelId(modelId) + .withBody( + StandardCharsets.UTF_8.encode( + "{\"prompt\":\"Hello, world!\",\"temperature\":0.7,\"top_p\":0.9,\"max_tokens_to_sample\":100}\n")); + bedrockRuntimeClient.invokeModel(invokeModelRequest); + return ""; + }); + + get( + "/bedrockagent/get-data-source", + (req, res) -> { + setMainStatus(200); + + GetDataSourceRequest request = + new GetDataSourceRequest() + .withDataSourceId("nonExistDatasourceId") + .withKnowledgeBaseId("nonExistKnowledgeBaseId"); + bedrockAgentClient.getDataSource(request); + return ""; + }); + get( + "/bedrockagent/getagent/:agentId", + (req, res) -> { + setMainStatus(200); + String testAgentId = req.params(":agentId"); + GetAgentRequest request = new GetAgentRequest().withAgentId(testAgentId); + bedrockAgentClient.getAgent(request); + return ""; + }); + get( + "/bedrock/getguardrail", + (req, res) -> { + setMainStatus(200); + GetGuardrailRequest request = + new GetGuardrailRequest() + .withGuardrailIdentifier("test-bedrock-guardrail") + .withGuardrailVersion("DRAFT"); + bedrockClient.getGuardrail(request); + return ""; + }); + get( + "/bedrockagentruntime/getmemory/:agentId", + (req, res) -> { + setMainStatus(200); + String agentId = req.params(":agentId"); + GetAgentMemoryRequest request = + new GetAgentMemoryRequest().withAgentId(agentId).withAgentAliasId("agent-alias-id"); + var repo = bedrockAgentRuntimeClient.getAgentMemory(request); + return ""; + }); + get( + "/bedrockagentruntime/retrieve/:knowledgeBaseId", + (req, res) -> { + setMainStatus(200); + String knowledgeBaseId = req.params(":knowledgeBaseId"); + RetrieveRequest request = new RetrieveRequest().withKnowledgeBaseId(knowledgeBaseId); + var repo = bedrockAgentRuntimeClient.retrieve(request); + return ""; + }); + } } diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-v2/build.gradle.kts b/appsignals-tests/images/aws-sdk/aws-sdk-v2/build.gradle.kts index ee60662ae3..e50f70772f 100644 --- a/appsignals-tests/images/aws-sdk/aws-sdk-v2/build.gradle.kts +++ b/appsignals-tests/images/aws-sdk/aws-sdk-v2/build.gradle.kts @@ -27,13 +27,19 @@ dependencies { implementation("com.sparkjava:spark-core") implementation("com.google.code.gson:gson:2.10.1") implementation("org.slf4j:slf4j-simple") - implementation(enforcedPlatform("software.amazon.awssdk:bom:2.20.102")) + implementation(project(":appsignals-tests:images:aws-sdk:aws-sdk-base")) + implementation(enforcedPlatform("software.amazon.awssdk:bom:2.26.20")) implementation("software.amazon.awssdk:s3") implementation("software.amazon.awssdk:dynamodb") implementation("software.amazon.awssdk:sqs") implementation("software.amazon.awssdk:kinesis") + implementation("software.amazon.awssdk:bedrock") + implementation("software.amazon.awssdk:bedrockagent") + implementation("software.amazon.awssdk:bedrockruntime") + implementation("software.amazon.awssdk:bedrockagentruntime") implementation("commons-logging:commons-logging") implementation("com.linecorp.armeria:armeria") + implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") } java { diff --git a/appsignals-tests/images/aws-sdk/aws-sdk-v2/src/main/java/com/amazon/sampleapp/App.java b/appsignals-tests/images/aws-sdk/aws-sdk-v2/src/main/java/com/amazon/sampleapp/App.java index a4ce9732d3..bc43402e9d 100644 --- a/appsignals-tests/images/aws-sdk/aws-sdk-v2/src/main/java/com/amazon/sampleapp/App.java +++ b/appsignals-tests/images/aws-sdk/aws-sdk-v2/src/main/java/com/amazon/sampleapp/App.java @@ -21,6 +21,8 @@ import static spark.Spark.port; import static spark.Spark.post; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; @@ -36,6 +38,17 @@ import software.amazon.awssdk.core.retry.RetryPolicy; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrock.BedrockClient; +import software.amazon.awssdk.services.bedrock.model.GetGuardrailRequest; +import software.amazon.awssdk.services.bedrockagent.BedrockAgentClient; +import software.amazon.awssdk.services.bedrockagent.model.GetAgentRequest; +import software.amazon.awssdk.services.bedrockagent.model.GetDataSourceRequest; +import software.amazon.awssdk.services.bedrockagent.model.GetKnowledgeBaseRequest; +import software.amazon.awssdk.services.bedrockagentruntime.BedrockAgentRuntimeClient; +import software.amazon.awssdk.services.bedrockagentruntime.model.GetAgentMemoryRequest; +import software.amazon.awssdk.services.bedrockagentruntime.model.RetrieveRequest; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; +import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelRequest; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; @@ -105,6 +118,7 @@ public static void main(String[] args) throws IOException, InterruptedException setupS3(); setupSqs(); setupKinesis(); + setupBedrock(); // Add this log line so that we only start testing after all routes are configured. awaitInitialization(); logger.info("All routes initialized"); @@ -514,4 +528,134 @@ private static void setupS3() { return ""; }); } + + private static void setupBedrock() { + // Localstack does not support Bedrock related services. + // We point all Bedrock related request endpoints to the local app, + // and then specifically handle each request to return the expected response. + // For the full list of services supported by Localstack, see: + // https://github.com/testcontainers/testcontainers-java/blob/1f38f0d9604edb9e89fd3b3ee1eff6728e2d1e07/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java#L402 + var objectMapper = new ObjectMapper(); + var bedrockClient = + BedrockClient.builder() + .endpointOverride(URI.create("http://bedrock.test:8080")) + .region(Region.US_WEST_2) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + var bedrockAgentClient = + BedrockAgentClient.builder() + .endpointOverride(URI.create("http://bedrock.test:8080")) + .region(Region.US_WEST_2) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + var bedrockAgentRuntimeClient = + BedrockAgentRuntimeClient.builder() + .endpointOverride(URI.create("http://bedrock.test:8080")) + .region(Region.US_WEST_2) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + var bedrockRuntimeClient = + BedrockRuntimeClient.builder() + .endpointOverride(URI.create("http://bedrock.test:8080")) + .region(Region.US_WEST_2) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + + // Setup API routes for Bedrockļ¼Œ BedrockAgent, BedrockAgentRuntime, and BedrockRuntime services. + Utils.setupGetKnowledgeBaseRoute(mainStatus); + Utils.setupGetAgentRoute(mainStatus); + Utils.setupGetGuardrailRoute(mainStatus); + Utils.setupGetAgentMemoryRoute(mainStatus); + Utils.setupGetDataSourceRoute(mainStatus); + Utils.setupInvokeModelRoute(mainStatus); + Utils.setupRetrieveRoute(mainStatus); + + get( + "/bedrockagent/getknowledgeBase/:knowledgeBaseId", + (req, res) -> { + setMainStatus(200); + String knowledgeBaseId = req.params(":knowledgeBaseId"); + GetKnowledgeBaseRequest request = + GetKnowledgeBaseRequest.builder().knowledgeBaseId(knowledgeBaseId).build(); + bedrockAgentClient.getKnowledgeBase(request); + return ""; + }); + get( + "/bedrockruntime/invokeModel", + (req, res) -> { + setMainStatus(200); + String llama2ModelId = "anthropic.claude-v2"; + ObjectNode payload = objectMapper.createObjectNode(); + payload.put("prompt", "test prompt"); + payload.put("max_gen_len", 1000); + payload.put("temperature", 0.5); + payload.put("top_p", 0.9); + InvokeModelRequest request = + InvokeModelRequest.builder() + .body(SdkBytes.fromUtf8String(payload.toString())) + .modelId(llama2ModelId) + .contentType("application/json") + .accept("application/json") + .build(); + bedrockRuntimeClient.invokeModel(request); + return ""; + }); + get( + "/bedrockagent/get-data-source", + (req, res) -> { + setMainStatus(200); + + GetDataSourceRequest request = + GetDataSourceRequest.builder() + .dataSourceId("nonExistDatasourceId") + .knowledgeBaseId("nonExistKnowledgeBaseId") + .build(); + bedrockAgentClient.getDataSource(request); + return ""; + }); + get( + "/bedrockagent/getagent/:agentId", + (req, res) -> { + setMainStatus(200); + String agentId = req.params(":agentId"); + GetAgentRequest request = GetAgentRequest.builder().agentId(agentId).build(); + bedrockAgentClient.getAgent(request); + return ""; + }); + get( + "/bedrockagentruntime/getmemory/:agentId", + (req, res) -> { + setMainStatus(200); + String agentId = req.params(":agentId"); + GetAgentMemoryRequest request = + GetAgentMemoryRequest.builder() + .agentId(agentId) + .agentAliasId("agent-alias-id") + .build(); + bedrockAgentRuntimeClient.getAgentMemory(request); + return ""; + }); + get( + "/bedrock/getguardrail", + (req, res) -> { + setMainStatus(200); + GetGuardrailRequest request = + GetGuardrailRequest.builder() + .guardrailIdentifier("test-bedrock-guardrail") + .guardrailVersion("DRAFT") + .build(); + bedrockClient.getGuardrail(request); + return ""; + }); + get( + "/bedrockagentruntime/retrieve/:knowledgeBaseId", + (req, res) -> { + setMainStatus(200); + String knowledgeBaseId = req.params(":knowledgeBaseId"); + RetrieveRequest request = + RetrieveRequest.builder().knowledgeBaseId(knowledgeBaseId).build(); + var repo = bedrockAgentRuntimeClient.retrieve(request); + return ""; + }); + } } diff --git a/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java b/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java index 91fedf576d..9759753791 100644 --- a/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java +++ b/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java @@ -747,12 +747,12 @@ public void testSdkClientSpanWithRemoteResourceAttributes() { validateRemoteResourceAttributes("AWS::Bedrock::Guardrail", "test_guardrail_^^id"); mockAttribute(AWS_GUARDRAIL_ID, null); - // Validate behaviour of AWS_BEDROCK_RUNTIME_MODEL_ID attribute, then remove it. + // Validate behaviour of GEN_AI_REQUEST_MODEL attribute, then remove it. mockAttribute(GEN_AI_REQUEST_MODEL, "test.service_id"); validateRemoteResourceAttributes("AWS::Bedrock::Model", "test.service_id"); mockAttribute(GEN_AI_REQUEST_MODEL, null); - // Validate behaviour of AWS_BEDROCK_RUNTIME_MODEL_ID attribute with special chars(^), then + // Validate behaviour of GEN_AI_REQUEST_MODEL attribute with special chars(^), then // remove it. mockAttribute(GEN_AI_REQUEST_MODEL, "test.service_^id"); validateRemoteResourceAttributes("AWS::Bedrock::Model", "test.service_^^id"); diff --git a/settings.gradle.kts b/settings.gradle.kts index 75b7909bd7..cc52e2b49c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -61,6 +61,7 @@ include("appsignals-tests:images:http-clients:native-http-client") include("appsignals-tests:images:http-clients:spring-mvc-client") include("appsignals-tests:images:http-clients:apache-http-client") include("appsignals-tests:images:http-clients:netty-http-client") +include("appsignals-tests:images:aws-sdk:aws-sdk-base") include("appsignals-tests:images:aws-sdk:aws-sdk-v1") include("appsignals-tests:images:aws-sdk:aws-sdk-v2") include("appsignals-tests:images:grpc:grpc-base")