aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrameshiyer27 <ramesh.murugan.iyer@est.tech>2025-02-16 10:24:55 +0000
committerrameshiyer27 <ramesh.murugan.iyer@est.tech>2025-02-24 11:18:52 +0000
commit8daa4d84d8eee9c0713239e354aebc76e4a299f9 (patch)
tree3422f527e78e3e54c9f9c57efdf1e43985e5005a
parentf25247386d9cf1e669c9ce0fc2ad0d31216b566c (diff)
Add encrypt/decrypt functionality for sensitive fields
Issue-ID: POLICY-5134 Signed-off-by: rameshiyer27 <ramesh.murugan.iyer@est.tech> Change-Id: If564f01900fbc51496b9ba6f9cea05bab93d44f9
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java19
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcmParameters.java6
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtils.java199
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java12
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java10
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java8
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java14
-rw-r--r--runtime-acm/src/main/resources/application.yaml2
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java55
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtilTest.java69
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScannerTest.java19
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java16
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java4
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java14
-rw-r--r--runtime-acm/src/test/resources/providers/AcDefinitionEncryptTest.yaml160
-rw-r--r--runtime-acm/src/test/resources/providers/AcInstantiateEncryptTest.json84
16 files changed, 645 insertions, 46 deletions
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
index 0979a811b..eacd07fc9 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2025 Nordix Foundation.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
@@ -79,6 +80,7 @@ public class AutomationCompositionInstantiationProvider {
private final SupervisionAcHandler supervisionAcHandler;
private final ParticipantProvider participantProvider;
private final AcRuntimeParameterGroup acRuntimeParameterGroup;
+ private final EncryptionUtils encryptionUtils;
/**
* Create automation composition.
@@ -104,6 +106,7 @@ public class AutomationCompositionInstantiationProvider {
if (!validationResult.isValid()) {
throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
+ encryptInstanceProperties(automationComposition, compositionId);
automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
return createInstantiationResponse(automationComposition);
@@ -141,6 +144,7 @@ public class AutomationCompositionInstantiationProvider {
if (!validationResult.isValid()) {
throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
+ encryptInstanceProperties(acToUpdate, compositionId);
automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
return createInstantiationResponse(automationComposition);
@@ -200,6 +204,8 @@ public class AutomationCompositionInstantiationProvider {
// Publish property update event to the participants
supervisionAcHandler.update(acToBeUpdated);
+ encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionId());
+
automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
return createInstantiationResponse(automationComposition);
}
@@ -242,6 +248,8 @@ public class AutomationCompositionInstantiationProvider {
// Publish migrate event to the participants
supervisionAcHandler.migrate(acToBeUpdated, acDefinition.getServiceTemplate());
+ encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionTargetId());
+
var ac = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
elementsRemoved.forEach(automationCompositionProvider::deleteAutomationCompositionElement);
return createInstantiationResponse(ac);
@@ -356,6 +364,15 @@ public class AutomationCompositionInstantiationProvider {
return result;
}
+
+ private void encryptInstanceProperties(AutomationComposition automationComposition, UUID compositionId) {
+ if (encryptionUtils.encryptionEnabled()) {
+ var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
+ acDefinitionOpt.ifPresent(acDefinition
+ -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition));
+ }
+ }
+
/**
* Get Automation Composition.
*
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcmParameters.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcmParameters.java
index 3ae21e5fb..554edea32 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcmParameters.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcmParameters.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * Copyright (C) 2023,2025 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,4 +35,8 @@ public class AcmParameters {
private String toscaCompositionName = "org.onap.policy.clamp.acm.AutomationComposition";
+ private String passPhrase;
+
+ private String salt;
+
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtils.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtils.java
new file mode 100644
index 000000000..565adb02d
--- /dev/null
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtils.java
@@ -0,0 +1,199 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2025 Nordix Foundation.
+ * ================================================================================
+ * Licensed 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.runtime.main.utils;
+
+import jakarta.ws.rs.core.Response;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * Class to encrypt/decrypt sensitive fields in the database.
+ */
+
+@Component
+public class EncryptionUtils {
+
+ private static final String ALGORITHM = "AES/GCM/NoPadding";
+ private static final String PBK_ALGORITHM = "PBKDF2WithHmacSHA256";
+ private static final String MARKER = "ENCRYPTED:";
+ private static final String SENSITIVE_METADATA = "sensitive";
+ private static final int GCM_TAG = 128;
+ private static final int IV_LENGTH = 12;
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+ private final String passPhrase;
+ private final String salt;
+
+
+ private static byte[] generateIV() {
+ var iv = new byte[IV_LENGTH];
+ SECURE_RANDOM.nextBytes(iv); //random iv
+ return iv;
+ }
+
+ /**
+ * Constructor EncryptionUtils.
+ * @param acRuntimeParameterGroup acRuntimeParameterGroup
+ */
+ public EncryptionUtils(AcRuntimeParameterGroup acRuntimeParameterGroup) {
+ this.passPhrase = acRuntimeParameterGroup.getAcmParameters().getPassPhrase();
+ this.salt = acRuntimeParameterGroup.getAcmParameters().getSalt();
+ }
+
+ /**
+ * Check encryption is enabled.
+ * @return boolean result
+ */
+ public boolean encryptionEnabled() {
+ return passPhrase != null && salt != null;
+ }
+
+
+ /**
+ * Find and encrypt sensitive fields in an AC instance.
+ * @param acDefinition acDefinition
+ * @param automationComposition acInstance
+ */
+ public void findAndEncryptSensitiveData(AutomationCompositionDefinition acDefinition,
+ AutomationComposition automationComposition) {
+ try {
+ for (var acInstanceElement: automationComposition.getElements().values()) {
+ var sensitiveProperties = findSensitiveElementFields(acDefinition, acInstanceElement);
+ for (var property : sensitiveProperties) {
+ var elementProperties = acInstanceElement.getProperties();
+ var sensitiveVal = elementProperties.get(property.getName());
+ if (sensitiveVal instanceof String sensitiveStr && !sensitiveStr.startsWith(MARKER)) {
+ var encryptedVal = encrypt(sensitiveStr);
+ elementProperties.put(property.getName(), encryptedVal);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new AutomationCompositionRuntimeException(Response.Status.fromStatusCode(500),
+ "Failed to encrypt instance field ", e);
+ }
+ }
+
+
+ /**
+ * Find and decrypt sensitive fields in an AC instance.
+ * @param automationComposition acInstance
+ */
+ public void findAndDecryptSensitiveData(AutomationComposition automationComposition) {
+ try {
+ for (var acInstanceElement: automationComposition.getElements().values()) {
+ for (var property : acInstanceElement.getProperties().entrySet()) {
+ var propertyVal = property.getValue();
+ if (propertyVal instanceof String propertyValStr && propertyValStr.startsWith(MARKER)) {
+ var decryptedVal = decrypt(propertyValStr);
+ acInstanceElement.getProperties().put(property.getKey(), decryptedVal);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new AutomationCompositionRuntimeException(Response.Status.fromStatusCode(500),
+ "Failed to decrypt instance field ", e);
+ }
+ }
+
+
+ private List<ToscaProperty> findSensitiveElementFields(AutomationCompositionDefinition acDefinition,
+ AutomationCompositionElement acInstanceElement) {
+
+ List<ToscaProperty> sensitiveProperties = new ArrayList<>();
+
+ // Fetch the node template element
+ var acDefElementOpt = acDefinition.getServiceTemplate().getToscaTopologyTemplate().getNodeTemplates()
+ .values().stream().filter(acDefElement -> acDefElement.getName()
+ .equals(acInstanceElement.getDefinition().getName())).findFirst();
+
+ // Fetch node type
+ if (acDefElementOpt.isPresent()) {
+ var toscaNodeTypeOpt = acDefinition.getServiceTemplate().getNodeTypes().values().stream()
+ .filter(toscaNodeType -> toscaNodeType.getName()
+ .equals(acDefElementOpt.get().getType())).findFirst();
+
+ toscaNodeTypeOpt.ifPresent(toscaNodeType -> toscaNodeType.getProperties().values()
+ .stream().filter(property -> property.getMetadata() != null
+ && property.getMetadata().containsKey(SENSITIVE_METADATA))
+ .forEach(sensitiveProperties::add));
+ }
+ return sensitiveProperties;
+ }
+
+
+ private SecretKey getSecretKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
+ var factory = SecretKeyFactory.getInstance(PBK_ALGORITHM);
+ var spec = new PBEKeySpec(passPhrase.toCharArray(), salt.getBytes(), 65536, 256);
+ return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
+ }
+
+ private String encrypt(String input) throws IllegalBlockSizeException, BadPaddingException,
+ NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException,
+ NoSuchPaddingException {
+ var iv = generateIV();
+ var parameterSpec = new GCMParameterSpec(GCM_TAG, iv);
+ var cipher = Cipher.getInstance(ALGORITHM);
+ cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), parameterSpec);
+ var cipherText = cipher.doFinal(input.getBytes());
+ var cipherByte = ByteBuffer.allocate(iv.length + cipherText.length).put(iv).put(cipherText).array();
+ return MARKER + Base64.getEncoder().encodeToString(cipherByte);
+ }
+
+ private String decrypt(String cipherText) throws IllegalBlockSizeException, BadPaddingException,
+ NoSuchAlgorithmException, InvalidKeySpecException,
+ InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException {
+ var decodedText = Base64.getDecoder().decode(cipherText.substring(MARKER.length()).getBytes());
+ var byteBuffer = ByteBuffer.wrap(decodedText);
+ var iv = new byte[IV_LENGTH];
+ byteBuffer.get(iv);
+ var encryptedByte = new byte[byteBuffer.remaining()];
+ byteBuffer.get(encryptedByte);
+
+ var parameterSpec = new GCMParameterSpec(GCM_TAG, iv);
+ var cipher = Cipher.getInstance(ALGORITHM);
+ cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), parameterSpec);
+ var plainText = cipher.doFinal(encryptedByte);
+ return new String(plainText);
+ }
+}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java
index 136276e55..0f9b9412d 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java
@@ -21,6 +21,7 @@
package org.onap.policy.clamp.acm.runtime.supervision.scanner;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.DeployState;
@@ -40,13 +41,15 @@ public abstract class AbstractScanner {
protected final AutomationCompositionProvider acProvider;
private final ParticipantSyncPublisher participantSyncPublisher;
+ private final EncryptionUtils encryptionUtils;
protected AbstractScanner(final AutomationCompositionProvider acProvider,
final ParticipantSyncPublisher participantSyncPublisher,
- final AcRuntimeParameterGroup acRuntimeParameterGroup) {
+ final AcRuntimeParameterGroup acRuntimeParameterGroup, final EncryptionUtils encryptionUtils) {
this.acProvider = acProvider;
this.participantSyncPublisher = participantSyncPublisher;
this.maxStatusWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs();
+ this.encryptionUtils = encryptionUtils;
}
protected void complete(final AutomationComposition automationComposition, UpdateSync updateSync) {
@@ -118,7 +121,14 @@ public abstract class AbstractScanner {
acProvider.deleteAutomationComposition(automationComposition.getInstanceId());
}
if (updateSync.isToBeSync()) {
+ decryptInstanceProperties(automationComposition);
participantSyncPublisher.sendSync(automationComposition);
}
}
+
+ protected void decryptInstanceProperties(AutomationComposition automationComposition) {
+ if (encryptionUtils.encryptionEnabled()) {
+ encryptionUtils.findAndDecryptSensitiveData(automationComposition);
+ }
+ }
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java
index de56040cd..18bdb5587 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java
@@ -21,6 +21,7 @@
package org.onap.policy.clamp.acm.runtime.supervision.scanner;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
@@ -52,8 +53,9 @@ public class PhaseScanner extends AbstractScanner {
final ParticipantSyncPublisher participantSyncPublisher,
final AutomationCompositionStateChangePublisher acStateChangePublisher,
final AutomationCompositionDeployPublisher acDeployPublisher,
- final AcRuntimeParameterGroup acRuntimeParameterGroup) {
- super(acProvider, participantSyncPublisher, acRuntimeParameterGroup);
+ final AcRuntimeParameterGroup acRuntimeParameterGroup,
+ final EncryptionUtils encryptionUtils) {
+ super(acProvider, participantSyncPublisher, acRuntimeParameterGroup, encryptionUtils);
this.acStateChangePublisher = acStateChangePublisher;
this.acDeployPublisher = acDeployPublisher;
}
@@ -115,7 +117,9 @@ public class PhaseScanner extends AbstractScanner {
if (DeployState.DEPLOYING.equals(automationComposition.getDeployState())) {
LOGGER.debug("retry message AutomationCompositionDeploy");
- acDeployPublisher.send(automationComposition, startPhase, false);
+ var acToSend = new AutomationComposition(automationComposition);
+ decryptInstanceProperties(acToSend);
+ acDeployPublisher.send(acToSend, startPhase, false);
} else {
LOGGER.debug("retry message AutomationCompositionStateChange");
acStateChangePublisher.send(automationComposition, startPhase, false);
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java
index c102412bb..51dadfac5 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java
@@ -21,6 +21,7 @@
package org.onap.policy.clamp.acm.runtime.supervision.scanner;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
@@ -45,9 +46,10 @@ public class SimpleScanner extends AbstractScanner {
* @param acRuntimeParameterGroup the parameters for the automation composition runtime
*/
public SimpleScanner(final AutomationCompositionProvider acProvider,
- final ParticipantSyncPublisher participantSyncPublisher,
- final AcRuntimeParameterGroup acRuntimeParameterGroup) {
- super(acProvider, participantSyncPublisher, acRuntimeParameterGroup);
+ final ParticipantSyncPublisher participantSyncPublisher,
+ final AcRuntimeParameterGroup acRuntimeParameterGroup,
+ final EncryptionUtils encryptionUtils) {
+ super(acProvider, participantSyncPublisher, acRuntimeParameterGroup, encryptionUtils);
}
/**
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java
index 18717cc2b..789303221 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java
@@ -22,6 +22,7 @@ package org.onap.policy.clamp.acm.runtime.supervision.scanner;
import java.util.Comparator;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
@@ -45,10 +46,11 @@ public class StageScanner extends AbstractScanner {
* @param acRuntimeParameterGroup the parameters for the automation composition runtime
*/
public StageScanner(final AutomationCompositionProvider acProvider,
- final ParticipantSyncPublisher participantSyncPublisher,
- final AutomationCompositionMigrationPublisher acMigrationPublisher,
- final AcRuntimeParameterGroup acRuntimeParameterGroup) {
- super(acProvider, participantSyncPublisher, acRuntimeParameterGroup);
+ final ParticipantSyncPublisher participantSyncPublisher,
+ final AutomationCompositionMigrationPublisher acMigrationPublisher,
+ final AcRuntimeParameterGroup acRuntimeParameterGroup,
+ final EncryptionUtils encryptionUtils) {
+ super(acProvider, participantSyncPublisher, acRuntimeParameterGroup, encryptionUtils);
this.acMigrationPublisher = acMigrationPublisher;
}
@@ -87,7 +89,9 @@ public class StageScanner extends AbstractScanner {
updateSync.setUpdated(true);
saveAndSync(automationComposition, updateSync);
LOGGER.debug("retry message AutomationCompositionMigration");
- acMigrationPublisher.send(automationComposition, minStageNotCompleted);
+ var acToSend = new AutomationComposition(automationComposition);
+ decryptInstanceProperties(acToSend);
+ acMigrationPublisher.send(acToSend, minStageNotCompleted);
} else {
handleTimeout(automationComposition, updateSync);
}
diff --git a/runtime-acm/src/main/resources/application.yaml b/runtime-acm/src/main/resources/application.yaml
index 1bc529a74..247cd2420 100644
--- a/runtime-acm/src/main/resources/application.yaml
+++ b/runtime-acm/src/main/resources/application.yaml
@@ -62,6 +62,8 @@ runtime:
acmParameters:
toscaElementName: org.onap.policy.clamp.acm.AutomationCompositionElement
toscaCompositionName: org.onap.policy.clamp.acm.AutomationComposition
+ passPhrase: 1234AbCEncryptionPassPhrase
+ salt: runtimeFixedSalt
management:
endpoints:
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
index 21ad2f616..d53f700f6 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2025 Nordix Foundation.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,6 +39,7 @@ import java.util.UUID;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
@@ -93,6 +94,8 @@ class AutomationCompositionInstantiationProviderTest {
private static final String DO_NOT_MATCH = " do not match with ";
+
+
private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
@BeforeAll
@@ -113,9 +116,10 @@ class AutomationCompositionInstantiationProviderTest {
var acProvider = mock(AutomationCompositionProvider.class);
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
null, supervisionAcHandler, participantProvider,
- CommonTestData.getTestParamaterGroup());
+ CommonTestData.getTestParamaterGroup(), encryptionUtils);
var automationCompositionCreate =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
automationCompositionCreate.setCompositionId(compositionId);
@@ -179,9 +183,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- CommonTestData.getTestParamaterGroup());
+ CommonTestData.getTestParamaterGroup(), encryptionUtils);
var instantiationResponse = instantiationProvider.updateAutomationComposition(
automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
@@ -207,13 +212,14 @@ class AutomationCompositionInstantiationProviderTest {
automationCompositionUpdate.setDeployState(DeployState.DEPLOYING);
automationCompositionUpdate.setLockState(LockState.NONE);
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
.thenReturn(automationCompositionUpdate);
var instantiationProvider =
new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
- mock(AcRuntimeParameterGroup.class));
+ mock(AcRuntimeParameterGroup.class), encryptionUtils);
var compositionId = automationCompositionUpdate.getCompositionId();
assertThatThrownBy(
@@ -279,9 +285,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- new AcRuntimeParameterGroup());
+ new AcRuntimeParameterGroup(), encryptionUtils);
automationCompositionTarget.setPrecheck(true);
var preCheckResponse = instantiationProvider.updateAutomationComposition(compositionId,
@@ -311,7 +318,7 @@ class AutomationCompositionInstantiationProviderTest {
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- new AcRuntimeParameterGroup());
+ new AcRuntimeParameterGroup(), null);
var instanceId = UUID.randomUUID();
assertDoesNotThrow(() -> {
instantiationProvider.checkCompatibility(newDefinition, oldDefinition, instanceId);
@@ -346,8 +353,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup());
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
+ encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
@@ -390,8 +399,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var acmParticipantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup());
+ new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup(),
+ encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
@@ -439,9 +450,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- new AcRuntimeParameterGroup());
+ new AcRuntimeParameterGroup(), encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
@@ -449,7 +461,7 @@ class AutomationCompositionInstantiationProviderTest {
}
@Test
- void testMigratePrecheckBadRequest() {
+ void testMigratePreCheckBadRequest() {
var acDefinitionProvider = mock(AcDefinitionProvider.class);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var compositionId = acDefinition.getCompositionId();
@@ -477,9 +489,10 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- new AcRuntimeParameterGroup());
+ new AcRuntimeParameterGroup(), encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
@@ -500,9 +513,11 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- null, supervisionAcHandler, participantProvider, acRuntimeParameterGroup);
+ null, supervisionAcHandler, participantProvider, acRuntimeParameterGroup,
+ encryptionUtils);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
@@ -535,7 +550,7 @@ class AutomationCompositionInstantiationProviderTest {
var instantiationProvider =
new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null,
- acRuntimeParamaterGroup);
+ acRuntimeParamaterGroup, null);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
@@ -562,10 +577,11 @@ class AutomationCompositionInstantiationProviderTest {
when(acProvider.createAutomationComposition(automationCompositionCreate))
.thenReturn(automationCompositionCreate);
var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
null, null, participantProvider,
- CommonTestData.getTestParamaterGroup());
+ CommonTestData.getTestParamaterGroup(), encryptionUtils);
var instantiationResponse = instantiationProvider.createAutomationComposition(
automationCompositionCreate.getCompositionId(), automationCompositionCreate);
@@ -591,8 +607,9 @@ class AutomationCompositionInstantiationProviderTest {
automationComposition.setCompositionId(compositionId);
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = mock(EncryptionUtils.class);
var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null,
- participantProvider, CommonTestData.getTestParamaterGroup());
+ participantProvider, CommonTestData.getTestParamaterGroup(), encryptionUtils);
assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
.hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
@@ -614,7 +631,7 @@ class AutomationCompositionInstantiationProviderTest {
.thenReturn(automationComposition);
var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
null, null, null,
- mock(AcRuntimeParameterGroup.class));
+ mock(AcRuntimeParameterGroup.class), null);
var compositionId = automationComposition.getCompositionId();
assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
@@ -634,7 +651,7 @@ class AutomationCompositionInstantiationProviderTest {
.thenReturn(automationComposition);
var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
null, null, null,
- mock(AcRuntimeParameterGroup.class));
+ mock(AcRuntimeParameterGroup.class), null);
var compositionId = automationComposition.getCompositionId();
var wrongCompositionId = UUID.randomUUID();
@@ -670,7 +687,7 @@ class AutomationCompositionInstantiationProviderTest {
var acProvider = mock(AutomationCompositionProvider.class);
var provider =
new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null,
- null);
+ null, null);
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
@@ -704,7 +721,7 @@ class AutomationCompositionInstantiationProviderTest {
var participantProvider = mock(ParticipantProvider.class);
var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
- mock(AcRuntimeParameterGroup.class));
+ mock(AcRuntimeParameterGroup.class), null);
var acInstanceStateUpdate = new AcInstanceStateUpdate();
acInstanceStateUpdate.setDeployOrder(DeployOrder.DEPLOY);
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtilTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtilTest.java
new file mode 100644
index 000000000..ae6066ae5
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/utils/EncryptionUtilTest.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2025 Nordix Foundation.
+ * ================================================================================
+ * Licensed 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.runtime.main.utils;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
+
+class EncryptionUtilTest {
+
+ private static ToscaServiceTemplate serviceTemplateEncrypt;
+ public static final String TOSCA_TEMPLATE_YAML = "src/test/resources/providers/AcDefinitionEncryptTest.yaml";
+ public static final String INSTANTIATE_JSON = "src/test/resources/providers/AcInstantiateEncryptTest.json";
+ private static AutomationCompositionDefinition acDefinition;
+
+ @BeforeAll
+ static void setUpBeforeClass() {
+ serviceTemplateEncrypt = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
+ var jpa2 = ProviderUtils.getJpaAndValidate(serviceTemplateEncrypt, JpaToscaServiceTemplate::new,
+ "toscaServiceTemplate");
+ serviceTemplateEncrypt = jpa2.toAuthorative();
+ acDefinition = CommonTestData.createAcDefinition(serviceTemplateEncrypt, AcTypeState.PRIMED);
+ }
+
+ @Test
+ void testEncryptAcInstanceProperties() {
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(INSTANTIATE_JSON, "Crud");
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getEncryptionParamaterGroup());
+ assertTrue(encryptionUtils.encryptionEnabled());
+ assertDoesNotThrow(()
+ -> {
+ assert automationComposition != null;
+ encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition);
+ });
+ assertDoesNotThrow(() -> {
+ assert automationComposition != null;
+ encryptionUtils.findAndDecryptSensitiveData(automationComposition);
+ });
+ }
+
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScannerTest.java
index 6958fe410..c2860a86b 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScannerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScannerTest.java
@@ -35,6 +35,7 @@ import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
@@ -68,9 +69,10 @@ class PhaseScannerTest {
var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var phaseScanner = new PhaseScanner(automationCompositionProvider, mock(ParticipantSyncPublisher.class),
- acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup);
+ acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
phaseScanner.scanWithPhase(automationComposition, serviceTemplate, new UpdateSync());
@@ -88,9 +90,10 @@ class PhaseScannerTest {
var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var phaseScanner = new PhaseScanner(automationCompositionProvider, mock(ParticipantSyncPublisher.class),
- acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup);
+ acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
phaseScanner.scanWithPhase(automationComposition, serviceTemplate, new UpdateSync());
@@ -119,10 +122,11 @@ class PhaseScannerTest {
var participantSyncPublisher = mock(ParticipantSyncPublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1);
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
// verify timeout scenario
var phaseScanner = new PhaseScanner(automationCompositionProvider, participantSyncPublisher,
- acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup);
+ acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup, encryptionUtils);
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
automationComposition.setLastMsg(TimestampHelper.now());
@@ -173,9 +177,10 @@ class PhaseScannerTest {
var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var phaseScanner = new PhaseScanner(automationCompositionProvider, mock(ParticipantSyncPublisher.class),
- acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup);
+ acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
phaseScanner.scanWithPhase(automationComposition, serviceTemplate, new UpdateSync());
@@ -207,10 +212,11 @@ class PhaseScannerTest {
var acProvider = mock(AutomationCompositionProvider.class);
var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var phaseScanner = new PhaseScanner(acProvider, mock(ParticipantSyncPublisher.class),
mock(AutomationCompositionStateChangePublisher.class), acDeployPublisher,
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
phaseScanner.scanWithPhase(automationComposition, serviceTemplate, new UpdateSync());
@@ -241,9 +247,10 @@ class PhaseScannerTest {
var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var phaseScanner = new PhaseScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup);
+ acStateChangePublisher, acDeployPublisher, acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
phaseScanner.scanWithPhase(automationComposition, serviceTemplate, new UpdateSync());
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java
index b422f13d3..c82969d47 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java
@@ -33,6 +33,7 @@ import java.util.UUID;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
@@ -69,8 +70,9 @@ class SimpleScannerTest {
docMessage.setStateChangeResult(StateChangeResult.FAILED);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
var result = simpleScanner.scanMessage(automationComposition, docMessage);
assertTrue(result.isUpdated());
assertTrue(result.isToBeSync());
@@ -93,8 +95,9 @@ class SimpleScannerTest {
docMessage.setLockState(LockState.LOCKED);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
// wrong MessageType
docMessage.setMessageType(ParticipantMessageType.PARTICIPANT_PRIME_ACK);
@@ -128,8 +131,9 @@ class SimpleScannerTest {
docMessage.setOutProperties(Map.of("key", "value"));
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
var result = simpleScanner.scanMessage(automationComposition, docMessage);
assertTrue(result.isUpdated());
assertTrue(result.isToBeSync());
@@ -150,8 +154,9 @@ class SimpleScannerTest {
docMessage.setLockState(LockState.LOCKED);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var acProvider = mock(AutomationCompositionProvider.class);
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
var result = simpleScanner.scanMessage(automationComposition, docMessage);
assertTrue(result.isUpdated());
assertFalse(result.isToBeSync());
@@ -234,8 +239,9 @@ class SimpleScannerTest {
automationComposition.setLastMsg(TimestampHelper.now());
var acProvider = mock(AutomationCompositionProvider.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
- acRuntimeParameterGroup);
+ acRuntimeParameterGroup, encryptionUtils);
simpleScanner.simpleScan(automationComposition, new UpdateSync());
verify(acProvider, times(0)).updateAutomationComposition(any());
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java
index 1cff25fe6..077580ded 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java
@@ -34,6 +34,7 @@ import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
@@ -70,8 +71,9 @@ class StageScannerTest {
when(acProvider.updateAutomationComposition(any())).thenReturn(automationComposition);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
var supervisionScanner = new StageScanner(acProvider, mock(ParticipantSyncPublisher.class),
- mock(AutomationCompositionMigrationPublisher.class), acRuntimeParameterGroup);
+ mock(AutomationCompositionMigrationPublisher.class), acRuntimeParameterGroup, encryptionUtils);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
supervisionScanner.scanStage(automationComposition, serviceTemplate, new UpdateSync());
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java
index c3b5ff919..0392596ce 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2025 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -165,4 +165,16 @@ public class CommonTestData {
return acRuntimeParameterGroup;
}
+ /**
+ * Create a new Test parameter group for Encryption.
+ *
+ * @return a new AutomationCompositionDefinition
+ */
+ public static AcRuntimeParameterGroup getEncryptionParamaterGroup() {
+ var acRuntimeParameterGroup = getTestParamaterGroup();
+ acRuntimeParameterGroup.getAcmParameters().setSalt("randomSalt");
+ acRuntimeParameterGroup.getAcmParameters().setPassPhrase("randomPhrase");
+ return acRuntimeParameterGroup;
+ }
+
}
diff --git a/runtime-acm/src/test/resources/providers/AcDefinitionEncryptTest.yaml b/runtime-acm/src/test/resources/providers/AcDefinitionEncryptTest.yaml
new file mode 100644
index 000000000..0e9372876
--- /dev/null
+++ b/runtime-acm/src/test/resources/providers/AcDefinitionEncryptTest.yaml
@@ -0,0 +1,160 @@
+# ============LICENSE_START=======================================================
+# Copyright (C) 2025 Nordix Foundation.
+# ================================================================================
+# Licensed 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+tosca_definitions_version: tosca_simple_yaml_1_3
+name: Migration-From
+data_types:
+ onap.datatypes.ToscaConceptIdentifier:
+ derived_from: tosca.datatypes.Root
+ properties:
+ name:
+ type: string
+ required: true
+ version:
+ type: string
+ required: true
+
+node_types:
+ org.onap.policy.clamp.acm.Participant:
+ version: 1.0.1
+ derived_from: tosca.nodetypes.Root
+ properties:
+ provider:
+ type: string
+ required: false
+ org.onap.policy.clamp.acm.AutomationCompositionElement:
+ version: 1.0.1
+ derived_from: tosca.nodetypes.Root
+ properties:
+ provider:
+ type: string
+ required: false
+ metadata:
+ common: true
+ description: Specifies the organization that provides the automation composition element
+ startPhase:
+ type: integer
+ required: false
+ constraints:
+ - greater_or_equal: 0
+ metadata:
+ common: true
+ description: A value indicating the start phase in which this automation composition element will be started, the
+ first start phase is zero. Automation Composition Elements are started in their start_phase order and stopped
+ in reverse start phase order. Automation Composition Elements with the same start phase are started and
+ stopped simultaneously
+ stage:
+ type: list
+ description: A list indicating the stages in which this automation composition element will be started, the
+ first stage is zero. Automation Composition Elements are started in their stage order.
+ Automation Composition Elements with the same stage are started simultaneously.
+
+ org.onap.policy.clamp.acm.AutomationComposition:
+ version: 1.0.1
+ derived_from: tosca.nodetypes.Root
+ properties:
+ provider:
+ type: string
+ required: false
+ metadata:
+ common: true
+ description: Specifies the organization that provides the automation composition element
+ elements:
+ type: list
+ required: true
+ metadata:
+ common: true
+ entry_schema:
+ type: onap.datatypes.ToscaConceptIdentifier
+ description: Specifies a list of automation composition element definitions that make up this automation composition definition
+
+ org.onap.policy.clamp.acm.SimAutomationCompositionElement:
+ version: 1.0.0
+ derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement
+ properties:
+ password:
+ type: String
+ metadata:
+ sensitive: true
+ credential:
+ type: String
+ metadata:
+ sensitive: true
+ baseUrl:
+ type: string
+ required: true
+ description: The base URL to be prepended to each path, identifies the host for the REST endpoints.
+ httpHeaders:
+ type: map
+ required: false
+ entry_schema:
+ type: string
+ description: HTTP headers to send on REST requests
+ configurationEntities:
+ type: map
+ required: true
+ entry_schema:
+ type: map
+ metadata:
+ sensitive: true
+ description: The configuration entities the Automation Composition Element is managing and their associated REST requests
+
+
+topology_template:
+
+ node_templates:
+
+ org.onap.policy.clamp.acm.SimParticipant:
+ version: 2.3.4
+ type: org.onap.policy.clamp.acm.Participant
+ type_version: 1.0.1
+ description: Participant Simulator
+ properties:
+ provider: ONAP
+
+ onap.policy.clamp.ac.element.Sim_StarterAutomationCompositionElement:
+ version: 1.2.3
+ type: org.onap.policy.clamp.acm.SimAutomationCompositionElement
+ type_version: 1.0.0
+ description: Automation composition element for the http requests of AC Element Starter microservice
+ properties:
+ provider: ONAP
+ startPhase: 0
+ stage: [1,2]
+
+ onap.policy.clamp.ac.element.Sim_BridgeAutomationCompositionElement:
+ version: 1.2.3
+ type: org.onap.policy.clamp.acm.SimAutomationCompositionElement
+ type_version: 1.0.0
+ description: Automation composition element for the http requests of AC Element Bridge microservice
+ properties:
+ provider: ONAP
+ startPhase: 0
+ stage: [0,1]
+
+ onap.policy.clamp.ac.element.AutomationCompositionDefinition:
+ version: 1.2.3
+ type: org.onap.policy.clamp.acm.AutomationComposition
+ type_version: 1.0.1
+ description: Automation composition for Demo
+ properties:
+ provider: ONAP
+ elements:
+ - name: onap.policy.clamp.ac.element.Sim_StarterAutomationCompositionElement
+ version: 1.2.3
+ - name: onap.policy.clamp.ac.element.Sim_BridgeAutomationCompositionElement
+ version: 1.2.3 \ No newline at end of file
diff --git a/runtime-acm/src/test/resources/providers/AcInstantiateEncryptTest.json b/runtime-acm/src/test/resources/providers/AcInstantiateEncryptTest.json
new file mode 100644
index 000000000..acf2a9b16
--- /dev/null
+++ b/runtime-acm/src/test/resources/providers/AcInstantiateEncryptTest.json
@@ -0,0 +1,84 @@
+{
+ "name": "Instance-Migration-From",
+ "version": "1.0.1",
+ "compositionId": "709c62b3-8918-41b9-a747-d21eb79c6c40",
+ "description": "Demo automation composition instance 0",
+ "elements": {
+ "709c62b3-8918-41b9-a747-d21eb79c6c34": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c34",
+ "definition": {
+ "name": "onap.policy.clamp.ac.element.Sim_StarterAutomationCompositionElement",
+ "version": "1.2.3"
+ },
+ "description": "Starter Automation Composition Element for the Demo",
+ "properties": {
+ "credential": "mycred1",
+ "password": "mypass1",
+ "baseUrl": "http://address:30800",
+ "httpHeaders": {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YWNtVXNlcjp6YiFYenRHMzQ="
+ },
+ "configurationEntities": [
+ {
+ "configurationEntityId": {
+ "name": "onap.policy.clamp.ac.starter",
+ "version": "1.0.0"
+ },
+ "restSequence": [
+ {
+ "restRequestId": {
+ "name": "request1",
+ "version": "1.0.1"
+ },
+ "httpMethod": "POST",
+ "path": "/onap/policy/clamp/acelement/v2/activate",
+ "body": "{ \"receiverId\": { \"name\": \"onap.policy.clamp.ac.startertobridge\", \"version\": \"1.0.0\" }, \"timerMs\": 20000, \"elementType\": \"STARTER\", \"topicParameterGroup\": { \"server\": \"message-router:3904\", \"listenerTopic\": \"POLICY_UPDATE_MSG\", \"publisherTopic\": \"AC_ELEMENT_MSG\", \"fetchTimeout\": 15000, \"topicCommInfrastructure\": \"dmaap\" } }",
+ "expectedResponse": 201
+ }
+ ],
+ "myParameterToUpdate": "text1"
+ }
+ ]
+ }
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c35": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c35",
+ "definition": {
+ "name": "onap.policy.clamp.ac.element.Sim_BridgeAutomationCompositionElement",
+ "version": "1.2.3"
+ },
+ "description": "Bridge Automation Composition Element for the Demo",
+ "properties": {
+ "baseUrl": "http://address:30801",
+ "password": "mypass2",
+ "credential": "mycred2",
+ "httpHeaders": {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YWNtVXNlcjp6YiFYenRHMzQ="
+ },
+ "configurationEntities": [
+ {
+ "configurationEntityId": {
+ "name": "onap.policy.clamp.ac.bridge",
+ "version": "1.0.0"
+ },
+ "restSequence": [
+ {
+ "restRequestId": {
+ "name": "request2",
+ "version": "1.0.1"
+ },
+ "httpMethod": "POST",
+ "path": "/onap/policy/clamp/acelement/v2/activate",
+ "body": "{ \"receiverId\": { \"name\": \"onap.policy.clamp.ac.bridgetosink\", \"version\": \"1.0.0\" }, \"timerMs\": 20000, \"elementType\": \"BRIDGE\", \"topicParameterGroup\": { \"server\": \"message-router:3904\", \"listenerTopic\": \"POLICY_UPDATE_MSG\", \"publisherTopic\": \"AC_ELEMENT_MSG\", \"fetchTimeout\": 15000, \"topicCommInfrastructure\": \"dmaap\" } }",
+ "expectedResponse": 201
+ }
+ ],
+ "myParameterToUpdate": "text2"
+ }
+ ]
+ }
+ }
+ }
+} \ No newline at end of file