Skip to content

Commit

Permalink
Add missing HTTP client dependency to azure-key-vault extension
Browse files Browse the repository at this point in the history
Fixes #6157
  • Loading branch information
jamesnetherton committed Jun 6, 2024
1 parent 6dad426 commit c2a088f
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 33 deletions.
4 changes: 4 additions & 0 deletions extensions-jvm/azure-key-vault/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-support-azure-core-http-client-vertx-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-azure-key-vault</artifactId>
Expand Down
16 changes: 4 additions & 12 deletions extensions-jvm/azure-key-vault/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,12 @@
<artifactId>camel-quarkus-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-azure-key-vault</artifactId>
<exclusions>
<exclusion>
<artifactId>reactor-core</artifactId>
<groupId>io.projectreactor</groupId>
</exclusion>
</exclusions>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-support-azure-core-http-client-vertx</artifactId>
</dependency>

<!-- has to be impoprted as the version from the azure-core to avoid conflicts -->
<dependency>
<artifactId>reactor-core</artifactId>
<groupId>io.projectreactor</groupId>
<groupId>org.apache.camel</groupId>
<artifactId>camel-azure-key-vault</artifactId>
</dependency>
</dependencies>

Expand Down
22 changes: 22 additions & 0 deletions integration-tests-jvm/azure-key-vault/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-azure-key-vault</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-direct</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
Expand All @@ -70,6 +74,11 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-tests-support-azure</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
Expand All @@ -95,6 +104,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-direct-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</profile>
</profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,64 @@
*/
package org.apache.camel.quarkus.component.azure.key.vault.it;

import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.camel.CamelContext;
import org.jboss.logging.Logger;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.azure.key.vault.KeyVaultConstants;

@Path("/azure-key-vault")
@ApplicationScoped
public class AzureKeyVaultResource {

private static final Logger LOG = Logger.getLogger(AzureKeyVaultResource.class);

private static final String COMPONENT_AZURE_KEY_VAULT = "azure-key-vault";
@Inject
CamelContext context;
ProducerTemplate producerTemplate;

@Path("/secret/{secretName}")
@POST
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public Response createSecret(@PathParam("secretName") String secretName, String secret) {
KeyVaultSecret result = producerTemplate.requestBodyAndHeader("direct:createSecret", secret,
KeyVaultConstants.SECRET_NAME, secretName, KeyVaultSecret.class);
return Response.ok(result.getName()).build();
}

@Path("/load/component/azure-key-vault")
@Path("/secret/{secretName}")
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response loadComponentAzureKeyVault() throws Exception {
/* This is an autogenerated test */
if (context.getComponent(COMPONENT_AZURE_KEY_VAULT) != null) {
return Response.ok().build();
}
LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_AZURE_KEY_VAULT);
return Response.status(500, COMPONENT_AZURE_KEY_VAULT + " could not be loaded from the Camel context").build();
public String getSecret(@PathParam("secretName") String secretName) {
return producerTemplate.requestBodyAndHeader("direct:getSecret", null,
KeyVaultConstants.SECRET_NAME, secretName, String.class);
}

@Path("/secret/{secretName}")
@DELETE
public Response deleteSecret(@PathParam("secretName") String secretName) {
producerTemplate.requestBodyAndHeader("direct:deleteSecret", null,
KeyVaultConstants.SECRET_NAME, secretName, Void.class);
return Response.ok().build();
}

@Path("/secret/{secretName}/purge")
@DELETE
public Response purgeSecret(@PathParam("secretName") String secretName) {
producerTemplate.requestBodyAndHeader("direct:purgeDeletedSecret", null,
KeyVaultConstants.SECRET_NAME, secretName, Void.class);
return Response.ok().build();
}

@Path("/secret/from/placeholder")
@GET
public String getSecretFromPropertyPlaceholder() {
return producerTemplate.requestBody("direct:propertyPlaceholder", null, String.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.quarkus.component.azure.key.vault.it;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spi.PropertiesComponent;

public class AzureKeyVaultRoutes extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:createSecret")
.to(azureKeyVault("createSecret"));

from("direct:getSecret")
.to(azureKeyVault("getSecret"));

from("direct:deleteSecret")
.to(azureKeyVault("deleteSecret"));

from("direct:purgeDeletedSecret")
.to(azureKeyVault("purgeDeletedSecret"));

from("direct:propertyPlaceholder")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Message message = exchange.getMessage();
PropertiesComponent component = exchange.getContext().getPropertiesComponent();
component.resolveProperty("azure:camel-quarkus-secret").ifPresent(message::setBody);
}
});
}

