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 2020/02/03 18:25:21 UTC

[camel] 01/07: CAMEL-14478 - Create an AWS-KMS component based on SDK v2

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bba3bca58ab74f00d805a920083a056489caa766
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Mon Feb 3 17:45:01 2020 +0100

    CAMEL-14478 - Create an AWS-KMS component based on SDK v2
---
 components/camel-aws2-kms/pom.xml                  |  86 +++++
 .../src/main/docs/aws-kms-component.adoc           | 200 ++++++++++++
 .../camel/component/aws2/kms/KMS2Component.java    | 122 +++++++
 .../aws2/kms/KMS2ComponentVerifierExtension.java   |  85 +++++
 .../component/aws2/kms/KMS2Configuration.java      | 152 +++++++++
 .../camel/component/aws2/kms/KMS2Constants.java    |  28 ++
 .../camel/component/aws2/kms/KMS2Endpoint.java     | 120 +++++++
 .../camel/component/aws2/kms/KMS2Operations.java   |  27 ++
 .../camel/component/aws2/kms/KMS2Producer.java     | 234 ++++++++++++++
 .../component/aws2/kms/AmazonKMSClientMock.java    | 106 +++++++
 .../aws2/kms/KMSComponentClientRegistryTest.java   |  43 +++
 .../aws2/kms/KMSComponentConfigurationTest.java    |  69 ++++
 .../kms/KMSComponentVerifierExtensionTest.java     |  74 +++++
 .../component/aws2/kms/KMSProducerSpringTest.java  | 149 +++++++++
 .../camel/component/aws2/kms/KMSProducerTest.java  | 175 ++++++++++
 .../src/test/resources/log4j2.properties           |  28 ++
 .../aws2/kms/KMSComponentSpringTest-context.xml    |  60 ++++
 .../builder/endpoint/EndpointBuilderFactory.java   |   1 +
 .../camel/builder/endpoint/EndpointBuilders.java   |   1 +
 .../endpoint/dsl/KMS2EndpointBuilderFactory.java   | 353 +++++++++++++++++++++
 20 files changed, 2113 insertions(+)

