You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2023/01/31 09:51:03 UTC
[camel] 02/04: CAMEL-18131 - camel-health - Add health checks for components that has extension for connectivity verification - AWS Lambda
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit cc47b9f5edd889657b5274afe486ae16ec6441d4
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Jan 31 10:40:30 2023 +0100
CAMEL-18131 - camel-health - Add health checks for components that has extension for connectivity verification - AWS Lambda
Signed-off-by: Andrea Cosentino <an...@gmail.com>
---
components/camel-aws/camel-aws2-lambda/pom.xml | 4 +
.../aws2/lambda/Lambda2ClientHealthCheck.java | 77 +++++++++++++++++
.../component/aws2/lambda/Lambda2Endpoint.java | 18 ++++
.../Lambda2ClientHealthCheckProfileCredsTest.java | 97 ++++++++++++++++++++++
.../Lambda2ClientHealthCheckStaticCredsTest.java | 97 ++++++++++++++++++++++
5 files changed, 293 insertions(+)
diff --git a/components/camel-aws/camel-aws2-lambda/pom.xml b/components/camel-aws/camel-aws2-lambda/pom.xml
index 4e15beeb148..e91625a5b4f 100644
--- a/components/camel-aws/camel-aws2-lambda/pom.xml
+++ b/components/camel-aws/camel-aws2-lambda/pom.xml
@@ -73,6 +73,10 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-health</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheck.java b/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheck.java
new file mode 100644
index 00000000000..b695c62697f
--- /dev/null
+++ b/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheck.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.camel.component.aws2.lambda;
+
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.impl.health.AbstractHealthCheck;
+import org.apache.camel.util.ObjectHelper;
+import software.amazon.awssdk.awscore.exception.AwsServiceException;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.lambda.LambdaClient;
+import software.amazon.awssdk.services.lambda.model.ListFunctionsRequest;
+
+import java.util.Map;
+
+public class Lambda2ClientHealthCheck extends AbstractHealthCheck {
+
+ private final Lambda2Endpoint lambda2Endpoint;
+
+ public Lambda2ClientHealthCheck(Lambda2Endpoint lambda2Endpoint, String clientId) {
+ super("camel", "aws2-lambda-client-" + clientId);
+ this.lambda2Endpoint = lambda2Endpoint;
+ }
+
+ @Override
+ public boolean isLiveness() {
+ // this health check is only readiness
+ return false;
+ }
+
+ @Override
+ protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) {
+ Lambda2Configuration configuration = lambda2Endpoint.getConfiguration();
+ if (ObjectHelper.isNotEmpty(configuration.getRegion())) {
+ if (!LambdaClient.serviceMetadata().regions().contains(Region.of(configuration.getRegion()))) {
+ builder.message("The service is not supported in this region");
+ builder.down();
+ return;
+ }
+ }
+ try {
+ LambdaClient lambda2Client = lambda2Endpoint.getAwsLambdaClient();
+
+ lambda2Client.listFunctions(ListFunctionsRequest.builder().maxItems(1).build());
+ } catch (AwsServiceException e) {
+ builder.message(e.getMessage());
+ builder.error(e);
+ if (ObjectHelper.isNotEmpty(e.statusCode())) {
+ builder.detail(SERVICE_STATUS_CODE, e.statusCode());
+ }
+ if (ObjectHelper.isNotEmpty(e.awsErrorDetails().errorCode())) {
+ builder.detail(SERVICE_ERROR_CODE, e.awsErrorDetails().errorCode());
+ }
+ builder.down();
+ return;
+ } catch (Exception e) {
+ builder.error(e);
+ builder.down();
+ return;
+ }
+ builder.up();
+ }
+}
diff --git a/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2Endpoint.java b/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2Endpoint.java
index ea31f833df8..3aace85070f 100644
--- a/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2Endpoint.java
+++ b/components/camel-aws/camel-aws2-lambda/src/main/java/org/apache/camel/component/aws2/lambda/Lambda2Endpoint.java
@@ -22,6 +22,8 @@ import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.aws2.lambda.client.Lambda2ClientFactory;
+import org.apache.camel.health.HealthCheckHelper;
+import org.apache.camel.impl.health.ComponentsHealthCheckRepository;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
@@ -40,6 +42,9 @@ public class Lambda2Endpoint extends DefaultEndpoint {
private LambdaClient awsLambdaClient;
+ private ComponentsHealthCheckRepository healthCheckRepository;
+ private Lambda2ClientHealthCheck clientHealthCheck;
+
@UriPath
@Metadata(required = true)
private String function;
@@ -78,10 +83,23 @@ public class Lambda2Endpoint extends DefaultEndpoint {
awsLambdaClient = configuration.getAwsLambdaClient() != null
? configuration.getAwsLambdaClient()
: Lambda2ClientFactory.getLambdaClient(configuration).getLambdaClient();
+
+ healthCheckRepository = HealthCheckHelper.getHealthCheckRepository(getCamelContext(),
+ ComponentsHealthCheckRepository.REPOSITORY_ID, ComponentsHealthCheckRepository.class);
+
+ if (healthCheckRepository != null) {
+ clientHealthCheck = new Lambda2ClientHealthCheck(this, getId());
+ healthCheckRepository.addHealthCheck(clientHealthCheck);
+ }
}
@Override
public void doStop() throws Exception {
+ if (healthCheckRepository != null && clientHealthCheck != null) {
+ healthCheckRepository.removeHealthCheck(clientHealthCheck);
+ clientHealthCheck = null;
+ }
+
if (ObjectHelper.isEmpty(configuration.getAwsLambdaClient())) {
if (awsLambdaClient != null) {
awsLambdaClient.close();
diff --git a/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckProfileCredsTest.java b/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckProfileCredsTest.java
new file mode 100644
index 00000000000..7338270198a
--- /dev/null
+++ b/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckProfileCredsTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.camel.component.aws2.lambda;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckHelper;
+import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
+
+public class Lambda2ClientHealthCheckProfileCredsTest extends CamelTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Lambda2ClientHealthCheckProfileCredsTest.class);
+
+ CamelContext context;
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ context = super.createCamelContext();
+ context.getPropertiesComponent().setLocation("ref:prop");
+
+ // install health check manually (yes a bit cumbersome)
+ HealthCheckRegistry registry = new DefaultHealthCheckRegistry();
+ registry.setCamelContext(context);
+ Object hc = registry.resolveById("context");
+ registry.register(hc);
+ hc = registry.resolveById("routes");
+ registry.register(hc);
+ hc = registry.resolveById("consumers");
+ registry.register(hc);
+ context.setExtension(HealthCheckRegistry.class, registry);
+
+ return context;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+
+ @Override
+ public void configure() {
+ from("direct:listClusters")
+ .to("aws2-lambda://test?operation=listFunctions®ion=l&useDefaultCredentialsProvider=true");
+ }
+ };
+ }
+
+ @Test
+ public void testConnectivity() {
+
+ Collection<HealthCheck.Result> res = HealthCheckHelper.invokeLiveness(context);
+ boolean up = res.stream().allMatch(r -> r.getState().equals(HealthCheck.State.UP));
+ Assertions.assertTrue(up, "liveness check");
+
+ // health-check readiness should be down
+ await().atMost(20, TimeUnit.SECONDS).untilAsserted(() -> {
+ Collection<HealthCheck.Result> res2 = HealthCheckHelper.invokeReadiness(context);
+ boolean down = res2.stream().allMatch(r -> r.getState().equals(HealthCheck.State.DOWN));
+ boolean containsAws2LambdaHealthCheck = res2.stream()
+ .filter(result -> result.getCheck().getId().startsWith("aws2-lambda-client"))
+ .findAny()
+ .isPresent();
+ boolean hasRegionMessage = res2.stream()
+ .anyMatch(r -> r.getMessage().stream().anyMatch(msg -> msg.contains("region")));
+ Assertions.assertTrue(down, "liveness check");
+ Assertions.assertTrue(containsAws2LambdaHealthCheck, "aws2-lambda check");
+ Assertions.assertTrue(hasRegionMessage, "aws2-lambda check error message");
+ });
+
+ }
+}
diff --git a/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckStaticCredsTest.java b/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckStaticCredsTest.java
new file mode 100644
index 00000000000..ee69aa0861e
--- /dev/null
+++ b/components/camel-aws/camel-aws2-lambda/src/test/java/org/apache/camel/component/aws2/lambda/Lambda2ClientHealthCheckStaticCredsTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.camel.component.aws2.lambda;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckHelper;
+import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
+
+public class Lambda2ClientHealthCheckStaticCredsTest extends CamelTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Lambda2ClientHealthCheckStaticCredsTest.class);
+
+ CamelContext context;
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ context = super.createCamelContext();
+ context.getPropertiesComponent().setLocation("ref:prop");
+
+ // install health check manually (yes a bit cumbersome)
+ HealthCheckRegistry registry = new DefaultHealthCheckRegistry();
+ registry.setCamelContext(context);
+ Object hc = registry.resolveById("context");
+ registry.register(hc);
+ hc = registry.resolveById("routes");
+ registry.register(hc);
+ hc = registry.resolveById("consumers");
+ registry.register(hc);
+ context.setExtension(HealthCheckRegistry.class, registry);
+
+ return context;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+
+ @Override
+ public void configure() {
+ from("direct:listClusters")
+ .to("aws2-lambda://test?operation=listFunctions®ion=l&secretKey=l&accessKey=k");
+ }
+ };
+ }
+
+ @Test
+ public void testConnectivity() {
+
+ Collection<HealthCheck.Result> res = HealthCheckHelper.invokeLiveness(context);
+ boolean up = res.stream().allMatch(r -> r.getState().equals(HealthCheck.State.UP));
+ Assertions.assertTrue(up, "liveness check");
+
+ // health-check readiness should be down
+ await().atMost(20, TimeUnit.SECONDS).untilAsserted(() -> {
+ Collection<HealthCheck.Result> res2 = HealthCheckHelper.invokeReadiness(context);
+ boolean down = res2.stream().allMatch(r -> r.getState().equals(HealthCheck.State.DOWN));
+ boolean containsAws2LambdaHealthCheck = res2.stream()
+ .filter(result -> result.getCheck().getId().startsWith("aws2-lambda-client"))
+ .findAny()
+ .isPresent();
+ boolean hasRegionMessage = res2.stream()
+ .anyMatch(r -> r.getMessage().stream().anyMatch(msg -> msg.contains("region")));
+ Assertions.assertTrue(down, "liveness check");
+ Assertions.assertTrue(containsAws2LambdaHealthCheck, "aws2-lambda check");
+ Assertions.assertTrue(hasRegionMessage, "aws2-lambda check error message");
+ });
+
+ }
+}