Skip to content

Commit 4d74a7d

Browse files
JiriOndrusekjamesnetherton
authored andcommitted
fixes #6660: azure-key-vault refresh context coverage
1 parent 3012217 commit 4d74a7d

File tree

8 files changed

+336
-44
lines changed

8 files changed

+336
-44
lines changed

integration-test-groups/azure/README.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ or skipped, if the given service is not supported by Azurite.
88
Unsupported by Azurite:
99

1010
* `azure-eventhubs`
11+
* `azure-key-vault`
1112

1213
=== Real Azure API
1314

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
== Azure key vault isolated integration tests
2+
3+
=== Real Azure API
4+
5+
Prerequisites:
6+
7+
* A https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&tabs=azure-portal[general-purpose v2 Azure storage account] and
8+
https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal[create a container]
9+
* The https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-change-feed?tabs=azure-portal#enable-and-disable-the-change-feed[change feed] is enabled on your storage account
10+
* View the https://docs.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#view-account-access-keys[account keys] and set the following environment variables
11+
* An https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-create[Azure Event Hub]
12+
* An https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string[Event Hubs connection string]
13+
* A https://learn.microsoft.com/en-us/azure/key-vault/general/overview[Key Vault] configured in your Azure account
14+
15+
To add resources required for key-vault tests, you can use `key-vault-resources.sh` script as follows. Ensure that you have installed (and logged in) the https://docs.microsoft.com/en-us/cli/azure/[Azure CLI] beforehand.
16+
The script prerequisites are permissions, resource group and event hub namespace.
17+
If you need such resources created as well, please follow instructions from the parent module.
18+
19+
[source,shell]
20+
----
21+
$ ./key-vault-resources.sh create
22+
----
23+
24+
The script outputs a set of export commands that you may want to paste to your shell.
25+
26+
Here are the environment variables you need to set:
27+
28+
[source,shell]
29+
----
30+
export RESOURCE_GROUP=<existing-resource-group>
31+
export ZONE=<your-zone>
32+
export EH_NAMESPACE=<existing event hub namespace>
33+
export AZURE_STORAGE_ACCOUNT_NAME=<existing event hub storage account name>
34+
----
35+
36+
To clean up, run
37+
38+
[source,shell]
39+
----
40+
$ ./key-vault-resources.sh delete
41+
----
42+
43+
=== What is created by the script
44+
45+
* eventhub used for testing context reload
46+
* storage container required for storing position of eventhub consumer
47+
48+
Following properties are generated by the script and are required for the test execution:
49+
[source,shell]
50+
----
51+
export AZURE_EVENT_HUBS_BLOB_CONTAINER_NAME=<container for storing position of eventhub consumer>
52+
export AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING=<connection string for eventhub>
53+
export AZURE_STORAGE_ACCOUNT_KEY=<storage account key required for context refresh configuration>
54+
----
55+
56+
Following properties have to be set manually before test execution
57+
58+
[source,shell]
59+
----
60+
export AZURE_CLIENT_ID=<your-azure-app-client-id>
61+
export AZURE_CLIENT_SECRET=<your-azure-app-client-secret>
62+
export AZURE_TENANT_ID=<your-azure-app-tenant-id>
63+
export AZURE_VAULT_NAME=<your-azure-key-vault-name>
64+
----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one or more
4+
# contributor license agreements. See the NOTICE file distributed with
5+
# this work for additional information regarding copyright ownership.
6+
# The ASF licenses this file to You under the Apache License, Version 2.0
7+
# (the "License"); you may not use this file except in compliance with
8+
# the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
#script to create/delete all resources required for key-vault refresh test.
20+
#In comparison with ../azure-resources/sh, the script is not creating any permissions, resource groups, ...
21+
#Following properties has to be se upon running the script
22+
#export RESOURCE_GROUP=<existing-resource-group>
23+
#export ZONE=<your-zone>
24+
#export EH_NAMESPACE=<existing event hub namespace>
25+
#export AZURE_STORAGE_ACCOUNT_NAME=<existing event hub storage account name>
26+
27+
if ! which az > /dev/null 2>&1; then
28+
echo "$(basename $0) requires the Azure CLI."
29+
echo
30+
echo "https://docs.microsoft.com/en-us/cli/azure/"
31+
echo
32+
exit 1
33+
fi
34+
35+
suffix="$(az ad signed-in-user show --query displayName -o tsv | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]' | cut -c-12)"
36+
suffix="${suffix}4"
37+
38+
export AZURE_VAULT_REFRESH_EH_NAME=camel-quarkus-secret-refresh-hub-${suffix}
39+
export AZURE_BLOB_CONTAINER_NAME=cq-container-${suffix}
40+
41+
function createResources() {
42+
set -e
43+
set -x
44+
AZURE_EVENT_HUBS_CONNECTION_STRING=$(az eventhubs namespace authorization-rule keys list --resource-group ${RESOURCE_GROUP} --namespace-name ${EH_NAMESPACE} --name RootManageSharedAccessKey --query primaryConnectionString -o tsv)
45+
46+
az storage container create --account-name ${AZURE_STORAGE_ACCOUNT_NAME} --name ${AZURE_BLOB_CONTAINER_NAME} --auth-mode login
47+
48+
AZURE_STORAGE_ACCOUNT_KEY=$(az storage account keys list --account-name ${AZURE_STORAGE_ACCOUNT_NAME} --query '[0].value' -o tsv)
49+
50+
az eventhubs eventhub create --name ${AZURE_VAULT_REFRESH_EH_NAME} --resource-group ${RESOURCE_GROUP} --namespace-name ${EH_NAMESPACE} --cleanup-policy Delete --partition-count 1 --retention-time 1
51+
52+
set +x
53+
echo "Add the following to your environment:"
54+
echo 'export AZURE_VAULT_EVENT_HUBS_BLOB_CONTAINER_NAME="'${AZURE_BLOB_CONTAINER_NAME}'"'
55+
echo 'export AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING="'$AZURE_EVENT_HUBS_CONNECTION_STRING';EntityPath='${AZURE_VAULT_REFRESH_EH_NAME}'"'
56+
echo 'export AZURE_STORAGE_ACCOUNT_KEY="'${AZURE_STORAGE_ACCOUNT_KEY}'"'
57+
}
58+
59+
60+
function deleteResources() {
61+
set -x
62+
set +e
63+
64+
az storage container delete --account-name ${AZURE_STORAGE_ACCOUNT_NAME} --name ${AZURE_BLOB_CONTAINER_NAME} --auth-mode login
65+
66+
az eventhubs eventhub delete --name ${AZURE_VAULT_REFRESH_EH_NAME} --resource-group ${RESOURCE_GROUP} --namespace-name ${EH_NAMESPACE}
67+
}
68+
69+
case "$1" in
70+
create) echo "Creating Azure resources"
71+
createResources
72+
;;
73+
delete) echo "Deleting Azure resources"
74+
deleteResources
75+
;;
76+
*) echo "usage: $0 [create|delete]"
77+
;;
78+
esac

integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultResource.java

+17
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
*/
1717
package org.apache.camel.quarkus.component.azure.key.vault.it;
1818

19+
import java.util.concurrent.atomic.AtomicBoolean;
20+
1921
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
2022
import jakarta.enterprise.context.ApplicationScoped;
23+
import jakarta.enterprise.event.Observes;
2124
import jakarta.inject.Inject;
2225
import jakarta.ws.rs.Consumes;
2326
import jakarta.ws.rs.DELETE;
@@ -30,13 +33,20 @@
3033
import jakarta.ws.rs.core.Response;
3134
import org.apache.camel.ProducerTemplate;
3235
import org.apache.camel.component.azure.key.vault.KeyVaultConstants;
36+
import org.apache.camel.impl.event.CamelContextReloadedEvent;
3337

3438
@Path("/azure-key-vault")
3539
@ApplicationScoped
3640
public class AzureKeyVaultResource {
3741
@Inject
3842
ProducerTemplate producerTemplate;
3943

44+
static final AtomicBoolean contextReloaded = new AtomicBoolean(false);
45+
46+
void onReload(@Observes CamelContextReloadedEvent event) {
47+
contextReloaded.set(true);
48+
}
49+
4050
@Path("/secret/{secretName}")
4151
@POST
4252
@Consumes(MediaType.TEXT_PLAIN)
@@ -76,4 +86,11 @@ public Response purgeSecret(@PathParam("secretName") String secretName) {
7686
public String getSecretFromPropertyPlaceholder() {
7787
return producerTemplate.requestBody("direct:propertyPlaceholder", null, String.class);
7888
}
89+
90+
@Path("/context/reload")
91+
@GET
92+
@Produces(MediaType.TEXT_PLAIN)
93+
public boolean contextReloadStatus() {
94+
return contextReloaded.get();
95+
}
7996
}

integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultRoutes.java

+16-16
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,43 @@
1616
*/
1717
package org.apache.camel.quarkus.component.azure.key.vault.it;
1818

19-
import org.apache.camel.Exchange;
2019
import org.apache.camel.Message;
21-
import org.apache.camel.Processor;
2220
import org.apache.camel.builder.RouteBuilder;
2321
import org.apache.camel.spi.PropertiesComponent;
2422

2523
public class AzureKeyVaultRoutes extends RouteBuilder {
2624
@Override
2725
public void configure() throws Exception {
2826
from("direct:createSecret")
29-
.to(azureKeyVault("createSecret"));
27+
.to(azureKeyVault("createSecret", true));
3028

3129
from("direct:getSecret")
32-
.to(azureKeyVault("getSecret"));
30+
.to(azureKeyVault("getSecret", false));
3331

3432
from("direct:deleteSecret")
35-
.to(azureKeyVault("deleteSecret"));
33+
.to(azureKeyVault("deleteSecret", true));
3634

3735
from("direct:purgeDeletedSecret")
38-
.to(azureKeyVault("purgeDeletedSecret"));
36+
.to(azureKeyVault("purgeDeletedSecret", false));
3937

4038
from("direct:propertyPlaceholder")
41-
.process(new Processor() {
42-
@Override
43-
public void process(Exchange exchange) throws Exception {
44-
Message message = exchange.getMessage();
45-
PropertiesComponent component = exchange.getContext().getPropertiesComponent();
46-
component.resolveProperty("azure:camel-quarkus-secret").ifPresent(message::setBody);
47-
}
39+
.process(exchange -> {
40+
Message message = exchange.getMessage();
41+
PropertiesComponent component = exchange.getContext().getPropertiesComponent();
42+
component.resolveProperty("azure:camel-quarkus-secret").ifPresent(message::setBody);
4843
});
4944
}
5045

51-
private String azureKeyVault(String operation) {
52-
return "azure-key-vault://{{camel.vault.azure.vaultName}}" +
46+
private String azureKeyVault(String operation, boolean useIdentity) {
47+
StringBuilder sb = new StringBuilder("azure-key-vault://{{camel.vault.azure.vaultName}}" +
5348
"?clientId=RAW({{camel.vault.azure.clientId}})" +
5449
"&clientSecret=RAW({{camel.vault.azure.clientSecret}})" +
5550
"&tenantId=RAW({{camel.vault.azure.tenantId}})" +
56-
"&operation=" + operation;
51+
"&operation=" + operation);
52+
53+
if (useIdentity) {
54+
sb.append("&credentialType=AZURE_IDENTITY");
55+
}
56+
return sb.toString();
5757
}
5858
}

0 commit comments

Comments
 (0)