This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 73a5654d5e Fixes #7004: making azure-key-valt refresh test stable.
73a5654d5e is described below
commit 73a5654d5ef464cbc066fa9e93c62d552661a135
Author: Jiri Ondrusek <[email protected]>
AuthorDate: Thu Feb 13 09:07:03 2025 +0100
Fixes #7004: making azure-key-valt refresh test stable.
---
.../azure/azure-key-vault/README.adoc | 6 ++
.../azure/key/vault/it/AzureKeyVaultResource.java | 4 +
.../src/main/resources/application.properties | 2 +
.../it/AbstractAzureKeyVaultContextReloadTest.java | 83 ++++++++-------
.../key/vault/it/AbstractAzureKeyVaultTest.java | 1 +
.../vault/it/AzureKeyVaultContextReloadTest.java | 3 -
.../it/AzureKeyVaultContextReloadTestProfile.java | 4 +-
...AzureKeyVaultContextReloadWithIdentityTest.java | 3 -
...yVaultContextReloadWithIdentityTestProfile.java | 4 +-
.../azure/key/vault/it/AzureKeyVaultTest.java | 2 +-
.../azure/key/vault/it/AzureKeyVaultUtil.java | 112 +++++++++++++++++----
11 files changed, 154 insertions(+), 70 deletions(-)
diff --git a/integration-test-groups/azure/azure-key-vault/README.adoc
b/integration-test-groups/azure/azure-key-vault/README.adoc
index 9306a8e9b4..2a50097d70 100644
--- a/integration-test-groups/azure/azure-key-vault/README.adoc
+++ b/integration-test-groups/azure/azure-key-vault/README.adoc
@@ -80,3 +80,9 @@ Following properties are generated by the script and are
required for the test e
export AZURE_STORAGE_ACCOUNT_KEY=<storage account key required for context
refresh configuration>
----
+=== Limitations
+
+Do not execute the tests in parallel, without changing the Event Hubs resource!
+
+Even thought each test is using a unique secret name regexp, the refresh
trigger task receives all events, which are send to the event hub.
+Therefore an event send by the first test might be consumed by the second
test, which would fail the first test.
\ No newline at end of file
diff --git
a/integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultResource.java
b/integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultResource.java
index b7b015b308..6e760768b1 100644
---
a/integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultResource.java
+++
b/integration-test-groups/azure/azure-key-vault/src/main/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultResource.java
@@ -36,10 +36,13 @@ import org.apache.camel.ProducerTemplate;
import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.component.azure.key.vault.KeyVaultConstants;
import org.apache.camel.impl.event.CamelContextReloadedEvent;
+import org.jboss.logging.Logger;
@Path("/azure-key-vault")
@ApplicationScoped
public class AzureKeyVaultResource {
+ private static final Logger LOG =
Logger.getLogger(AzureKeyVaultResource.class);
+
@Inject
ProducerTemplate producerTemplate;
@@ -49,6 +52,7 @@ public class AzureKeyVaultResource {
static final AtomicBoolean contextReloaded = new AtomicBoolean(false);
void onReload(@Observes CamelContextReloadedEvent event) {
+ LOG.info("AzureKeyVaultResource onReload");
contextReloaded.set(true);
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/main/resources/application.properties
b/integration-test-groups/azure/azure-key-vault/src/main/resources/application.properties
index 14e9f961cc..bc6b51551e 100644
---
a/integration-test-groups/azure/azure-key-vault/src/main/resources/application.properties
+++
b/integration-test-groups/azure/azure-key-vault/src/main/resources/application.properties
@@ -15,6 +15,8 @@
## limitations under the License.
## ---------------------------------------------------------------------------
camel.vault.azure.vaultName = ${AZURE_VAULT_NAME:cq-vault-testing}
+camel.main.context-reload-enabled = true
+
#following properties are added by the test profile if needed
#camel.vault.azure.tenantId = ${AZURE_TENANT_ID:placeholderTenantId}
#camel.vault.azure.clientId = ${AZURE_CLIENT_ID:placeholderClientId}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultContextReloadTest.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultContextReloadTest.java
index 0b494c2897..b899ae18aa 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultContextReloadTest.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultContextReloadTest.java
@@ -18,15 +18,13 @@ package
org.apache.camel.quarkus.component.azure.key.vault.it;
import java.util.LinkedList;
import java.util.List;
-import java.util.UUID;
import java.util.concurrent.TimeUnit;
import com.azure.messaging.eventhubs.EventData;
import com.azure.messaging.eventhubs.EventHubClientBuilder;
-import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
import com.azure.messaging.eventhubs.EventHubProducerClient;
-import com.azure.messaging.eventhubs.models.EventPosition;
import io.restassured.RestAssured;
+import org.eclipse.microprofile.config.ConfigProvider;
import org.hamcrest.CoreMatchers;
import org.jboss.logging.Logger;
import org.junit.jupiter.api.Test;
@@ -38,26 +36,20 @@ import static org.hamcrest.Matchers.is;
abstract class AbstractAzureKeyVaultContextReloadTest {
private static final Logger LOG =
Logger.getLogger(AbstractAzureKeyVaultContextReloadTest.class);
- private static final String SECRET_NAME_FOR_REFRESH_PREFIX =
"cq-secret-context-refresh-";
private static final String AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING =
"AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING";
- private final boolean useIdentity;
-
- public AbstractAzureKeyVaultContextReloadTest(boolean useIdentity) {
- this.useIdentity = useIdentity;
- }
-
private String generateRefreshEvent(String secretName) {
return "[{\n" +
- " \"subject\": \"" + SECRET_NAME_FOR_REFRESH_PREFIX +
(useIdentity ? "Identity-" : "") + ".*\",\n" +
+ " \"subject\": \"" + secretName + "\",\n" +
" \"eventType\":
\"Microsoft.KeyVault.SecretNewVersionCreated\"\n" +
"}]";
}
@Test
void contextReload() {
- String secretName = SECRET_NAME_FOR_REFRESH_PREFIX + (useIdentity ?
"Identity-" : "") + UUID.randomUUID();
+ String secretName =
ConfigProvider.getConfig().getValue("camel.vault.azure.secrets",
String.class).replace(".*", "");
String secretValue = "Hello Camel Quarkus Azure Key Vault From
Refresh";
+ boolean reloadDetected = false;
try {
// Create secret
RestAssured.given()
@@ -66,12 +58,21 @@ abstract class AbstractAzureKeyVaultContextReloadTest {
.then()
.statusCode(200)
.body(is(secretName));
+ LOG.infof("Secret created: %s", secretName);
// Retrieve secret
RestAssured.given()
.get("/azure-key-vault/secret/true/{secretName}",
secretName)
.then()
.statusCode(200);
+ LOG.info("Secret verified before refresh.");
+
+ LOG.info("Wait some time for listener to be initialized");
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
//force reload by sending a msg
try (EventHubProducerClient client = new EventHubClientBuilder()
@@ -81,44 +82,52 @@ abstract class AbstractAzureKeyVaultContextReloadTest {
EventData eventData = new
EventData(generateRefreshEvent(secretName).getBytes());
List<EventData> finalEventData = new LinkedList<>();
finalEventData.add(eventData);
+ LOG.info("Sending refresh event.");
client.send(finalEventData);
} catch (Exception e) {
LOG.info("Failed to send a refresh message", e);
}
//await context reload
- Awaitility.await().pollInterval(10, TimeUnit.SECONDS).atMost(1,
TimeUnit.MINUTES).untilAsserted(
+ Awaitility.await().pollInterval(10, TimeUnit.SECONDS).atMost(2,
TimeUnit.MINUTES).untilAsserted(
() -> {
RestAssured.get("/azure-key-vault/context/reload")
.then()
.statusCode(200)
.body(CoreMatchers.is("true"));
});
+ reloadDetected = true;
} finally {
-
- //move cursor of events to ignore old ones (old events are deleted
after 1 hour)
- try {
- String connectionString =
System.getenv(AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING);
- String consumerGroup =
EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME;
-
- try (EventHubConsumerAsyncClient consumer = new
EventHubClientBuilder()
- .connectionString(connectionString)
- .consumerGroup(consumerGroup)
- .buildAsyncConsumerClient()) {
-
- // Move consumer to the latest position, skipping old
messages
- consumer.receiveFromPartition("0", EventPosition.latest())
- .subscribe(event -> {
- System.out.println("Processing new event: " +
event.toString());
- }, error -> {
- System.err.println("Error receiving events: "
+ error);
- });
- }
- } catch (Exception e) {
- LOG.info("Failed to clear event hub.", e);
- }
-
- AzureKeyVaultUtil.deleteSecretImmediately(secretName);
+ // meant to be commented.
+ // during development, it may be handy to mark eventhub as
completely read. (in case the test is not reading all the messages by itself)
+ // Please uncomment the rest of the code to make cursor reset to
the latest position after test execution
+
+ // following code moves the cursor of the hub to the
latest position, thus marking all events as read
+ // partition 0 is hardcoded (the resource script
creates only one partition)
+ // by default this functionality should not be
executed, as the eventbus might be shared for more tests/purposes
+ // even if event stays, it is removed by retention
policy in some time (i.e. 1 hpr)
+ // try {
+ // String connectionString =
System.getenv(AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING);
+ // String consumerGroup =
EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME;
+ //
+ // try (EventHubConsumerAsyncClient consumer = new
EventHubClientBuilder()
+ // .connectionString(connectionString)
+ // .consumerGroup(consumerGroup)
+ // .buildAsyncConsumerClient()) {
+ //
+ // // Move consumer to the latest position,
skipping old messages
+ // consumer.receiveFromPartition("0",
EventPosition.latest())
+ // .subscribe(event -> {
+ // System.out.println("Processing
new event: " + event.toString());
+ // }, error -> {
+ // System.err.println("Error
receiving events: " + error);
+ // });
+ // }
+ // } catch (Exception e) {
+ // LOG.info("Failed to clear event hub.", e);
+ // }
+
+ AzureKeyVaultUtil.deleteSecretImmediately(secretName, true);
}
}
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultTest.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultTest.java
index 21b766830b..04af95bdb3 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultTest.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AbstractAzureKeyVaultTest.java
@@ -76,6 +76,7 @@ abstract class AbstractAzureKeyVaultTest {
.then()
.statusCode(200)
.body(is(secret));
+
} finally {
AzureKeyVaultUtil.deleteSecretImmediately(secretName, useIdentity);
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTest.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTest.java
index 608c94ce4a..d661d99ba7 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTest.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTest.java
@@ -36,7 +36,4 @@ import
org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@TestProfile(AzureKeyVaultContextReloadTestProfile.class)
@QuarkusTest
class AzureKeyVaultContextReloadTest extends
AbstractAzureKeyVaultContextReloadTest {
- public AzureKeyVaultContextReloadTest() {
- super(false);
- }
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTestProfile.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTestProfile.java
index f9ea660ef3..a5f5567186 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTestProfile.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadTestProfile.java
@@ -18,6 +18,7 @@ package org.apache.camel.quarkus.component.azure.key.vault.it;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import io.quarkus.test.junit.QuarkusTestProfile;
@@ -32,12 +33,11 @@ public class AzureKeyVaultContextReloadTestProfile
implements QuarkusTestProfile
props.put("camel.vault.azure.clientSecret",
System.getenv("AZURE_CLIENT_SECRET"));
props.put("camel.vault.azure.refreshEnabled", "true");
props.put("camel.vault.azure.refreshPeriod", "1000");
- props.put("camel.vault.azure.secrets", "cq-secret-context-refresh.*");
+ props.put("camel.vault.azure.secrets",
String.format("cq-secret-context-refresh-%s.*", UUID.randomUUID()));
props.put("camel.vault.azure.eventhubConnectionString",
System.getenv("AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING"));
props.put("camel.vault.azure.blobAccountName",
System.getenv("AZURE_STORAGE_ACCOUNT_NAME"));
props.put("camel.vault.azure.blobContainerName",
System.getenv("AZURE_VAULT_EVENT_HUBS_BLOB_CONTAINER_NAME"));
props.put("camel.vault.azure.blobAccessKey",
System.getenv("AZURE_STORAGE_ACCOUNT_KEY"));
- props.put("camel.main.context-reload-enabled", "true");
return props;
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTest.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTest.java
index df793ef69e..a69774e4a3 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTest.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTest.java
@@ -36,7 +36,4 @@ import
org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@TestProfile(AzureKeyVaultContextReloadWithIdentityTestProfile.class)
@QuarkusTest
class AzureKeyVaultContextReloadWithIdentityTest extends
AbstractAzureKeyVaultContextReloadTest {
- public AzureKeyVaultContextReloadWithIdentityTest() {
- super(true);
- }
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTestProfile.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTestProfile.java
index f775ec8805..4f22b2547d 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTestProfile.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultContextReloadWithIdentityTestProfile.java
@@ -18,6 +18,7 @@ package org.apache.camel.quarkus.component.azure.key.vault.it;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import io.quarkus.test.junit.QuarkusTestProfile;
@@ -29,12 +30,11 @@ public class
AzureKeyVaultContextReloadWithIdentityTestProfile implements Quarku
Map<String, String> props = new HashMap<>();
props.put("camel.vault.azure.refreshEnabled", "true");
props.put("camel.vault.azure.refreshPeriod", "1000");
- props.put("camel.vault.azure.secrets", "cq-secret-context-refresh.*");
+ props.put("camel.vault.azure.secrets",
String.format("cq-secret-context-refresh-identity-%s.*", UUID.randomUUID()));
props.put("camel.vault.azure.eventhubConnectionString",
System.getenv("AZURE_VAULT_EVENT_HUBS_CONNECTION_STRING"));
props.put("camel.vault.azure.blobAccountName",
System.getenv("AZURE_STORAGE_ACCOUNT_NAME"));
props.put("camel.vault.azure.blobContainerName",
System.getenv("AZURE_VAULT_EVENT_HUBS_BLOB_CONTAINER_NAME"));
props.put("camel.vault.azure.blobAccessKey",
System.getenv("AZURE_STORAGE_ACCOUNT_KEY"));
- props.put("camel.main.context-reload-enabled", "true");
props.put("camel.vault.azure.azureIdentityEnabled", "true");
return props;
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultTest.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultTest.java
index 8997cef6d6..67a101fc68 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultTest.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultTest.java
@@ -66,7 +66,7 @@ class AzureKeyVaultTest extends AbstractAzureKeyVaultTest {
tryToDeleteSecret = false;
} finally {
if (tryToDeleteSecret) {
- AzureKeyVaultUtil.deleteSecretImmediately(secretName);
+ AzureKeyVaultUtil.deleteSecretImmediately(secretName, true);
}
}
}
diff --git
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultUtil.java
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultUtil.java
index 291f5b111f..18b9f4825b 100644
---
a/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultUtil.java
+++
b/integration-test-groups/azure/azure-key-vault/src/test/java/org/apache/camel/quarkus/component/azure/key/vault/it/AzureKeyVaultUtil.java
@@ -16,33 +16,101 @@
*/
package org.apache.camel.quarkus.component.azure.key.vault.it;
+import com.azure.core.credential.TokenCredential;
+import com.azure.core.exception.HttpResponseException;
+import com.azure.core.exception.ResourceNotFoundException;
+import com.azure.identity.ClientSecretCredentialBuilder;
+import com.azure.security.keyvault.secrets.SecretClient;
+import com.azure.security.keyvault.secrets.SecretClientBuilder;
+import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
import io.restassured.RestAssured;
+import org.jboss.logging.Logger;
public class AzureKeyVaultUtil {
+ private static final Logger LOG =
Logger.getLogger(AzureKeyVaultUtil.class);
- static void deleteSecretImmediately(String secretName) {
- //we need to se identity by default, as the non-identity routes may
not start
- AzureKeyVaultUtil.deleteSecretImmediately(secretName, true);
- }
+ private static final int MAX_RETRIES = 5;
+ private static final int RETRY_DELAY_MS = 5000; // 5 seconds
static void deleteSecretImmediately(String secretName, boolean
useIdentity) {
- // Delete secret
- RestAssured.given()
- .delete("/azure-key-vault/secret/" + useIdentity +
"/{secretName}", secretName)
- .then()
- .statusCode(200);
-
- // Purge secret
- RestAssured.given()
- .delete("/azure-key-vault/secret/" + useIdentity +
"/{secretName}/purge", secretName)
- .then()
- .statusCode(200);
-
- // Confirm deletion
- RestAssured.given()
- .queryParam("identity", useIdentity)
- .get("/azure-key-vault/secret/" + useIdentity +
"/{secretName}", secretName)
- .then()
- .statusCode(500);
+
+ boolean deleted = false;
+
+ try {
+ // Delete secret
+ RestAssured.given()
+ .delete("/azure-key-vault/secret/" + useIdentity +
"/{secretName}", secretName)
+ .then()
+ .statusCode(200);
+
+ // Purge secret
+ RestAssured.given()
+ .delete("/azure-key-vault/secret/" + useIdentity +
"/{secretName}/purge", secretName)
+ .then()
+ .statusCode(200);
+
+ // Confirm deletion
+ RestAssured.given()
+ .queryParam("identity", useIdentity)
+ .get("/azure-key-vault/secret/" + useIdentity +
"/{secretName}", secretName)
+ .then()
+ .statusCode(500);
+ deleted = true;
+ } finally {
+ if (!deleted) {
+ // in case the deletion via component fails, delete directly
via client
+ deleteSecretImmediatelyViaClient(secretName);
+ }
+ }
+
+ }
+
+ private static void deleteSecretImmediatelyViaClient(String secretName) {
+
+ //create client
+ String keyVaultUri = "https://" + System.getenv("AZURE_VAULT_NAME") +
".vault.azure.net";
+ TokenCredential credential = ((ClientSecretCredentialBuilder)
((ClientSecretCredentialBuilder) (new ClientSecretCredentialBuilder())
+
.tenantId(System.getenv("AZURE_TENANT_ID"))).clientId(System.getenv("AZURE_CLIENT_ID")))
+ .clientSecret(System.getenv("AZURE_CLIENT_SECRET")).build();
+
+ SecretClient client = (new
SecretClientBuilder()).vaultUrl(keyVaultUri).credential(credential).buildClient();
+
+ try {
+ KeyVaultSecret secret = client.getSecret(secretName);
+
+ if (secret != null) {
+ client.beginDeleteSecret(secretName);
+ }
+
+ } catch (ResourceNotFoundException e) {
+ //already deleted
+ } finally {
+ //purge secret in all cases to be sure it is purged
+ try {
+ client.purgeDeletedSecret(secretName);
+ } catch (HttpResponseException e) {
+ if (e.getResponse().getStatusCode() == 409) { // Conflict:
Object is being deleted
+ int attempt = 0;
+ while (attempt++ < MAX_RETRIES) {
+ LOG.infof("Attempt %d to delete secret '%s'.",
attempt, secretName);
+ try {
+ Thread.sleep(RETRY_DELAY_MS);
+ } catch (InterruptedException ex) {
+ LOG.errorf("Purging of secret `%s` failed",
secretName, ex);
+ }
+ try {
+ client.purgeDeletedSecret(secretName);
+ break;
+ } catch (HttpResponseException ex) {
+ LOG.errorf("Purging of secret `%s` failed",
secretName, ex);
+ }
+
+ }
+ if (attempt >= MAX_RETRIES) {
+ LOG.errorf("Purging of secret `%s` failed after %d
attempts.", secretName, attempt);
+ }
+ }
+ }
+ }
}
}