diff --git a/components/camel-aws2-kms/pom.xml b/components/camel-aws2-kms/pom.xml
new file mode 100644
index 0000000..08fb697
--- /dev/null
+++ b/components/camel-aws2-kms/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>3.1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-aws2-kms</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: AWS2 KMS</name>
+    <description>A Camel Amazon KMS Web Service Component Version 2</description>
+
+    <properties>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>kms</artifactId>
+            <version>${aws-java-sdk2-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>apache-client</artifactId>
+            <version>${aws-java-sdk2-version}</version>
+        </dependency>
+
+        <!-- for testing -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/components/camel-aws2-kms/src/main/docs/aws-kms-component.adoc b/components/camel-aws2-kms/src/main/docs/aws-kms-component.adoc
new file mode 100644
index 0000000..4b57400
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/docs/aws-kms-component.adoc
@@ -0,0 +1,200 @@
+[[aws-kms-component]]
+= AWS KMS Component
+
+*Since Camel 2.21*
+
+// HEADER START
+*Only producer is supported*
+// HEADER END
+
+The KMS component supports the ability to work with keys stored in
+https://aws.amazon.com/kms/[AWS KMS] instances.
+
+Prerequisites
+
+You must have a valid Amazon Web Services developer account, and be
+signed up to use Amazon KMS. More information is available at
+https://aws.amazon.com/kms/[Amazon KMS].
+
+== URI Format
+
+[source,java]
+-------------------------
+aws-kms://label[?options]
+-------------------------
+
+You can append query options to the URI in the following format,
+?options=value&option2=value&...
+
+== URI Options
+
+
+// component options: START
+The AWS KMS component supports 6 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *configuration* (advanced) | The AWS KMS default configuration |  | KMSConfiguration
+| *accessKey* (producer) | Amazon AWS Access Key |  | String
+| *secretKey* (producer) | Amazon AWS Secret Key |  | String
+| *region* (producer) | The region in which KMS client needs to work |  | String
+| *basicPropertyBinding* (advanced) | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+|===
+// component options: END
+
+
+
+
+// endpoint options: START
+The AWS KMS endpoint is configured using URI syntax:
+
+----
+aws-kms:label
+----
+
+with the following path and query parameters:
+
+=== Path Parameters (1 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *label* | *Required* Logical name |  | String
+|===
+
+
+=== Query Parameters (11 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *accessKey* (producer) | Amazon AWS Access Key |  | String
+| *kmsClient* (producer) | To use a existing configured AWS KMS as client |  | AWSKMS
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+| *operation* (producer) | *Required* The operation to perform |  | KMSOperations
+| *proxyHost* (producer) | To define a proxy host when instantiating the KMS client |  | String
+| *proxyPort* (producer) | To define a proxy port when instantiating the KMS client |  | Integer
+| *proxyProtocol* (producer) | To define a proxy protocol when instantiating the KMS client | HTTPS | Protocol
+| *region* (producer) | The region in which KMS client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1) You'll need to use the name Regions.EU_WEST_1.name() |  | String
+| *secretKey* (producer) | Amazon AWS Secret Key |  | String
+| *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
+| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
+|===
+// endpoint options: END
+// spring-boot-auto-configure options: START
+== Spring Boot Auto-Configuration
+
+When using Spring Boot make sure to use the following Maven dependency to have support for auto configuration:
+
+[source,xml]
+----
+<dependency>
+  <groupId>org.apache.camel.springboot</groupId>
+  <artifactId>camel-aws-kms-starter</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----
+
+
+The component supports 15 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *camel.component.aws-kms.access-key* | Amazon AWS Access Key |  | String
+| *camel.component.aws-kms.basic-property-binding* | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | Boolean
+| *camel.component.aws-kms.bridge-error-handler* | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | Boolean
+| *camel.component.aws-kms.configuration.access-key* | Amazon AWS Access Key |  | String
+| *camel.component.aws-kms.configuration.kms-client* | To use a existing configured AWS KMS as client |  | AWSKMS
+| *camel.component.aws-kms.configuration.operation* | The operation to perform |  | KMSOperations
+| *camel.component.aws-kms.configuration.proxy-host* | To define a proxy host when instantiating the KMS client |  | String
+| *camel.component.aws-kms.configuration.proxy-port* | To define a proxy port when instantiating the KMS client |  | Integer
+| *camel.component.aws-kms.configuration.proxy-protocol* | To define a proxy protocol when instantiating the KMS client |  | Protocol
+| *camel.component.aws-kms.configuration.region* | The region in which KMS client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1) You'll need to use the name Regions.EU_WEST_1.name() |  | String
+| *camel.component.aws-kms.configuration.secret-key* | Amazon AWS Secret Key |  | String
+| *camel.component.aws-kms.enabled* | Whether to enable auto configuration of the aws-kms component. This is enabled by default. |  | Boolean
+| *camel.component.aws-kms.lazy-start-producer* | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed th [...]
+| *camel.component.aws-kms.region* | The region in which KMS client needs to work |  | String
+| *camel.component.aws-kms.secret-key* | Amazon AWS Secret Key |  | String
+|===
+// spring-boot-auto-configure options: END
+
+
+
+
+Required KMS component options
+
+You have to provide the amazonKmsClient in the
+Registry or your accessKey and secretKey to access
+the https://aws.amazon.com/kms/[Amazon KMS] service.
+
+== Usage
+
+=== Message headers evaluated by the KMS producer
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Header |Type |Description
+
+|`CamelAwsKMSLimit` |`Integer` |The limit number of keys to return while performing a listKeys operation
+
+|`CamelAwsKMSOperation` |`String` |The operation we want to perform
+
+|`CamelAwsKMSDescription` |`String` |A key description to use while performing a createKey operation
+
+|`CamelAwsKMSKeyId` |`String` |The key Id 
+|=======================================================================
+
+=== KMS Producer operations
+
+Camel-AWS KMS component provides the following operation on the producer side:
+
+- listKeys
+- createKey
+- disableKey
+- scheduleKeyDeletion
+- describeKey
+- enableKey
+
+== Producer Examples
+
+- listKeys: this operation will list the available keys in KMS
+
+[source,java]
+--------------------------------------------------------------------------------
+from("direct:listKeys")
+      .to("aws-kms://test?kmsClient=#amazonKmsClient&operation=listKeys")
+--------------------------------------------------------------------------------
+
+== Automatic detection of AWSKMS client in registry
+
+The component is capable of detecting the presence of an AWSKMS bean into the registry.
+If it's the only instance of that type it will be used as client and you won't have to define it as uri parameter.
+This may be really useful for smarter configuration of the endpoint.
+
+Dependencies
+
+Maven users will need to add the following dependency to their pom.xml.
+
+*pom.xml*
+
+[source,xml]
+---------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-aws-kms</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+---------------------------------------
+
+where `$\{camel-version\}` must be replaced by the actual version of Camel.
+
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Component.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Component.java
new file mode 100644
index 0000000..8003761
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Component.java
@@ -0,0 +1,122 @@
+/*
+ * 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.kms;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+
+import software.amazon.awssdk.services.kms.KmsClient;
+
+/**
+ * For working with Amazon KMS.
+ */
+@Component("aws2-kms")
+public class KMS2Component extends DefaultComponent {
+
+    @Metadata
+    private String accessKey;
+    @Metadata
+    private String secretKey;
+    @Metadata
+    private String region;
+    @Metadata(label = "advanced")    
+    private KMS2Configuration configuration;
+    
+    public KMS2Component() {
+        this(null);
+    }
+    
+    public KMS2Component(CamelContext context) {
+        super(context);
+        
+        registerExtension(new KMS2ComponentVerifierExtension());
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        KMS2Configuration configuration = this.configuration != null ? this.configuration.copy() : new KMS2Configuration();
+        
+        KMS2Endpoint endpoint = new KMS2Endpoint(uri, this, configuration);
+        endpoint.getConfiguration().setAccessKey(accessKey);
+        endpoint.getConfiguration().setSecretKey(secretKey);
+        endpoint.getConfiguration().setRegion(region);
+        setProperties(endpoint, parameters);
+        checkAndSetRegistryClient(configuration);
+        if (configuration.getKmsClient() == null && (configuration.getAccessKey() == null || configuration.getSecretKey() == null)) {
+            throw new IllegalArgumentException("Amazon kms client or accessKey and secretKey must be specified");
+        }
+        
+        return endpoint;
+    }
+    
+    public KMS2Configuration getConfiguration() {
+        return configuration;
+    }
+
+    /**
+     * The AWS KMS default configuration
+     */
+    public void setConfiguration(KMS2Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    /**
+     * Amazon AWS Access Key
+     */
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    /**
+     * Amazon AWS Secret Key
+     */
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+    
+    public String getRegion() {
+        return region;
+    }
+
+    /**
+     * The region in which KMS client needs to work
+     */
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    private void checkAndSetRegistryClient(KMS2Configuration configuration) {
+        Set<KmsClient> clients = getCamelContext().getRegistry().findByType(KmsClient.class);
+        if (clients.size() == 1) {
+            configuration.setKmsClient(clients.stream().findFirst().get());
+        }
+    }
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2ComponentVerifierExtension.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2ComponentVerifierExtension.java
new file mode 100644
index 0000000..9c7779c
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2ComponentVerifierExtension.java
@@ -0,0 +1,85 @@
+/*
+ * 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.kms;
+
+import java.util.Map;
+
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.core.exception.SdkClientException;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.awssdk.services.kms.KmsClientBuilder;
+
+import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension;
+import org.apache.camel.component.extension.verifier.ResultBuilder;
+import org.apache.camel.component.extension.verifier.ResultErrorBuilder;
+import org.apache.camel.component.extension.verifier.ResultErrorHelper;
+
+public class KMS2ComponentVerifierExtension extends DefaultComponentVerifierExtension {
+
+    public KMS2ComponentVerifierExtension() {
+        this("aws2-kms");
+    }
+
+    public KMS2ComponentVerifierExtension(String scheme) {
+        super(scheme);
+    }
+
+    // *********************************
+    // Parameters validation
+    // *********************************
+
+    @Override
+    protected Result verifyParameters(Map<String, Object> parameters) {
+
+        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS).error(ResultErrorHelper.requiresOption("accessKey", parameters))
+            .error(ResultErrorHelper.requiresOption("secretKey", parameters)).error(ResultErrorHelper.requiresOption("region", parameters));
+
+        // Validate using the catalog
+
+        super.verifyParametersAgainstCatalog(builder, parameters);
+
+        return builder.build();
+    }
+
+    // *********************************
+    // Connectivity validation
+    // *********************************
+
+    @Override
+    protected Result verifyConnectivity(Map<String, Object> parameters) {
+        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY);
+
+        try {
+            KMS2Configuration configuration = setProperties(new KMS2Configuration(), parameters);
+            AwsBasicCredentials cred = AwsBasicCredentials.create(configuration.getAccessKey(), configuration.getSecretKey());
+            KmsClientBuilder clientBuilder = KmsClient.builder();
+            KmsClient client = clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred)).region(Region.of(configuration.getRegion())).build();
+            client.listKeys();
+        } catch (SdkClientException e) {
+            ResultErrorBuilder errorBuilder = ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, e.getMessage())
+                .detail("aws_kms_exception_message", e.getMessage()).detail(VerificationError.ExceptionAttribute.EXCEPTION_CLASS, e.getClass().getName())
+                .detail(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE, e);
+
+            builder.error(errorBuilder.build());
+        } catch (Exception e) {
+            builder.error(ResultErrorBuilder.withException(e).build());
+        }
+        return builder.build();
+    }
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Configuration.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Configuration.java
new file mode 100644
index 0000000..9efe1fc
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Configuration.java
@@ -0,0 +1,152 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+
+import software.amazon.awssdk.core.Protocol;
+import software.amazon.awssdk.services.kms.KmsClient;
+
+@UriParams
+public class KMS2Configuration implements Cloneable {
+
+    @UriPath(description = "Logical name")
+    @Metadata(required = true)
+    private String label;
+    @UriParam(label = "producer")
+    private KmsClient kmsClient;
+    @UriParam(label = "producer", secret = true)
+    private String accessKey;
+    @UriParam(label = "producer", secret = true)
+    private String secretKey;
+    @UriParam(label = "producer")
+    @Metadata(required = true)
+    private KMS2Operations operation;
+    @UriParam(enums = "HTTP,HTTPS", defaultValue = "HTTPS")
+    private Protocol proxyProtocol = Protocol.HTTPS;
+    @UriParam(label = "producer")
+    private String proxyHost;
+    @UriParam(label = "producer")
+    private Integer proxyPort;
+    @UriParam
+    private String region;
+
+    public KmsClient getKmsClient() {
+        return kmsClient;
+    }
+
+    /**
+     * To use a existing configured AWS KMS as client
+     */
+    public void setKmsClient(KmsClient kmsClient) {
+        this.kmsClient = kmsClient;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    /**
+     * Amazon AWS Access Key
+     */
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    /**
+     * Amazon AWS Secret Key
+     */
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public KMS2Operations getOperation() {
+        return operation;
+    }
+
+    /**
+     * The operation to perform
+     */
+    public void setOperation(KMS2Operations operation) {
+        this.operation = operation;
+    }
+    
+    public Protocol getProxyProtocol() {
+        return proxyProtocol;
+    }
+
+    /**
+     * To define a proxy protocol when instantiating the KMS client
+     */
+    public void setProxyProtocol(Protocol proxyProtocol) {
+        this.proxyProtocol = proxyProtocol;
+    }
+
+    public String getProxyHost() {
+        return proxyHost;
+    }
+
+    /**
+     * To define a proxy host when instantiating the KMS client
+     */
+    public void setProxyHost(String proxyHost) {
+        this.proxyHost = proxyHost;
+    }
+
+    public Integer getProxyPort() {
+        return proxyPort;
+    }
+
+    /**
+     * To define a proxy port when instantiating the KMS client
+     */
+    public void setProxyPort(Integer proxyPort) {
+        this.proxyPort = proxyPort;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    /**
+     * The region in which KMS client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1)
+     * You'll need to use the name Regions.EU_WEST_1.name()
+     */
+    public void setRegion(String region) {
+        this.region = region;
+    }
+    
+    // *************************************************
+    //
+    // *************************************************
+
+    public KMS2Configuration copy() {
+        try {
+            return (KMS2Configuration)super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Constants.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Constants.java
new file mode 100644
index 0000000..6b8d494
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Constants.java
@@ -0,0 +1,28 @@
+/*
+ * 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.kms;
+
+/**
+ * Constants used in Camel AWS KMS module
+ */
+public interface KMS2Constants {
+    String OPERATION                = "CamelAwsKMSOperation";
+    String LIMIT                    = "CamelAwsKMSLimit";
+    String DESCRIPTION              = "CamelAwsKMSDescription";
+    String KEY_ID                   = "CamelAwsKMSKeyId";
+    String PENDING_WINDOW_IN_DAYS   = "CamelAwsKMSPendingWindowInDays";
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Endpoint.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Endpoint.java
new file mode 100644
index 0000000..dfc061a
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Endpoint.java
@@ -0,0 +1,120 @@
+/*
+ * 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.kms;
+
+import java.net.URI;
+
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.support.ScheduledPollEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache.ApacheHttpClient;
+import software.amazon.awssdk.http.apache.ProxyConfiguration;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.awssdk.services.kms.KmsClientBuilder;
+
+/**
+ * The aws-kms is used for managing Amazon KMS
+ */
+@UriEndpoint(firstVersion = "3.1.0", scheme = "aws2-kms", title = "AWS 2 KMS", syntax = "aws2-kms:label", producerOnly = true, label = "cloud,management")
+public class KMS2Endpoint extends ScheduledPollEndpoint {
+
+    private KmsClient kmsClient;
+
+    @UriParam
+    private KMS2Configuration configuration;
+
+    public KMS2Endpoint(String uri, Component component, KMS2Configuration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        throw new UnsupportedOperationException("You cannot receive messages from this endpoint");
+    }
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new KMS2Producer(this);
+    }
+
+    @Override
+    public void doStart() throws Exception {
+        super.doStart();
+
+        kmsClient = configuration.getKmsClient() != null ? configuration.getKmsClient() : createKMSClient();
+    }
+    
+    @Override
+    public void doStop() throws Exception {
+        if (ObjectHelper.isEmpty(configuration.getKmsClient())) {
+            if (kmsClient != null) {
+                kmsClient.close();
+            }
+        }
+        super.doStop();
+    }
+
+    public KMS2Configuration getConfiguration() {
+        return configuration;
+    }
+
+    public KmsClient getKmsClient() {
+        return kmsClient;
+    }
+
+    KmsClient createKMSClient() {
+        KmsClient client = null;
+        KmsClientBuilder clientBuilder = KmsClient.builder();
+        ProxyConfiguration.Builder proxyConfig = null;
+        ApacheHttpClient.Builder httpClientBuilder = null;
+        boolean isClientConfigFound = false;
+        if (ObjectHelper.isNotEmpty(configuration.getProxyHost()) && ObjectHelper.isNotEmpty(configuration.getProxyPort())) {
+            proxyConfig = ProxyConfiguration.builder();
+            URI proxyEndpoint = URI.create(configuration.getProxyProtocol() + configuration.getProxyHost() + configuration.getProxyPort());
+            proxyConfig.endpoint(proxyEndpoint);
+            httpClientBuilder = ApacheHttpClient.builder().proxyConfiguration(proxyConfig.build());
+            isClientConfigFound = true;
+        }
+        if (configuration.getAccessKey() != null && configuration.getSecretKey() != null) {
+            AwsBasicCredentials cred = AwsBasicCredentials.create(configuration.getAccessKey(), configuration.getSecretKey());
+            if (isClientConfigFound) {
+                clientBuilder = clientBuilder.httpClientBuilder(httpClientBuilder).credentialsProvider(StaticCredentialsProvider.create(cred));
+            } else {
+                clientBuilder = clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred));
+            }
+        } else {
+            if (!isClientConfigFound) {
+                clientBuilder = clientBuilder.httpClientBuilder(httpClientBuilder);
+            }
+        }
+        if (ObjectHelper.isNotEmpty(configuration.getRegion())) {
+            clientBuilder = clientBuilder.region(Region.of(configuration.getRegion()));
+        }
+        client = clientBuilder.build();
+        return client;
+    }
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Operations.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Operations.java
new file mode 100644
index 0000000..cdf1205
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Operations.java
@@ -0,0 +1,27 @@
+/*
+ * 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.kms;
+
+public enum KMS2Operations {
+
+    listKeys,
+    createKey,
+    disableKey,
+    scheduleKeyDeletion,
+    describeKey,
+    enableKey
+}
diff --git a/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Producer.java b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Producer.java
new file mode 100644
index 0000000..66b0b45
--- /dev/null
+++ b/components/camel-aws2-kms/src/main/java/org/apache/camel/component/aws2/kms/KMS2Producer.java
@@ -0,0 +1,234 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.support.DefaultProducer;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import software.amazon.awssdk.awscore.exception.AwsServiceException;
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.awssdk.services.kms.model.CreateKeyRequest;
+import software.amazon.awssdk.services.kms.model.CreateKeyResponse;
+import software.amazon.awssdk.services.kms.model.DescribeKeyRequest;
+import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
+import software.amazon.awssdk.services.kms.model.DisableKeyRequest;
+import software.amazon.awssdk.services.kms.model.DisableKeyResponse;
+import software.amazon.awssdk.services.kms.model.EnableKeyRequest;
+import software.amazon.awssdk.services.kms.model.EnableKeyResponse;
+import software.amazon.awssdk.services.kms.model.ListKeysRequest;
+import software.amazon.awssdk.services.kms.model.ListKeysResponse;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionRequest;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionResponse;
+
+/**
+ * A Producer which sends messages to the Amazon KMS Service
+ * <a href="http://aws.amazon.com/kms/">AWS KMS</a>
+ */
+public class KMS2Producer extends DefaultProducer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KMS2Producer.class);
+
+    private transient String kmsProducerToString;
+
+    public KMS2Producer(Endpoint endpoint) {
+        super(endpoint);
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        switch (determineOperation(exchange)) {
+        case listKeys:
+            listKeys(getEndpoint().getKmsClient(), exchange);
+            break;
+        case createKey:
+            createKey(getEndpoint().getKmsClient(), exchange);
+            break;
+        case disableKey:
+            disableKey(getEndpoint().getKmsClient(), exchange);
+            break;
+        case enableKey:
+            enableKey(getEndpoint().getKmsClient(), exchange);
+            break;
+        case scheduleKeyDeletion:
+            scheduleKeyDeletion(getEndpoint().getKmsClient(), exchange);
+            break;
+        case describeKey:
+            describeKey(getEndpoint().getKmsClient(), exchange);
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported operation");
+        }
+    }
+
+    private KMS2Operations determineOperation(Exchange exchange) {
+        KMS2Operations operation = exchange.getIn().getHeader(KMS2Constants.OPERATION, KMS2Operations.class);
+        if (operation == null) {
+            operation = getConfiguration().getOperation();
+        }
+
+        if (ObjectHelper.isEmpty(operation)) {
+            throw new IllegalArgumentException("Operation must be specified");
+        }
+        return operation;
+    }
+
+    protected KMS2Configuration getConfiguration() {
+        return getEndpoint().getConfiguration();
+    }
+
+    @Override
+    public String toString() {
+        if (kmsProducerToString == null) {
+            kmsProducerToString = "KMSProducer[" + URISupport.sanitizeUri(getEndpoint().getEndpointUri()) + "]";
+        }
+        return kmsProducerToString;
+    }
+
+    @Override
+    public KMS2Endpoint getEndpoint() {
+        return (KMS2Endpoint)super.getEndpoint();
+    }
+
+    private void listKeys(KmsClient kmsClient, Exchange exchange) {
+        ListKeysRequest.Builder builder = ListKeysRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.LIMIT))) {
+            int limit = exchange.getIn().getHeader(KMS2Constants.LIMIT, Integer.class);
+            builder.limit(limit);
+        }
+        ListKeysResponse result;
+        try {
+            result = kmsClient.listKeys(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("List Keys command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    private void createKey(KmsClient kmsClient, Exchange exchange) {
+        CreateKeyRequest.Builder builder = CreateKeyRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.DESCRIPTION))) {
+            String description = exchange.getIn().getHeader(KMS2Constants.DESCRIPTION, String.class);
+            builder.description(description);
+        }
+        CreateKeyResponse result;
+        try {
+            result = kmsClient.createKey(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("Create Key command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    private void disableKey(KmsClient kmsClient, Exchange exchange) {
+        DisableKeyRequest.Builder builder = DisableKeyRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.KEY_ID))) {
+            String keyId = exchange.getIn().getHeader(KMS2Constants.KEY_ID, String.class);
+            builder.keyId(keyId);
+        } else {
+            throw new IllegalArgumentException("Key Id must be specified");
+        }
+        DisableKeyResponse result;
+        try {
+            result = kmsClient.disableKey(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("Disable Key command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    private void scheduleKeyDeletion(KmsClient kmsClient, Exchange exchange) {
+        ScheduleKeyDeletionRequest.Builder builder = ScheduleKeyDeletionRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.KEY_ID))) {
+            String keyId = exchange.getIn().getHeader(KMS2Constants.KEY_ID, String.class);
+            builder.keyId(keyId);
+        } else {
+            throw new IllegalArgumentException("Key Id must be specified");
+        }
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.PENDING_WINDOW_IN_DAYS))) {
+            int pendingWindows = exchange.getIn().getHeader(KMS2Constants.PENDING_WINDOW_IN_DAYS, Integer.class);
+            builder.pendingWindowInDays(pendingWindows);
+        } 
+        ScheduleKeyDeletionResponse result;
+        try {
+            result = kmsClient.scheduleKeyDeletion(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("Schedule Key Deletion command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    private void describeKey(KmsClient kmsClient, Exchange exchange) {
+        DescribeKeyRequest.Builder builder = DescribeKeyRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.KEY_ID))) {
+            String keyId = exchange.getIn().getHeader(KMS2Constants.KEY_ID, String.class);
+            builder.keyId(keyId);
+        } else {
+            throw new IllegalArgumentException("Key Id must be specified");
+        }
+        DescribeKeyResponse result;
+        try {
+            result = kmsClient.describeKey(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("Describe Key command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    private void enableKey(KmsClient kmsClient, Exchange exchange) {
+        EnableKeyRequest.Builder builder = EnableKeyRequest.builder();
+        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(KMS2Constants.KEY_ID))) {
+            String keyId = exchange.getIn().getHeader(KMS2Constants.KEY_ID, String.class);
+            builder.keyId(keyId);
+        } else {
+            throw new IllegalArgumentException("Key Id must be specified");
+        }
+        EnableKeyResponse result;
+        try {
+            result = kmsClient.enableKey(builder.build());
+        } catch (AwsServiceException ase) {
+            LOG.trace("Enable Key command returned the error code {}", ase.getMessage());
+            throw ase;
+        }
+        Message message = getMessageForResponse(exchange);
+        message.setBody(result);
+    }
+    
+    public static Message getMessageForResponse(final Exchange exchange) {
+        if (exchange.getPattern().isOutCapable()) {
+            Message out = exchange.getOut();
+            out.copyFrom(exchange.getIn());
+            return out;
+        }
+        return exchange.getIn();
+    }
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/AmazonKMSClientMock.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/AmazonKMSClientMock.java
new file mode 100644
index 0000000..8c30dc4
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/AmazonKMSClientMock.java
@@ -0,0 +1,106 @@
+/*
+ * 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.kms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.awssdk.services.kms.model.CreateKeyRequest;
+import software.amazon.awssdk.services.kms.model.CreateKeyResponse;
+import software.amazon.awssdk.services.kms.model.DescribeKeyRequest;
+import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
+import software.amazon.awssdk.services.kms.model.DisableKeyRequest;
+import software.amazon.awssdk.services.kms.model.DisableKeyResponse;
+import software.amazon.awssdk.services.kms.model.EnableKeyRequest;
+import software.amazon.awssdk.services.kms.model.EnableKeyResponse;
+import software.amazon.awssdk.services.kms.model.KeyListEntry;
+import software.amazon.awssdk.services.kms.model.KeyMetadata;
+import software.amazon.awssdk.services.kms.model.ListKeysRequest;
+import software.amazon.awssdk.services.kms.model.ListKeysResponse;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionRequest;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionResponse;
+
+public class AmazonKMSClientMock implements KmsClient {
+
+    public AmazonKMSClientMock() {
+    }
+
+    @Override
+    public CreateKeyResponse createKey(CreateKeyRequest createKeyRequest) {
+    	CreateKeyResponse.Builder res = CreateKeyResponse.builder();
+        KeyMetadata.Builder metadata = KeyMetadata.builder();
+        metadata.keyId("test");
+        metadata.enabled(true);
+        res.keyMetadata(metadata.build());
+        return res.build();
+    }
+
+    @Override
+    public DescribeKeyResponse describeKey(DescribeKeyRequest describeKeyRequest) {
+    	DescribeKeyResponse.Builder res = DescribeKeyResponse.builder();
+        KeyMetadata.Builder metadata = KeyMetadata.builder();
+        metadata.enabled(false);
+        metadata.description("MyCamelKey");
+        metadata.keyId("test");
+        res.keyMetadata(metadata.build());
+        return res.build();
+    }
+
+    @Override
+    public DisableKeyResponse disableKey(DisableKeyRequest disableKeyRequest) {
+        DisableKeyResponse res = DisableKeyResponse.builder().build();
+        return res;
+    }
+
+    @Override
+    public EnableKeyResponse enableKey(EnableKeyRequest enableKeyRequest) {
+    	EnableKeyResponse res = EnableKeyResponse.builder().build();
+        return res;
+    }
+
+    @Override
+    public ListKeysResponse listKeys(ListKeysRequest listKeysRequest) {
+    	ListKeysResponse.Builder result = ListKeysResponse.builder();
+        List<KeyListEntry> keyList = new ArrayList<>();
+        KeyListEntry.Builder kle = KeyListEntry.builder();
+        kle.keyId("keyId");
+        keyList.add(kle.build());
+        result.keys(keyList);
+        return result.build();
+    }
+
+    @Override
+    public ScheduleKeyDeletionResponse scheduleKeyDeletion(ScheduleKeyDeletionRequest scheduleKeyDeletionRequest) {
+    	ScheduleKeyDeletionResponse.Builder response = ScheduleKeyDeletionResponse.builder();
+    	response.keyId("test");
+        return response.build();
+    }
+
+	@Override
+	public String serviceName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void close() {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentClientRegistryTest.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentClientRegistryTest.java
new file mode 100644
index 0000000..53bb551
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentClientRegistryTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.component.aws2.kms.KMS2Component;
+import org.apache.camel.component.aws2.kms.KMS2Endpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class KMSComponentClientRegistryTest extends CamelTestSupport {
+
+    @Test
+    public void createEndpointWithMinimalKMSClientConfiguration() throws Exception {
+
+        AmazonKMSClientMock clientMock = new AmazonKMSClientMock();
+        context.getRegistry().bind("amazonKmsClient", clientMock);
+        KMS2Component component = context.getComponent("aws2-kms", KMS2Component.class);
+        KMS2Endpoint endpoint = (KMS2Endpoint)component.createEndpoint("aws2-kms://TestDomain");
+
+        assertNotNull(endpoint.getConfiguration().getKmsClient());
+    }
+    
+    @Test(expected = IllegalArgumentException.class)
+    public void createEndpointWithMinimalKMSClientMisconfiguration() throws Exception {
+
+        KMS2Component component = context.getComponent("aws2-kms", KMS2Component.class);
+        KMS2Endpoint endpoint = (KMS2Endpoint)component.createEndpoint("aws2-kms://TestDomain");
+    }
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentConfigurationTest.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentConfigurationTest.java
new file mode 100644
index 0000000..04b7663
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentConfigurationTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.component.aws2.kms.KMS2Component;
+import org.apache.camel.component.aws2.kms.KMS2Endpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import software.amazon.awssdk.core.Protocol;
+import software.amazon.awssdk.regions.Region;
+
+public class KMSComponentConfigurationTest extends CamelTestSupport {
+
+    
+    @Test
+    public void createEndpointWithComponentElements() throws Exception {
+        KMS2Component component = context.getComponent("aws2-kms", KMS2Component.class);
+        component.setAccessKey("XXX");
+        component.setSecretKey("YYY");
+        KMS2Endpoint endpoint = (KMS2Endpoint)component.createEndpoint("aws2-kms://label");
+        
+        assertEquals("XXX", endpoint.getConfiguration().getAccessKey());
+        assertEquals("YYY", endpoint.getConfiguration().getSecretKey());
+    }
+    
+    @Test
+    public void createEndpointWithComponentAndEndpointElements() throws Exception {
+        KMS2Component component = context.getComponent("aws2-kms", KMS2Component.class);
+        component.setAccessKey("XXX");
+        component.setSecretKey("YYY");
+        component.setRegion(Region.US_WEST_1.toString());
+        KMS2Endpoint endpoint = (KMS2Endpoint)component.createEndpoint("aws2-kms://label?accessKey=xxxxxx&secretKey=yyyyy&region=US_EAST_1");
+        
+        assertEquals("xxxxxx", endpoint.getConfiguration().getAccessKey());
+        assertEquals("yyyyy", endpoint.getConfiguration().getSecretKey());
+        assertEquals("US_EAST_1", endpoint.getConfiguration().getRegion());
+    }
+    
+    @Test
+    public void createEndpointWithComponentEndpointElementsAndProxy() throws Exception {
+        KMS2Component component = context.getComponent("aws2-kms", KMS2Component.class);
+        component.setAccessKey("XXX");
+        component.setSecretKey("YYY");
+        component.setRegion(Region.US_WEST_1.toString());
+        KMS2Endpoint endpoint = (KMS2Endpoint)component.createEndpoint("aws2-kms://label?accessKey=xxxxxx&secretKey=yyyyy&region=US_EAST_1&proxyHost=localhost&proxyPort=9000&proxyProtocol=HTTP");
+        
+        assertEquals("xxxxxx", endpoint.getConfiguration().getAccessKey());
+        assertEquals("yyyyy", endpoint.getConfiguration().getSecretKey());
+        assertEquals("US_EAST_1", endpoint.getConfiguration().getRegion());
+        assertEquals(Protocol.HTTP, endpoint.getConfiguration().getProxyProtocol());
+        assertEquals("localhost", endpoint.getConfiguration().getProxyHost());
+        assertEquals(Integer.valueOf(9000), endpoint.getConfiguration().getProxyPort());
+    }
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentVerifierExtensionTest.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentVerifierExtensionTest.java
new file mode 100644
index 0000000..ae237a6
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSComponentVerifierExtensionTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.kms;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Component;
+import org.apache.camel.component.aws2.kms.KMS2Operations;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class KMSComponentVerifierExtensionTest extends CamelTestSupport {
+
+    // *************************************************
+    // Tests (parameters)
+    // *************************************************
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        Component component = context().getComponent("aws2-kms");
+
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        Map<String, Object> parameters = new HashMap<>();
+        parameters.put("secretKey", "l");
+        parameters.put("accessKey", "k");
+        parameters.put("region", "l");
+        parameters.put("label", "test");
+        parameters.put("operation", KMS2Operations.listKeys);
+
+        ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testConnectivity() throws Exception {
+        Component component = context().getComponent("aws2-kms");
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        Map<String, Object> parameters = new HashMap<>();
+        parameters.put("secretKey", "l");
+        parameters.put("accessKey", "k");
+        parameters.put("region", "US_EAST_1");
+        parameters.put("label", "test");
+        parameters.put("operation", KMS2Operations.listKeys);
+
+        ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+    }
+
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerSpringTest.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerSpringTest.java
new file mode 100644
index 0000000..26f9f77
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerSpringTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.aws2.kms.KMS2Constants;
+import org.apache.camel.component.aws2.kms.KMS2Operations;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import software.amazon.awssdk.services.kms.model.CreateKeyResponse;
+import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
+import software.amazon.awssdk.services.kms.model.ListKeysResponse;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionResponse;
+
+public class KMSProducerSpringTest extends CamelSpringTestSupport {
+    
+    @EndpointInject("mock:result")
+    private MockEndpoint mock;
+    
+    @Test
+    public void kmsListBrokersTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:listKeys", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.listKeys);
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        ListKeysResponse resultGet = (ListKeysResponse) exchange.getIn().getBody();
+        assertEquals(1, resultGet.keys().size());
+        assertEquals("keyId", resultGet.keys().get(0).keyId());
+    }
+    
+    @Test
+    public void kmsCreateKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:createKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.createKey);
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        CreateKeyResponse resultGet = (CreateKeyResponse) exchange.getIn().getBody();
+        assertEquals("test", resultGet.keyMetadata().keyId());
+        assertEquals(true, resultGet.keyMetadata().enabled());
+    }
+    
+    @Test
+    public void kmsDisableKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        template.request("direct:disableKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.disableKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+    }
+    
+    @Test
+    public void kmsEnableKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        template.request("direct:enableKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.enableKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+    }
+    
+    @Test
+    public void kmsScheduleKeyDeletionTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:scheduleDelete", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.scheduleKeyDeletion);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        ScheduleKeyDeletionResponse resultGet = (ScheduleKeyDeletionResponse) exchange.getIn().getBody();
+        assertEquals("test", resultGet.keyId());
+    }
+    
+    @Test
+    public void kmsDescribeKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:describeKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.describeKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        DescribeKeyResponse resultGet = exchange.getIn().getBody(DescribeKeyResponse.class);
+        assertEquals("test", resultGet.keyMetadata().keyId());
+        assertEquals("MyCamelKey", resultGet.keyMetadata().description());
+        assertFalse(resultGet.keyMetadata().enabled());
+    }
+
+    @Override
+    protected ClassPathXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/component/aws2/kms/KMSComponentSpringTest-context.xml");
+    }
+}
diff --git a/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerTest.java b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerTest.java
new file mode 100644
index 0000000..9096c0a
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/java/org/apache/camel/component/aws2/kms/KMSProducerTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.kms;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.aws2.kms.KMS2Constants;
+import org.apache.camel.component.aws2.kms.KMS2Operations;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import software.amazon.awssdk.services.kms.model.CreateKeyResponse;
+import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
+import software.amazon.awssdk.services.kms.model.ListKeysResponse;
+import software.amazon.awssdk.services.kms.model.ScheduleKeyDeletionResponse;
+
+public class KMSProducerTest extends CamelTestSupport {
+
+    @BindToRegistry("amazonKmsClient")
+    AmazonKMSClientMock clientMock = new AmazonKMSClientMock();
+
+    @EndpointInject("mock:result")
+    private MockEndpoint mock;
+    
+    @Test
+    public void kmsListBrokersTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:listKeys", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.listKeys);
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        ListKeysResponse resultGet = (ListKeysResponse) exchange.getIn().getBody();
+        assertEquals(1, resultGet.keys().size());
+        assertEquals("keyId", resultGet.keys().get(0).keyId());
+    }
+    
+    @Test
+    public void kmsCreateKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:createKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.createKey);
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        CreateKeyResponse resultGet = (CreateKeyResponse) exchange.getIn().getBody();
+        assertEquals("test", resultGet.keyMetadata().keyId());
+        assertEquals(true, resultGet.keyMetadata().enabled());
+    }
+    
+    @Test
+    public void kmsDisableKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        template.request("direct:disableKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.disableKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+    }
+    
+    @Test
+    public void kmsEnableKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        template.request("direct:enableKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.enableKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+    }
+    
+    @Test
+    public void kmsScheduleKeyDeletionTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:scheduleDelete", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.scheduleKeyDeletion);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        ScheduleKeyDeletionResponse resultGet = (ScheduleKeyDeletionResponse) exchange.getIn().getBody();
+        assertEquals("test", resultGet.keyId());
+    }
+    
+    @Test
+    public void kmsDescribeKeyTest() throws Exception {
+
+        mock.expectedMessageCount(1);
+        Exchange exchange = template.request("direct:describeKey", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(KMS2Constants.OPERATION, KMS2Operations.describeKey);
+                exchange.getIn().setHeader(KMS2Constants.KEY_ID, "test");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        
+        DescribeKeyResponse resultGet = exchange.getIn().getBody(DescribeKeyResponse.class);
+        assertEquals("test", resultGet.keyMetadata().keyId());
+        assertEquals("MyCamelKey", resultGet.keyMetadata().description());
+        assertFalse(resultGet.keyMetadata().enabled());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:listKeys")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=listKeys")
+                    .to("mock:result");
+                from("direct:createKey")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=createKey")
+                    .to("mock:result");
+                from("direct:disableKey")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=disableKey")
+                    .to("mock:result");
+                from("direct:enableKey")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=enableKey")
+                    .to("mock:result");
+                from("direct:scheduleDelete")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=scheduleKeyDeletion")
+                    .to("mock:result");
+                from("direct:describeKey")
+                    .to("aws2-kms://test?kmsClient=#amazonKmsClient&operation=describeKey")
+                    .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-aws2-kms/src/test/resources/log4j2.properties b/components/camel-aws2-kms/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..986f470
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/resources/log4j2.properties
@@ -0,0 +1,28 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-aws-kms-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components/camel-aws2-kms/src/test/resources/org/apache/camel/component/aws2/kms/KMSComponentSpringTest-context.xml b/components/camel-aws2-kms/src/test/resources/org/apache/camel/component/aws2/kms/KMSComponentSpringTest-context.xml
new file mode 100644
index 0000000..4a8a0f7
--- /dev/null
+++ b/components/camel-aws2-kms/src/test/resources/org/apache/camel/component/aws2/kms/KMSComponentSpringTest-context.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+    http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+        <route>
+            <from uri="direct:listKeys"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=listKeys"/>
+            <to uri="mock:result"/>
+        </route>
+        <route>
+            <from uri="direct:createKey"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=createKey"/>
+            <to uri="mock:result"/>
+        </route>
+        <route>
+            <from uri="direct:disableKey"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=disableKey"/>
+            <to uri="mock:result"/>
+        </route>
+        <route>
+            <from uri="direct:enableKey"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=enableKey"/>
+            <to uri="mock:result"/>
+        </route>
+        <route>
+            <from uri="direct:scheduleDelete"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=scheduleKeyDeletion"/>
+            <to uri="mock:result"/>
+        </route>
+        <route>
+            <from uri="direct:describeKey"/>
+            <to uri="aws2-kms://Test?kmsClient=#amazonKmsClient&amp;operation=describeKey"/>
+            <to uri="mock:result"/>
+        </route>
+    </camelContext>
+
+    <bean id="amazonKmsClient" class="org.apache.camel.component.aws2.kms.AmazonKMSClientMock"/>
+</beans>
\ No newline at end of file
diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
index 88861f8..3330c02 100644
--- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
@@ -186,6 +186,7 @@ public interface EndpointBuilderFactory
             org.apache.camel.builder.endpoint.dsl.JsltEndpointBuilderFactory.JsltBuilders,
             org.apache.camel.builder.endpoint.dsl.JsonValidatorEndpointBuilderFactory.JsonValidatorBuilders,
             org.apache.camel.builder.endpoint.dsl.Jt400EndpointBuilderFactory.Jt400Builders,
+            org.apache.camel.builder.endpoint.dsl.KMS2EndpointBuilderFactory.KMS2Builders,
             org.apache.camel.builder.endpoint.dsl.KMSEndpointBuilderFactory.KMSBuilders,
             org.apache.camel.builder.endpoint.dsl.KafkaEndpointBuilderFactory.KafkaBuilders,
             org.apache.camel.builder.endpoint.dsl.KeystoneEndpointBuilderFactory.KeystoneBuilders,
diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
index df9ab77..9217c4c 100644
--- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
+++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
@@ -183,6 +183,7 @@ public interface EndpointBuilders
             org.apache.camel.builder.endpoint.dsl.JsltEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.JsonValidatorEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.Jt400EndpointBuilderFactory,
+            org.apache.camel.builder.endpoint.dsl.KMS2EndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.KMSEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.KafkaEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.KeystoneEndpointBuilderFactory,
diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/KMS2EndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/KMS2EndpointBuilderFactory.java
new file mode 100644
index 0000000..de314d8
--- /dev/null
+++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/KMS2EndpointBuilderFactory.java
@@ -0,0 +1,353 @@
+/*
+ * 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.builder.endpoint.dsl;
+
+import javax.annotation.Generated;
+import org.apache.camel.builder.EndpointConsumerBuilder;
+import org.apache.camel.builder.EndpointProducerBuilder;
+import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
+
+/**
+ * The aws-kms is used for managing Amazon KMS
+ * 
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
+public interface KMS2EndpointBuilderFactory {
+
+
+    /**
+     * Builder for endpoint for the AWS 2 KMS component.
+     */
+    public interface KMS2EndpointBuilder extends EndpointProducerBuilder {
+        default AdvancedKMS2EndpointBuilder advanced() {
+            return (AdvancedKMS2EndpointBuilder) this;
+        }
+        /**
+         * Amazon AWS Access Key.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder accessKey(String accessKey) {
+            doSetProperty("accessKey", accessKey);
+            return this;
+        }
+        /**
+         * To use a existing configured AWS KMS as client.
+         * 
+         * The option is a:
+         * <code>software.amazon.awssdk.services.kms.KmsClient</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder kmsClient(Object kmsClient) {
+            doSetProperty("kmsClient", kmsClient);
+            return this;
+        }
+        /**
+         * To use a existing configured AWS KMS as client.
+         * 
+         * The option will be converted to a
+         * <code>software.amazon.awssdk.services.kms.KmsClient</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder kmsClient(String kmsClient) {
+            doSetProperty("kmsClient", kmsClient);
+            return this;
+        }
+        /**
+         * Whether the producer should be started lazy (on the first message).
+         * By starting lazy you can use this to allow CamelContext and routes to
+         * startup in situations where a producer may otherwise fail during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer
+         */
+        default KMS2EndpointBuilder lazyStartProducer(boolean lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+        /**
+         * Whether the producer should be started lazy (on the first message).
+         * By starting lazy you can use this to allow CamelContext and routes to
+         * startup in situations where a producer may otherwise fail during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer
+         */
+        default KMS2EndpointBuilder lazyStartProducer(String lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+        /**
+         * The operation to perform.
+         * 
+         * The option is a:
+         * <code>org.apache.camel.component.aws2.kms.KMS2Operations</code> type.
+         * 
+         * Required: true
+         * Group: producer
+         */
+        default KMS2EndpointBuilder operation(KMS2Operations operation) {
+            doSetProperty("operation", operation);
+            return this;
+        }
+        /**
+         * The operation to perform.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.component.aws2.kms.KMS2Operations</code> type.
+         * 
+         * Required: true
+         * Group: producer
+         */
+        default KMS2EndpointBuilder operation(String operation) {
+            doSetProperty("operation", operation);
+            return this;
+        }
+        /**
+         * To define a proxy host when instantiating the KMS client.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder proxyHost(String proxyHost) {
+            doSetProperty("proxyHost", proxyHost);
+            return this;
+        }
+        /**
+         * To define a proxy port when instantiating the KMS client.
+         * 
+         * The option is a: <code>java.lang.Integer</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder proxyPort(Integer proxyPort) {
+            doSetProperty("proxyPort", proxyPort);
+            return this;
+        }
+        /**
+         * To define a proxy port when instantiating the KMS client.
+         * 
+         * The option will be converted to a <code>java.lang.Integer</code>
+         * type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder proxyPort(String proxyPort) {
+            doSetProperty("proxyPort", proxyPort);
+            return this;
+        }
+        /**
+         * To define a proxy protocol when instantiating the KMS client.
+         * 
+         * The option is a: <code>software.amazon.awssdk.core.Protocol</code>
+         * type.
+         * 
+         * Default: HTTPS
+         * Group: producer
+         */
+        default KMS2EndpointBuilder proxyProtocol(Protocol proxyProtocol) {
+            doSetProperty("proxyProtocol", proxyProtocol);
+            return this;
+        }
+        /**
+         * To define a proxy protocol when instantiating the KMS client.
+         * 
+         * The option will be converted to a
+         * <code>software.amazon.awssdk.core.Protocol</code> type.
+         * 
+         * Default: HTTPS
+         * Group: producer
+         */
+        default KMS2EndpointBuilder proxyProtocol(String proxyProtocol) {
+            doSetProperty("proxyProtocol", proxyProtocol);
+            return this;
+        }
+        /**
+         * The region in which KMS client needs to work. When using this
+         * parameter, the configuration will expect the capitalized name of the
+         * region (for example AP_EAST_1) You'll need to use the name
+         * Regions.EU_WEST_1.name().
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder region(String region) {
+            doSetProperty("region", region);
+            return this;
+        }
+        /**
+         * Amazon AWS Secret Key.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: producer
+         */
+        default KMS2EndpointBuilder secretKey(String secretKey) {
+            doSetProperty("secretKey", secretKey);
+            return this;
+        }
+    }
+
+    /**
+     * Advanced builder for endpoint for the AWS 2 KMS component.
+     */
+    public interface AdvancedKMS2EndpointBuilder
+            extends
+                EndpointProducerBuilder {
+        default KMS2EndpointBuilder basic() {
+            return (KMS2EndpointBuilder) this;
+        }
+        /**
+         * Whether the endpoint should use basic property binding (Camel 2.x) or
+         * the newer property binding with additional capabilities.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         */
+        default AdvancedKMS2EndpointBuilder basicPropertyBinding(
+                boolean basicPropertyBinding) {
+            doSetProperty("basicPropertyBinding", basicPropertyBinding);
+            return this;
+        }
+        /**
+         * Whether the endpoint should use basic property binding (Camel 2.x) or
+         * the newer property binding with additional capabilities.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         */
+        default AdvancedKMS2EndpointBuilder basicPropertyBinding(
+                String basicPropertyBinding) {
+            doSetProperty("basicPropertyBinding", basicPropertyBinding);
+            return this;
+        }
+        /**
+         * Sets whether synchronous processing should be strictly used, or Camel
+         * is allowed to use asynchronous processing (if supported).
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         */
+        default AdvancedKMS2EndpointBuilder synchronous(boolean synchronous) {
+            doSetProperty("synchronous", synchronous);
+            return this;
+        }
+        /**
+         * Sets whether synchronous processing should be strictly used, or Camel
+         * is allowed to use asynchronous processing (if supported).
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         */
+        default AdvancedKMS2EndpointBuilder synchronous(String synchronous) {
+            doSetProperty("synchronous", synchronous);
+            return this;
+        }
+    }
+
+    /**
+     * Proxy enum for
+     * <code>org.apache.camel.component.aws2.kms.KMS2Operations</code> enum.
+     */
+    enum KMS2Operations {
+        listKeys,
+        createKey,
+        disableKey,
+        scheduleKeyDeletion,
+        describeKey,
+        enableKey;
+    }
+
+    /**
+     * Proxy enum for <code>software.amazon.awssdk.core.Protocol</code> enum.
+     */
+    enum Protocol {
+        http,
+        https;
+    }
+
+    public interface KMS2Builders {
+        /**
+         * AWS 2 KMS (camel-aws2-kms)
+         * The aws-kms is used for managing Amazon KMS
+         * 
+         * Category: cloud,management
+         * Since: 3.1
+         * Maven coordinates: org.apache.camel:camel-aws2-kms
+         * 
+         * Syntax: <code>aws2-kms:label</code>
+         * 
+         * Path parameter: label (required)
+         * Logical name
+         */
+        default KMS2EndpointBuilder aws2Kms(String path) {
+            return KMS2EndpointBuilderFactory.aws2Kms(path);
+        }
+    }
+    /**
+     * AWS 2 KMS (camel-aws2-kms)
+     * The aws-kms is used for managing Amazon KMS
+     * 
+     * Category: cloud,management
+     * Since: 3.1
+     * Maven coordinates: org.apache.camel:camel-aws2-kms
+     * 
+     * Syntax: <code>aws2-kms:label</code>
+     * 
+     * Path parameter: label (required)
+     * Logical name
+     */
+    static KMS2EndpointBuilder aws2Kms(String path) {
+        class KMS2EndpointBuilderImpl extends AbstractEndpointBuilder implements KMS2EndpointBuilder, AdvancedKMS2EndpointBuilder {
+            public KMS2EndpointBuilderImpl(String path) {
+                super("aws2-kms", path);
+            }
+        }
+        return new KMS2EndpointBuilderImpl(path);
+    }
+}
\ No newline at end of file