diff options
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 |