This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit e9a8a5729ac5a43d12d53702c486625222814275 Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Wed Jun 8 13:58:35 2022 +0200 CAMEL-17689 - Create a Camel Hashicorp Vault Component --- catalog/camel-allcomponents/pom.xml | 4 + components/camel-hashicorp-vault/pom.xml | 84 +++++++++ .../vault/HashicorpVaultComponentConfigurer.java | 55 ++++++ .../vault/HashicorpVaultEndpointConfigurer.java | 81 ++++++++ .../vault/HashicorpVaultEndpointUriFactory.java | 78 ++++++++ .../services/org/apache/camel/component.properties | 7 + .../org/apache/camel/component/hashicorp-vault | 2 + .../camel/configurer/hashicorp-vault-component | 2 + .../camel/configurer/hashicorp-vault-endpoint | 2 + .../camel/urifactory/hashicorp-vault-endpoint | 2 + .../component/hashicorp/vault/hashicorp-vault.json | 42 +++++ .../src/main/docs/azure-key-vault-component.adoc | 203 +++++++++++++++++++++ .../hashicorp/vault/HashicorpVaultComponent.java | 71 +++++++ .../vault/HashicorpVaultConfiguration.java | 146 +++++++++++++++ .../hashicorp/vault/HashicorpVaultConstants.java | 31 ++++ .../hashicorp/vault/HashicorpVaultEndpoint.java | 103 +++++++++++ .../hashicorp/vault/HashicorpVaultOperation.java | 21 +++ .../hashicorp/vault/HashicorpVaultProducer.java | 84 +++++++++ .../HashicorpProducerCreateSecretIT.java | 47 +++++ .../HashicorpProducerCreateSecretPOJOIT.java | 63 +++++++ .../src/test/resources/log4j2.properties | 27 +++ parent/pom.xml | 5 + 22 files changed, 1160 insertions(+) diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index 30c313535d3..4d4952915e5 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -593,6 +593,10 @@ <groupId>org.apache.camel</groupId> <artifactId>camel-guava-eventbus</artifactId> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-hashicorp-vault</artifactId> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-hazelcast</artifactId> diff --git a/components/camel-hashicorp-vault/pom.xml b/components/camel-hashicorp-vault/pom.xml new file mode 100644 index 00000000000..c26f6c23248 --- /dev/null +++ b/components/camel-hashicorp-vault/pom.xml @@ -0,0 +1,84 @@ +<?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.18.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-hashicorp-vault</artifactId> + <packaging>jar</packaging> + + <name>Camel :: Hashicorp :: Key Vault</name> + <description>Camel Azure Hashicorp Component</description> + + <properties> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-support</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.vault</groupId> + <artifactId>spring-vault-core</artifactId> + <version>2.3.2</version> + </dependency> + + <!-- extras --> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + + <!-- for testing --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-junit5</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-junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.awaitility</groupId> + <artifactId>awaitility</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>${commons-lang3-version}</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponentConfigurer.java b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponentConfigurer.java new file mode 100644 index 00000000000..3438dbdac6b --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponentConfigurer.java @@ -0,0 +1,55 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.component.hashicorp.vault; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.support.component.PropertyConfigurerSupport; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class HashicorpVaultComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + HashicorpVaultComponent target = (HashicorpVaultComponent) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "autowiredenabled": + case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true; + case "lazystartproducer": + case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; + default: return false; + } + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "autowiredenabled": + case "autowiredEnabled": return boolean.class; + case "lazystartproducer": + case "lazyStartProducer": return boolean.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + HashicorpVaultComponent target = (HashicorpVaultComponent) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "autowiredenabled": + case "autowiredEnabled": return target.isAutowiredEnabled(); + case "lazystartproducer": + case "lazyStartProducer": return target.isLazyStartProducer(); + default: return null; + } + } +} + diff --git a/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointConfigurer.java b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointConfigurer.java new file mode 100644 index 00000000000..b16d1df8ddf --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointConfigurer.java @@ -0,0 +1,81 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.component.hashicorp.vault; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.support.component.PropertyConfigurerSupport; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class HashicorpVaultEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + HashicorpVaultEndpoint target = (HashicorpVaultEndpoint) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "host": target.getConfiguration().setHost(property(camelContext, java.lang.String.class, value)); return true; + case "lazystartproducer": + case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; + case "operation": target.getConfiguration().setOperation(property(camelContext, org.apache.camel.component.hashicorp.vault.HashicorpVaultOperation.class, value)); return true; + case "port": target.getConfiguration().setPort(property(camelContext, java.lang.String.class, value)); return true; + case "scheme": target.getConfiguration().setScheme(property(camelContext, java.lang.String.class, value)); return true; + case "secretpath": + case "secretPath": target.getConfiguration().setSecretPath(property(camelContext, java.lang.String.class, value)); return true; + case "token": target.getConfiguration().setToken(property(camelContext, java.lang.String.class, value)); return true; + case "vaulttemplate": + case "vaultTemplate": target.getConfiguration().setVaultTemplate(property(camelContext, org.springframework.vault.core.VaultTemplate.class, value)); return true; + default: return false; + } + } + + @Override + public String[] getAutowiredNames() { + return new String[]{"vaultTemplate"}; + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "host": return java.lang.String.class; + case "lazystartproducer": + case "lazyStartProducer": return boolean.class; + case "operation": return org.apache.camel.component.hashicorp.vault.HashicorpVaultOperation.class; + case "port": return java.lang.String.class; + case "scheme": return java.lang.String.class; + case "secretpath": + case "secretPath": return java.lang.String.class; + case "token": return java.lang.String.class; + case "vaulttemplate": + case "vaultTemplate": return org.springframework.vault.core.VaultTemplate.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + HashicorpVaultEndpoint target = (HashicorpVaultEndpoint) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "host": return target.getConfiguration().getHost(); + case "lazystartproducer": + case "lazyStartProducer": return target.isLazyStartProducer(); + case "operation": return target.getConfiguration().getOperation(); + case "port": return target.getConfiguration().getPort(); + case "scheme": return target.getConfiguration().getScheme(); + case "secretpath": + case "secretPath": return target.getConfiguration().getSecretPath(); + case "token": return target.getConfiguration().getToken(); + case "vaulttemplate": + case "vaultTemplate": return target.getConfiguration().getVaultTemplate(); + default: return null; + } + } +} + diff --git a/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointUriFactory.java b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointUriFactory.java new file mode 100644 index 00000000000..6832e3b9b8a --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpointUriFactory.java @@ -0,0 +1,78 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.component.hashicorp.vault; + +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.camel.spi.EndpointUriFactory; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +public class HashicorpVaultEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory { + + private static final String BASE = ":vaultName"; + + private static final Set<String> PROPERTY_NAMES; + private static final Set<String> SECRET_PROPERTY_NAMES; + private static final Set<String> MULTI_VALUE_PREFIXES; + static { + Set<String> props = new HashSet<>(9); + props.add("host"); + props.add("lazyStartProducer"); + props.add("operation"); + props.add("port"); + props.add("scheme"); + props.add("secretPath"); + props.add("secretsEngine"); + props.add("token"); + props.add("vaultTemplate"); + PROPERTY_NAMES = Collections.unmodifiableSet(props); + Set<String> secretProps = new HashSet<>(1); + secretProps.add("token"); + SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps); + MULTI_VALUE_PREFIXES = Collections.emptySet(); + } + + @Override + public boolean isEnabled(String scheme) { + return "hashicorp-vault".equals(scheme); + } + + @Override + public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException { + String syntax = scheme + BASE; + String uri = syntax; + + Map<String, Object> copy = new HashMap<>(properties); + + uri = buildPathParameter(syntax, uri, "secretsEngine", null, false, copy); + uri = buildQueryParameters(uri, copy, encode); + return uri; + } + + @Override + public Set<String> propertyNames() { + return PROPERTY_NAMES; + } + + @Override + public Set<String> secretPropertyNames() { + return SECRET_PROPERTY_NAMES; + } + + @Override + public Set<String> multiValuePrefixes() { + return MULTI_VALUE_PREFIXES; + } + + @Override + public boolean isLenientProperties() { + return false; + } +} + diff --git a/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component.properties new file mode 100644 index 00000000000..426a6aadccd --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +components=hashicorp-vault +groupId=org.apache.camel +artifactId=camel-hashicorp-vault +version=3.18.0-SNAPSHOT +projectName=Camel :: Hashicorp :: Key Vault +projectDescription=Camel Azure Hashicorp Component diff --git a/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component/hashicorp-vault b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component/hashicorp-vault new file mode 100644 index 00000000000..a137188931d --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/component/hashicorp-vault @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.hashicorp.vault.HashicorpVaultComponent diff --git a/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-component b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-component new file mode 100644 index 00000000000..c0252147c60 --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-component @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.hashicorp.vault.HashicorpVaultComponentConfigurer diff --git a/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-endpoint b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-endpoint new file mode 100644 index 00000000000..7f8e80d30e5 --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/configurer/hashicorp-vault-endpoint @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.hashicorp.vault.HashicorpVaultEndpointConfigurer diff --git a/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/urifactory/hashicorp-vault-endpoint b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/urifactory/hashicorp-vault-endpoint new file mode 100644 index 00000000000..07bf21e8e12 --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/META-INF/services/org/apache/camel/urifactory/hashicorp-vault-endpoint @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.hashicorp.vault.HashicorpVaultEndpointUriFactory diff --git a/components/camel-hashicorp-vault/src/generated/resources/org/apache/camel/component/hashicorp/vault/hashicorp-vault.json b/components/camel-hashicorp-vault/src/generated/resources/org/apache/camel/component/hashicorp/vault/hashicorp-vault.json new file mode 100644 index 00000000000..036ce798670 --- /dev/null +++ b/components/camel-hashicorp-vault/src/generated/resources/org/apache/camel/component/hashicorp/vault/hashicorp-vault.json @@ -0,0 +1,42 @@ +{ + "component": { + "kind": "component", + "name": "hashicorp-vault", + "title": "Hashicorp Vault", + "description": "Manage secrets in Hashicorp Vault Service", + "deprecated": false, + "firstVersion": "3.18.0", + "label": "cloud,cloud", + "javaType": "org.apache.camel.component.hashicorp.vault.HashicorpVaultComponent", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-hashicorp-vault", + "version": "3.18.0-SNAPSHOT", + "scheme": "hashicorp-vault", + "extendsScheme": "", + "syntax": "hashicorp-vault:vaultName", + "async": false, + "api": false, + "consumerOnly": false, + "producerOnly": true, + "lenientProperties": false + }, + "componentProperties": { + "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "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 star [...] + "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...] + }, + "headers": { + "CamelHashicorpVaultProducerOperation": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.apache.camel.component.azure.key.vault.KeyVaultOperationDefinition", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Overrides the desired operation to be used in the producer.", "constantName": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConstants#OPERATION" } + }, + "properties": { + "secretsEngine": { "kind": "path", "displayName": "Secrets Engine", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Vault Name to be used" }, + "host": { "kind": "parameter", "displayName": "Host", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Hashicorp Vault instance host to be used" }, + "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "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 sta [...] + "operation": { "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.hashicorp.vault.HashicorpVaultOperation", "enum": [ "createSecret" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Operation to be performed" }, + "port": { "kind": "parameter", "displayName": "Port", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "8200", "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Hashicorp Vault instance port to be used" }, + "scheme": { "kind": "parameter", "displayName": "Scheme", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "https", "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Hashicorp Vault instance scheme to be used" }, + "secretPath": { "kind": "parameter", "displayName": "Secret Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Hashicorp Vault instance secret Path to be used" }, + "vaultTemplate": { "kind": "parameter", "displayName": "Vault Template", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.springframework.vault.core.VaultTemplate", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Instance of Vault template" }, + "token": { "kind": "parameter", "displayName": "Token", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.hashicorp.vault.HashicorpVaultConfiguration", "configurationField": "configuration", "description": "Token to be used" } + } +} diff --git a/components/camel-hashicorp-vault/src/main/docs/azure-key-vault-component.adoc b/components/camel-hashicorp-vault/src/main/docs/azure-key-vault-component.adoc new file mode 100644 index 00000000000..014141813ff --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/docs/azure-key-vault-component.adoc @@ -0,0 +1,203 @@ += Azure Key Vault Component +:doctitle: Azure Key Vault +:shortname: azure-key-vault +:artifactid: camel-azure-key-vault +:description: Manage secrets and keys in Azure Key Vault Service +:since: 3.17 +:supportlevel: Preview +:component-header: Only producer is supported +//Manually maintained attributes +:group: Azure +:camel-spring-boot-name: azure-key-vault + +*Since Camel {since}* + +*{component-header}* + +The azure-key-vault component that integrates https://azure.microsoft.com/en-us/services/key-vault/[Azure ServiceBus]. + +Prerequisites + +You must have a valid Windows Azure Key Vault account. More information is available at +https://docs.microsoft.com/azure/[Azure Documentation Portal]. + +== URI Format + +[source,xml] +------------------------------------------------------------ +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-azure-key-vault</artifactId> + <version>x.x.x</version> + <!-- use the same version as your Camel core version --> +</dependency> +------------------------------------------------------------ + + +// component-configure options: START + +// component-configure options: END + +// component options: START +include::partial$component-configure-options.adoc[] +include::partial$component-endpoint-options.adoc[] +// component options: END + +// endpoint options: START + +// endpoint options: END + + +== Usage + +=== Using Azure Key Vault Property Function + +To use this function you'll need to provide credentials to Azure Key Vault Service as environment variables: + +[source,bash] +---- +export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId +export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId +export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret +export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName +---- + +You can also configure the credentials in the `application.properties` file such as: + +[source,properties] +---- +camel.vault.azure.tenantId = accessKey +camel.vault.azure.clientId = clientId +camel.vault.azure.clientSecret = clientSecret +camel.vault.azure.vaultName = vaultName +---- + +At this point you'll be able to reference a property in the following way: + +[source,xml] +---- +<camelContext> + <route> + <from uri="direct:start"/> + <to uri="{{azure:route}}"/> + </route> +</camelContext> +---- + +Where route will be the name of the secret stored in the Azure Key Vault Service. + +You could specify a default value in case the secret is not present on Azure Key Vault Service: + +[source,xml] +---- +<camelContext> + <route> + <from uri="direct:start"/> + <to uri="{{azure:route:default}}"/> + </route> +</camelContext> +---- + +In this case if the secret doesn't exist, the property will fallback to "default" as value. + +Also you are able to get particular field of the secret, if you have for example a secret named database of this form: + +[source,bash] +---- +{ + "username": "admin", + "password": "password123", + "engine": "postgres", + "host": "127.0.0.1", + "port": "3128", + "dbname": "db" +} +---- + +You're able to do get single secret value in your route, like for example: + +[source,xml] +---- +<camelContext> + <route> + <from uri="direct:start"/> + <log message="Username is {{azure:database/username}}"/> + </route> +</camelContext> +---- + +Or re-use the property as part of an endpoint. + +You could specify a default value in case the particular field of secret is not present on Azure Key Vault: + +[source,xml] +---- +<camelContext> + <route> + <from uri="direct:start"/> + <log message="Username is {{azure:database/username:admin}}"/> + </route> +</camelContext> +---- + +In this case if the secret doesn't exist or the secret exists, but the username field is not part of the secret, the property will fallback to "admin" as value. + +For the moment we are not considering the rotation function, if any will be applied, but it is in the work to be done. + +The only requirement is adding the camel-azure-key-vault jar to your Camel application. + +// component headers: START +include::partial$component-endpoint-headers.adoc[] +// component headers: END + +=== Azure Key Vault Producer operations + +Azure Key Vault component provides the following operation on the producer side: + +- createSecret +- getSecret +- deleteSecret +- purgeDeletedSecret + +== Examples + +=== Producer Examples + +- createSecret: this operation will create a secret in Azure Key Vault + +[source,java] +-------------------------------------------------------------------------------- +from("direct:createSecret") + .setHeader(KeyVaultConstants.SECRET_NAME, "Test") + .setBody(constant("Test")) + .to("azure-key-vault://test123?clientId=RAW({{clientId}})&clientSecret=RAW({{clientSecret}})&tenantId=RAW({{tenantId}})") +-------------------------------------------------------------------------------- + +- getSecret: this operation will get a secret from Azure Key Vault + +[source,java] +-------------------------------------------------------------------------------- +from("direct:getSecret") + .setHeader(KeyVaultConstants.SECRET_NAME, "Test") + .to("azure-key-vault://test123?clientId=RAW({{clientId}})&clientSecret=RAW({{clientSecret}})&tenantId=RAW({{tenantId}})&operation=getSecret") +-------------------------------------------------------------------------------- + +- deleteSecret: this operation will delete a Secret from Azure Key Vault + +[source,java] +-------------------------------------------------------------------------------- +from("direct:deleteSecret") + .setHeader(KeyVaultConstants.SECRET_NAME, "Test") + .to("azure-key-vault://test123?clientId=RAW({{clientId}})&clientSecret=RAW({{clientSecret}})&tenantId=RAW({{tenantId}})&operation=deleteSecret") +-------------------------------------------------------------------------------- + +- purgeDeletedSecret: this operation will purge a deleted Secret from Azure Key Vault + +[source,java] +-------------------------------------------------------------------------------- +from("direct:purgeDeletedSecret") + .setHeader(KeyVaultConstants.SECRET_NAME, "Test") + .to("azure-key-vault://test123?clientId=RAW({{clientId}})&clientSecret=RAW({{clientSecret}})&tenantId=RAW({{tenantId}})&operation=purgeDeletedSecret") +-------------------------------------------------------------------------------- + +include::spring-boot:partial$starter.adoc[] diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponent.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponent.java new file mode 100644 index 00000000000..0ecc217e991 --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultComponent.java @@ -0,0 +1,71 @@ +/* + * 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.hashicorp.vault; + +import java.util.Map; + +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 org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Hashicorp Vault component + */ +@Component("hashicorp-vault") +public class HashicorpVaultComponent extends DefaultComponent { + + private static final Logger LOG = LoggerFactory.getLogger(HashicorpVaultComponent.class); + + @Metadata + private HashicorpVaultConfiguration configuration = new HashicorpVaultConfiguration(); + + public HashicorpVaultComponent() { + } + + public HashicorpVaultComponent(final CamelContext context) { + super(context); + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + + if (remaining == null || remaining.trim().length() == 0) { + throw new IllegalArgumentException("A vault name must be specified."); + } + + final HashicorpVaultConfiguration epConfiguration + = this.configuration != null ? this.configuration.copy() : new HashicorpVaultConfiguration(); + + // set account or topic name + epConfiguration.setSecretsEngine(remaining); + + final HashicorpVaultEndpoint endpoint = new HashicorpVaultEndpoint(uri, this, epConfiguration); + setProperties(endpoint, parameters); + + if (epConfiguration.getVaultTemplate() == null + && epConfiguration.getToken() == null) { + throw new IllegalArgumentException( + "Vault Template or token must be specified"); + } + + return endpoint; + } +} diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConfiguration.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConfiguration.java new file mode 100644 index 00000000000..404de9c309c --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConfiguration.java @@ -0,0 +1,146 @@ +/* + * 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.hashicorp.vault; + +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 org.springframework.vault.core.VaultTemplate; + +@UriParams +public class HashicorpVaultConfiguration implements Cloneable { + + @UriPath + private String secretsEngine; + @UriParam + @Metadata(autowired = true) + private VaultTemplate vaultTemplate; + @UriParam + private String host; + @UriParam(defaultValue = "8200") + private String port = "8200"; + @UriParam(defaultValue = "https") + private String scheme = "https"; + @UriParam + private String secretPath; + @UriParam(label = "security", secret = true) + private String token; + @UriParam(label = "producer") + private HashicorpVaultOperation operation = HashicorpVaultOperation.createSecret; + + /** + * Instance of Vault template + */ + public VaultTemplate getVaultTemplate() { + return vaultTemplate; + } + + public void setVaultTemplate(VaultTemplate vaultTemplate) { + this.vaultTemplate = vaultTemplate; + } + + /** + * Vault Name to be used + */ + public String getSecretsEngine() { + return secretsEngine; + } + + public void setSecretsEngine(String secretsEngine) { + this.secretsEngine = secretsEngine; + } + + /** + * Token to be used + */ + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + /** + * Hashicorp Vault instance host to be used + */ + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Hashicorp Vault instance port to be used + */ + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + /** + * Hashicorp Vault instance scheme to be used + */ + public String getScheme() { + return scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + /** + * Hashicorp Vault instance secret Path to be used + */ + public String getSecretPath() { + return secretPath; + } + + public void setSecretPath(String secretPath) { + this.secretPath = secretPath; + } + + /** + * Operation to be performed + */ + public HashicorpVaultOperation getOperation() { + return operation; + } + + public void setOperation(HashicorpVaultOperation operation) { + this.operation = operation; + } + + // ************************************************* + // + // ************************************************* + + public HashicorpVaultConfiguration copy() { + try { + return (HashicorpVaultConfiguration) super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeCamelException(e); + } + } +} diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConstants.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConstants.java new file mode 100644 index 00000000000..a6c7afc2e6b --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultConstants.java @@ -0,0 +1,31 @@ +/* + * 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.hashicorp.vault; + +import org.apache.camel.spi.Metadata; + +public final class HashicorpVaultConstants { + private static final String HEADER_PREFIX = "CamelHashicorpVault"; + + // headers set by the producer only + @Metadata(label = "producer", description = "Overrides the desired operation to be used in the producer.", + javaType = "org.apache.camel.component.azure.key.vault.KeyVaultOperationDefinition") + public static final String OPERATION = HEADER_PREFIX + "ProducerOperation"; + + private HashicorpVaultConstants() { + } +} diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpoint.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpoint.java new file mode 100644 index 00000000000..fcc186a0f30 --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultEndpoint.java @@ -0,0 +1,103 @@ +/* + * 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.hashicorp.vault; + +import org.apache.camel.Category; +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.DefaultEndpoint; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.core.VaultTemplate; + +/** + * Manage secrets in Hashicorp Vault Service + */ +@UriEndpoint(firstVersion = "3.18.0", scheme = "hashicorp-vault", title = "Hashicorp Vault", + syntax = "hashicorp-vault:vaultName", category = { + Category.CLOUD, Category.CLOUD }, + producerOnly = true, + headersClass = HashicorpVaultConstants.class) +public class HashicorpVaultEndpoint extends DefaultEndpoint { + + private VaultTemplate vaultTemplate; + + @UriParam + private HashicorpVaultConfiguration configuration; + + public HashicorpVaultEndpoint(final String uri, final Component component, final HashicorpVaultConfiguration configuration) { + super(uri, component); + this.configuration = configuration; + } + + @Override + public void doInit() throws Exception { + super.doInit(); + vaultTemplate = configuration.getVaultTemplate() != null + ? configuration.getVaultTemplate() : createVaultTemplate(); + } + + private VaultTemplate createVaultTemplate() { + VaultTemplate vaultTemplate; + + VaultEndpoint vaultEndpoint = new VaultEndpoint(); + vaultEndpoint.setHost(configuration.getHost()); + vaultEndpoint.setPort(Integer.parseInt(configuration.getPort())); + vaultEndpoint.setScheme(configuration.getScheme()); + + vaultTemplate = new VaultTemplate(vaultEndpoint, + new TokenAuthentication(configuration.getToken())); + + return vaultTemplate; + } + + @Override + public Producer createProducer() throws Exception { + return new HashicorpVaultProducer(this); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + throw new UnsupportedOperationException("Consumer not supported"); + } + + /** + * The component configurations + */ + public HashicorpVaultConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(HashicorpVaultConfiguration configuration) { + this.configuration = configuration; + } + + /** + * The vault template + */ + public VaultTemplate getVaultTemplate() { + return vaultTemplate; + } + + public void setVaultTemplate(VaultTemplate vaultTemplate) { + this.vaultTemplate = vaultTemplate; + } +} diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultOperation.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultOperation.java new file mode 100644 index 00000000000..70d314382e5 --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultOperation.java @@ -0,0 +1,21 @@ +/* + * 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.hashicorp.vault; + +public enum HashicorpVaultOperation { + createSecret +} diff --git a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultProducer.java b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultProducer.java new file mode 100644 index 00000000000..ca27872fc6c --- /dev/null +++ b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultProducer.java @@ -0,0 +1,84 @@ +/* + * 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.hashicorp.vault; + +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.InvalidPayloadException; +import org.apache.camel.Message; +import org.apache.camel.support.DefaultProducer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.vault.core.VaultKeyValueOperations; +import org.springframework.vault.core.VaultKeyValueOperationsSupport; + +public class HashicorpVaultProducer extends DefaultProducer { + + private static final Logger LOG = LoggerFactory.getLogger(HashicorpVaultProducer.class); + + public HashicorpVaultProducer(final Endpoint endpoint) { + super(endpoint); + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + } + + @Override + public void process(Exchange exchange) throws Exception { + HashicorpVaultOperation operation = determineOperation(exchange); + switch (operation) { + case createSecret: + createSecret(exchange); + break; + default: + throw new IllegalArgumentException("Unsupported operation"); + } + } + + private void createSecret(Exchange exchange) throws InvalidPayloadException { + VaultKeyValueOperations keyValue = getEndpoint().getVaultTemplate().opsForKeyValue(getEndpoint().getConfiguration().getSecretsEngine(), VaultKeyValueOperationsSupport.KeyValueBackend.versioned()); + keyValue.put(getEndpoint().getConfiguration().getSecretPath(), exchange.getMessage().getBody()); + } + + @Override + public HashicorpVaultEndpoint getEndpoint() { + return (HashicorpVaultEndpoint) super.getEndpoint(); + } + + public HashicorpVaultConfiguration getConfiguration() { + return getEndpoint().getConfiguration(); + } + + public static Message getMessageForResponse(final Exchange exchange) { + return exchange.getMessage(); + } + + private HashicorpVaultOperation determineOperation(Exchange exchange) { + HashicorpVaultOperation operation = exchange.getIn().getHeader(HashicorpVaultConstants.OPERATION, HashicorpVaultOperation.class); + if (operation == null) { + operation = getConfiguration().getOperation(); + } + return operation; + } +} diff --git a/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretIT.java b/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretIT.java new file mode 100644 index 00000000000..cfa5f9e6664 --- /dev/null +++ b/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretIT.java @@ -0,0 +1,47 @@ +package org.apache.camel.component.hashicorp.vault.integration.operations; + +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.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +@Disabled("Disabled until we'll have a Camel-Hashicorp-vault test-infra module") +public class HashicorpProducerCreateSecretIT extends CamelTestSupport { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + @Test + public void createSecretTest() { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createSecret", new Processor() { + @Override + public void process(Exchange exchange) { + HashMap map = new HashMap(); + map.put("integer", "30"); + exchange.getIn().setBody(map); + } + }); + + + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:createSecret") + .to("hashicorp-vault://secret?operation=createSecret&token=RAW(token)&host=localhost&scheme=http&secretPath=test") + .to("mock:result"); + } + }; + } +} diff --git a/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretPOJOIT.java b/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretPOJOIT.java new file mode 100644 index 00000000000..a6ed25304ef --- /dev/null +++ b/components/camel-hashicorp-vault/src/test/java/org/apache/camel/component/hashicorp/vault/integration/operations/HashicorpProducerCreateSecretPOJOIT.java @@ -0,0 +1,63 @@ +package org.apache.camel.component.hashicorp.vault.integration.operations; + +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.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.vault.support.VaultResponse; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@Disabled("Disabled until we'll have a Camel-Hashicorp-vault test-infra module") +public class HashicorpProducerCreateSecretPOJOIT extends CamelTestSupport { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + @Test + public void createSecretTest() { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createSecret", new Processor() { + @Override + public void process(Exchange exchange) { + Secrets sec = new Secrets(); + sec.username = "admin"; + sec.password = "password"; + exchange.getIn().setBody(sec); + } + }); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:createSecret") + .to("hashicorp-vault://secret?operation=createSecret&token=RAW(token)&host=localhost&scheme=http&secretPath=test") + .to("mock:result"); + } + }; + } + + class Secrets { + + String username; + String password; + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + } +} diff --git a/components/camel-hashicorp-vault/src/test/resources/log4j2.properties b/components/camel-hashicorp-vault/src/test/resources/log4j2.properties new file mode 100644 index 00000000000..b4aa74472e1 --- /dev/null +++ b/components/camel-hashicorp-vault/src/test/resources/log4j2.properties @@ -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. +## --------------------------------------------------------------------------- +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-hashicorp-vault-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/parent/pom.xml b/parent/pom.xml index 35fa4d4ff2e..54e2ee70b07 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1518,6 +1518,11 @@ <artifactId>camel-guava-eventbus</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-hashicorp-vault</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-hazelcast</artifactId>