private String azureKeyVault(String operation) {
return "azure-key-vault://{{camel.vault.azure.vaultName}}" +
"?clientId=RAW({{camel.vault.azure.clientId}})" +
"&clientSecret=RAW({{camel.vault.azure.clientSecret}})" +
"&tenantId=RAW({{camel.vault.azure.tenantId}})" +
"&operation=" + operation;
}
}
Original file line number Diff line number Diff line change
@@ -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.
## ---------------------------------------------------------------------------
#
camel.vault.azure.tenantId = ${AZURE_TENANT_ID}
camel.vault.azure.clientId = ${AZURE_CLIENT_ID}
camel.vault.azure.clientSecret = ${AZURE_CLIENT_SECRET}
camel.vault.azure.vaultName = ${AZURE_VAULT_NAME:cq-vault-testing}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,101 @@
*/
package org.apache.camel.quarkus.component.azure.key.vault.it;

import java.util.UUID;

import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;

import static org.hamcrest.Matchers.is;

// Azure Key Vault is not supported by Azurite https://github.com/Azure/Azurite/issues/619
@EnabledIfEnvironmentVariable(named = "AZURE_TENANT_ID", matches = ".+")
@EnabledIfEnvironmentVariable(named = "AZURE_CLIENT_ID", matches = ".+")
@EnabledIfEnvironmentVariable(named = "AZURE_CLIENT_SECRET", matches = ".+")
@EnabledIfEnvironmentVariable(named = "AZURE_VAULT_NAME", matches = ".+")
@QuarkusTest
class AzureKeyVaultTest {

@Test
public void loadComponentAzureKeyVault() {
/* A simple autogenerated test */
RestAssured.get("/azure-key-vault/load/component/azure-key-vault")
.then()
.statusCode(200);
void secretCreateRetrieveDeletePurge() {
String secretName = UUID.randomUUID().toString();
String secret = "Hello Camel Quarkus Azure Key Vault";

try {
// Create secret
RestAssured.given()
.body(secret)
.post("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(200)
.body(is(secretName));

// Retrieve secret
RestAssured.given()
.get("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(200)
.body(is(secret));
} finally {
// Delete secret
RestAssured.given()
.delete("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(200);

// Purge secret
RestAssured.given()
.delete("/azure-key-vault/secret/{secretName}/purge", secretName)
.then()
.statusCode(200);

// Confirm deletion
RestAssured.given()
.get("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(500);
}
}

@Test
void propertyPlaceholder() {
String secretName = "camel-quarkus-secret";
String secret = "Hello Camel Quarkus Azure Key Vault From Property Placeholder";

try {
// Create secret
RestAssured.given()
.body(secret)
.post("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(200)
.body(is(secretName));

// Retrieve secret
RestAssured.given()
.get("/azure-key-vault/secret/from/placeholder")
.then()
.statusCode(200)
.body(is(secret));
} finally {
// Delete secret
RestAssured.given()
.delete("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(200);

// Purge secret
RestAssured.given()
.delete("/azure-key-vault/secret/{secretName}/purge", secretName)
.then()
.statusCode(200);

// Confirm deletion
RestAssured.given()
.get("/azure-key-vault/secret/{secretName}", secretName)
.then()
.statusCode(500);
}
}
}

0 comments on commit c2a088f

Please sign in to comment.