diff options
Diffstat (limited to 'models')
8 files changed, 427 insertions, 332 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/commissioning/CommissioningResponse.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/commissioning/CommissioningResponse.java index 42ce79843..9f6736d32 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/commissioning/CommissioningResponse.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/commissioning/CommissioningResponse.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ package org.onap.policy.clamp.models.acm.messages.rest.commissioning; import java.util.List; +import java.util.UUID; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -34,5 +35,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @Setter @ToString(callSuper = true) public class CommissioningResponse extends SimpleResponse { + private UUID compositionId; + private List<ToscaConceptIdentifier> affectedAutomationCompositionDefinitions; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java new file mode 100644 index 000000000..5740207c7 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2022 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.models.acm.persistence.provider; + +import java.util.List; +import java.util.UUID; +import javax.ws.rs.core.Response; +import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository; +import org.onap.policy.clamp.models.acm.persistence.repository.ToscaServiceTemplateRepository; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class AcDefinitionProvider { + + private final ToscaServiceTemplateRepository serviceTemplateRepository; + private final AutomationCompositionDefinitionRepository acmDefinitionRepository; + + /** + * Create Automation Composition Definition. + * + * @param serviceTemplate the service template to be created + * @return the created ACM Definition + */ + public AutomationCompositionDefinition createAutomationCompositionDefinition( + final ToscaServiceTemplate serviceTemplate) { + var acmDefinition = new AutomationCompositionDefinition(); + acmDefinition.setCompositionId(UUID.randomUUID()); + acmDefinition.setServiceTemplate(serviceTemplate); + var result = acmDefinitionRepository.save(new JpaAutomationCompositionDefinition(acmDefinition)); + return result.toAuthorative(); + } + + /** + * Update the ServiceTemplate. + * + * @param compositionId The UUID of the automation composition definition to delete + * @param serviceTemplate the service template to be created + */ + public void updateServiceTemplate(UUID compositionId, ToscaServiceTemplate serviceTemplate) { + var jpaServiceTemplate = + ProviderUtils.getJpaAndValidate(serviceTemplate, JpaToscaServiceTemplate::new, "toscaServiceTemplate"); + serviceTemplateRepository.save(jpaServiceTemplate); + } + + /** + * Delete Automation Composition Definition. + * + * @param compositionId The UUID of the automation composition definition to delete + * @return the TOSCA service template that was deleted + */ + public ToscaServiceTemplate deleteAcDefintion(UUID compositionId) { + var jpaDelete = acmDefinitionRepository.findById(compositionId.toString()); + if (jpaDelete.isEmpty()) { + String errorMessage = "delete of Automation Composition Definition \"" + compositionId + + "\" failed, Automation Composition Definition does not exist"; + throw new PfModelRuntimeException(Response.Status.NOT_FOUND, errorMessage); + } + + var item = jpaDelete.get().getServiceTemplate(); + serviceTemplateRepository.deleteById(item.getKey()); + acmDefinitionRepository.deleteById(compositionId.toString()); + return item.toAuthorative(); + } + + /** + * Get the requested automation composition definitions. + * + * @param compositionId The UUID of the automation composition definition to delete + * @return the automation composition definition + */ + @Transactional(readOnly = true) + public ToscaServiceTemplate getAcDefinition(UUID compositionId) { + var jpaGet = acmDefinitionRepository.findById(compositionId.toString()); + if (jpaGet.isEmpty()) { + String errorMessage = + "Get serviceTemplate \"" + compositionId + "\" failed, serviceTemplate does not exist"; + throw new PfModelRuntimeException(Response.Status.NOT_FOUND, errorMessage); + } + return jpaGet.get().getServiceTemplate().toAuthorative(); + } + + /** + * Get service templates. + * + * @return the topology templates found + */ + @Transactional(readOnly = true) + public List<ToscaServiceTemplate> getAllServiceTemplates() { + var jpaList = serviceTemplateRepository.findAll(); + return ProviderUtils.asEntityList(jpaList); + } + + /** + * Get service templates. + * + * @param name the name of the topology template to get, set to null to get all service templates + * @param version the version of the service template to get, set to null to get all service templates + * @return the topology templates found + */ + @Transactional(readOnly = true) + public List<ToscaServiceTemplate> getServiceTemplateList(final String name, final String version) { + var jpaList = serviceTemplateRepository.getFiltered(JpaToscaServiceTemplate.class, name, version); + return ProviderUtils.asEntityList(jpaList); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index 5ee7d02f6..c4f8b91e7 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ @@ -189,7 +189,7 @@ public class AutomationCompositionProvider { if (jpaDeleteAutomationComposition.isEmpty()) { String errorMessage = "delete of automation composition \"" + automationCompositionKey.getId() + "\" failed, automation composition does not exist"; - throw new PfModelException(Response.Status.BAD_REQUEST, errorMessage); + throw new PfModelException(Response.Status.NOT_FOUND, errorMessage); } automationCompositionRepository.deleteById(automationCompositionKey); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java index 1f9e07f8e..6e3b56d56 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,10 +51,9 @@ public class ParticipantProvider { * @param name the name of the participant to get, null to get all participants * @param version the version of the participant to get, null to get all participants * @return the participants found - * @throws PfModelException on errors getting participants */ @Transactional(readOnly = true) - public List<Participant> getParticipants(final String name, final String version) throws PfModelException { + public List<Participant> getParticipants(final String name, final String version) { return ProviderUtils.asEntityList(participantRepository.getFiltered(JpaParticipant.class, name, version)); } @@ -63,10 +62,9 @@ public class ParticipantProvider { * Get all participants. * * @return the participants found - * @throws PfModelException on errors getting policies */ @Transactional(readOnly = true) - public List<Participant> getParticipants() throws PfModelException { + public List<Participant> getParticipants() { return ProviderUtils.asEntityList(participantRepository.findAll()); } @@ -93,11 +91,9 @@ public class ParticipantProvider { * * @param filter the filter for the participants to get * @return the participants found - * @throws PfModelException on errors getting policies */ @Transactional(readOnly = true) - public List<Participant> getFilteredParticipants(@NonNull final ToscaTypedEntityFilter<Participant> filter) - throws PfModelException { + public List<Participant> getFilteredParticipants(@NonNull final ToscaTypedEntityFilter<Participant> filter) { return filter.filter(ProviderUtils.asEntityList( participantRepository.getFiltered(JpaParticipant.class, filter.getName(), filter.getVersion()))); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java deleted file mode 100644 index 4661c74c7..000000000 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProvider.java +++ /dev/null @@ -1,230 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 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.models.acm.persistence.provider; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import lombok.RequiredArgsConstructor; -import org.onap.policy.clamp.models.acm.persistence.repository.ToscaServiceTemplateRepository; -import org.onap.policy.models.base.PfConceptKey; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; -import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class ServiceTemplateProvider { - - private final ToscaServiceTemplateRepository serviceTemplateRepository; - - /** - * Create service template. - * - * @param serviceTemplate the service template to be created - * @return the created service template - * @throws PfModelException on errors creating the service template - */ - public ToscaServiceTemplate createServiceTemplate(final ToscaServiceTemplate serviceTemplate) - throws PfModelException { - try { - var result = serviceTemplateRepository.save(ProviderUtils.getJpaAndValidate(serviceTemplate, - JpaToscaServiceTemplate::new, "toscaServiceTemplate")); - return result.toAuthorative(); - } catch (IllegalArgumentException e) { - throw new PfModelException(Status.BAD_REQUEST, "Error in save serviceTemplate", e); - } - } - - /** - * Delete service template. - * - * @param name the name of the service template to delete. - * @param version the version of the service template to delete. - * @return the TOSCA service template that was deleted - * @throws PfModelException on errors deleting policy types - */ - public ToscaServiceTemplate deleteServiceTemplate(final String name, final String version) throws PfModelException { - var serviceTemplateKey = new PfConceptKey(name, version); - var jpaDelete = serviceTemplateRepository.findById(serviceTemplateKey); - if (jpaDelete.isEmpty()) { - String errorMessage = "delete of serviceTemplate \"" + serviceTemplateKey.getId() - + "\" failed, serviceTemplate does not exist"; - throw new PfModelException(Response.Status.BAD_REQUEST, errorMessage); - } - serviceTemplateRepository.deleteById(serviceTemplateKey); - return jpaDelete.get().toAuthorative(); - } - - /** - * Get the requested automation composition definitions. - * - * @param name the name of the definition to get, null for all definitions - * @param version the version of the definition to get, null for all definitions - * @return the automation composition definitions - * @throws PfModelException on errors getting automation composition definitions - */ - @Transactional(readOnly = true) - public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException { - var serviceTemplateKey = new PfConceptKey(name, version); - var jpaServiceTemplates = serviceTemplateRepository.findById(serviceTemplateKey); - if (jpaServiceTemplates.isEmpty()) { - throw new PfModelException(Status.NOT_FOUND, "Automation composition definitions not found"); - } - return jpaServiceTemplates.get().toAuthorative(); - } - - /** - * Get service templates. - * - * @return the topology templates found - * @throws PfModelException on errors getting service templates - */ - @Transactional(readOnly = true) - public List<ToscaServiceTemplate> getAllServiceTemplates() throws PfModelException { - var jpaList = serviceTemplateRepository.findAll(); - return ProviderUtils.asEntityList(jpaList); - } - - /** - * Get service templates. - * - * @param name the name of the topology template to get, set to null to get all service templates - * @param version the version of the service template to get, set to null to get all service templates - * @return the topology templates found - * @throws PfModelException on errors getting service templates - */ - @Transactional(readOnly = true) - public List<ToscaServiceTemplate> getServiceTemplateList(final String name, final String version) - throws PfModelException { - var jpaList = serviceTemplateRepository.getFiltered(JpaToscaServiceTemplate.class, name, version); - return ProviderUtils.asEntityList(jpaList); - } - - /** - * Get the initial node types with common or instance properties. - * - * @param fullNodeTypes map of all the node types in the specified template - * @param common boolean to indicate whether common or instance properties are required - * @return node types map that only has common properties - */ - private Map<String, ToscaNodeType> getInitialNodeTypesMap(Map<String, ToscaNodeType> fullNodeTypes, - boolean common) { - - var tempNodeTypesMap = new HashMap<String, ToscaNodeType>(); - - fullNodeTypes.forEach((key, nodeType) -> { - var tempToscaNodeType = new ToscaNodeType(); - tempToscaNodeType.setName(key); - - var resultantPropertyMap = findCommonOrInstancePropsInNodeTypes(nodeType, common); - - if (!resultantPropertyMap.isEmpty()) { - tempToscaNodeType.setProperties(resultantPropertyMap); - tempNodeTypesMap.put(key, tempToscaNodeType); - } - }); - return tempNodeTypesMap; - } - - private Map<String, ToscaProperty> findCommonOrInstancePropsInNodeTypes(ToscaNodeType nodeType, boolean common) { - - var tempCommonPropertyMap = new HashMap<String, ToscaProperty>(); - var tempInstancePropertyMap = new HashMap<String, ToscaProperty>(); - - nodeType.getProperties().forEach((propKey, prop) -> { - - if (prop.getMetadata() != null) { - prop.getMetadata().forEach((k, v) -> { - if (k.equals("common") && v.equals("true") && common) { - tempCommonPropertyMap.put(propKey, prop); - } else if (k.equals("common") && v.equals("false") && !common) { - tempInstancePropertyMap.put(propKey, prop); - } - - }); - } else { - tempInstancePropertyMap.put(propKey, prop); - } - }); - - if (tempCommonPropertyMap.isEmpty() && !common) { - return tempInstancePropertyMap; - } else { - return tempCommonPropertyMap; - } - } - - /** - * Get the node types derived from those that have common properties. - * - * @param initialNodeTypes map of all the node types in the specified template - * @param filteredNodeTypes map of all the node types that have common or instance properties - * @return all node types that have common properties including their children - * @throws PfModelException on errors getting node type with common properties - */ - private Map<String, ToscaNodeType> getFinalNodeTypesMap(Map<String, ToscaNodeType> initialNodeTypes, - Map<String, ToscaNodeType> filteredNodeTypes) { - for (var i = 0; i < initialNodeTypes.size(); i++) { - initialNodeTypes.forEach((key, nodeType) -> { - var tempToscaNodeType = new ToscaNodeType(); - tempToscaNodeType.setName(key); - - if (filteredNodeTypes.get(nodeType.getDerivedFrom()) != null) { - tempToscaNodeType.setName(key); - - var finalProps = new HashMap<String, ToscaProperty>( - filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties()); - - tempToscaNodeType.setProperties(finalProps); - } else { - return; - } - filteredNodeTypes.putIfAbsent(key, tempToscaNodeType); - - }); - } - return filteredNodeTypes; - } - - /** - * Get the requested node types with common or instance properties. - * - * @param common boolean indicating common or instance properties - * @param serviceTemplate the ToscaServiceTemplate - * @return the node types with common or instance properties - * @throws PfModelException on errors getting node type properties - */ - public Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common, - ToscaServiceTemplate serviceTemplate) throws PfModelException { - var tempNodeTypesMap = this.getInitialNodeTypesMap(serviceTemplate.getNodeTypes(), common); - - return this.getFinalNodeTypesMap(serviceTemplate.getNodeTypes(), tempNodeTypesMap); - - } -} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index f54ecb441..283edd49e 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -21,15 +21,31 @@ package org.onap.policy.clamp.models.acm.utils; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ObjectValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; @@ -37,11 +53,11 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; * Utility functions used in acm-runtime and participants. * */ -public class AcmUtils { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class AcmUtils { - private AcmUtils() { - throw new IllegalStateException("Utility class"); - } + private static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; + public static final String ENTRY = "entry "; /** * Prepare participant updates map. @@ -50,7 +66,7 @@ public class AcmUtils { * @param participantUpdates list of participantUpdates */ public static void prepareParticipantUpdate(AutomationCompositionElement acElement, - List<ParticipantUpdates> participantUpdates) { + List<ParticipantUpdates> participantUpdates) { if (participantUpdates.isEmpty()) { participantUpdates.add(getAutomationCompositionElementList(acElement)); return; @@ -81,11 +97,11 @@ public class AcmUtils { * @param acElement automation composition element * @param toscaServiceTemplate ToscaServiceTemplate */ - public static void setServiceTemplatePolicyInfo(AutomationCompositionElement acElement, - ToscaServiceTemplate toscaServiceTemplate) { + public static void setAcPolicyInfo(AutomationCompositionElement acElement, + ToscaServiceTemplate toscaServiceTemplate) { // Pass respective PolicyTypes or Policies as part of toscaServiceTemplateFragment if (toscaServiceTemplate.getPolicyTypes() == null - && toscaServiceTemplate.getToscaTopologyTemplate().getPolicies() == null) { + && toscaServiceTemplate.getToscaTopologyTemplate().getPolicies() == null) { return; } ToscaServiceTemplate toscaServiceTemplateFragment = new ToscaServiceTemplate(); @@ -107,8 +123,8 @@ public class AcmUtils { * @param commonPropertiesMap common properties map */ public static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier acParticipantType, String entryKey, - ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates, - Map<String, ToscaNodeType> commonPropertiesMap) { + ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates, + Map<String, ToscaNodeType> commonPropertiesMap) { var acDefinition = new AutomationCompositionElementDefinition(); acDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier(entryKey, entryValue.getVersion())); @@ -123,8 +139,8 @@ public class AcmUtils { List<AutomationCompositionElementDefinition> automationCompositionElementDefinitionList = new ArrayList<>(); if (participantDefinitionUpdates.isEmpty()) { - participantDefinitionUpdates.add( - getParticipantDefinition(acDefinition, acParticipantType, automationCompositionElementDefinitionList)); + participantDefinitionUpdates.add(getParticipantDefinition(acDefinition, acParticipantType, + automationCompositionElementDefinitionList)); } else { var participantExists = false; for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) { @@ -135,18 +151,207 @@ public class AcmUtils { } if (!participantExists) { participantDefinitionUpdates.add(getParticipantDefinition(acDefinition, acParticipantType, - automationCompositionElementDefinitionList)); + automationCompositionElementDefinitionList)); } } } private static ParticipantDefinition getParticipantDefinition(AutomationCompositionElementDefinition acDefinition, - ToscaConceptIdentifier acParticipantType, - List<AutomationCompositionElementDefinition> automationCompositionElementDefinitionList) { + ToscaConceptIdentifier acParticipantType, + List<AutomationCompositionElementDefinition> automationCompositionElementDefinitionList) { var participantDefinition = new ParticipantDefinition(); participantDefinition.setParticipantType(acParticipantType); automationCompositionElementDefinitionList.add(acDefinition); participantDefinition.setAutomationCompositionElementDefinitionList(automationCompositionElementDefinitionList); return participantDefinition; } + + /** + * Validate AutomationComposition. + * + * @param automationComposition AutomationComposition to validate + * @param serviceTemplate the service template + * @return the result of validation + */ + public static BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, + ToscaServiceTemplate serviceTemplate) { + var result = new BeanValidationResult(ENTRY + automationComposition.getDefinition().getName(), + automationComposition); + + var map = getMapToscaNodeTemplates(serviceTemplate); + + var toscaNodeTemplate = map.get(new ToscaConceptIdentifier(automationComposition.getDefinition().getName(), + automationComposition.getDefinition().getVersion())); + + if (toscaNodeTemplate == null || !AUTOMATION_COMPOSITION_NODE_TYPE.equals(toscaNodeTemplate.getType())) { + result.addResult( + new ObjectValidationResult("AutomationComposition", automationComposition.getDefinition().getName(), + ValidationStatus.INVALID, "Commissioned automation composition definition not found")); + } else { + + var acElementDefinitions = getAutomationCompositionElementDefinitions(map, toscaNodeTemplate); + + // @formatter:off + var definitions = acElementDefinitions + .stream() + .map(nodeTemplate -> nodeTemplate.getKey().asIdentifier()) + .collect(Collectors.toMap(ToscaConceptIdentifier::getName, UnaryOperator.identity())); + // @formatter:on + + for (var element : automationComposition.getElements().values()) { + result.addResult(validateDefinition(definitions, element.getDefinition())); + } + } + + return result; + + } + + private static ValidationResult validateDefinition(Map<String, ToscaConceptIdentifier> definitions, + ToscaConceptIdentifier definition) { + var result = new BeanValidationResult(ENTRY + definition.getName(), definition); + var identifier = definitions.get(definition.getName()); + if (identifier == null) { + result.setResult(ValidationStatus.INVALID, "Not found"); + } else if (!identifier.equals(definition)) { + result.setResult(ValidationStatus.INVALID, "Version not matching"); + } + return (result.isClean() ? null : result); + } + + private static Map<ToscaConceptIdentifier, ToscaNodeTemplate> getMapToscaNodeTemplates( + ToscaServiceTemplate serviceTemplate) { + if (serviceTemplate.getToscaTopologyTemplate() == null + || MapUtils.isEmpty(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates())) { + return Map.of(); + } + var list = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values(); + return list.stream().collect(Collectors + .toMap(node -> new ToscaConceptIdentifier(node.getName(), node.getVersion()), Function.identity())); + } + + private static List<ToscaNodeTemplate> getAutomationCompositionElementDefinitions( + Map<ToscaConceptIdentifier, ToscaNodeTemplate> map, ToscaNodeTemplate automationCompositionNodeTemplate) { + + if (MapUtils.isEmpty(automationCompositionNodeTemplate.getProperties())) { + return Collections.emptyList(); + } + + @SuppressWarnings("unchecked") + var automationCompositionElements = + (List<Map<String, String>>) automationCompositionNodeTemplate.getProperties().get("elements"); + + if (CollectionUtils.isEmpty(automationCompositionElements)) { + return Collections.emptyList(); + } + + // @formatter:off + return automationCompositionElements + .stream() + .map(elementMap -> + map.get(new ToscaConceptIdentifier(elementMap.get("name"), elementMap.get("version")))) + .collect(Collectors.toList()); + // @formatter:on + } + + /** + * Get the initial node types with common or instance properties. + * + * @param fullNodeTypes map of all the node types in the specified template + * @param common boolean to indicate whether common or instance properties are required + * @return node types map that only has common properties + */ + private static Map<String, ToscaNodeType> getInitialNodeTypesMap(Map<String, ToscaNodeType> fullNodeTypes, + boolean common) { + + var tempNodeTypesMap = new HashMap<String, ToscaNodeType>(); + + fullNodeTypes.forEach((key, nodeType) -> { + var tempToscaNodeType = new ToscaNodeType(); + tempToscaNodeType.setName(key); + + var resultantPropertyMap = findCommonOrInstancePropsInNodeTypes(nodeType, common); + + if (!resultantPropertyMap.isEmpty()) { + tempToscaNodeType.setProperties(resultantPropertyMap); + tempNodeTypesMap.put(key, tempToscaNodeType); + } + }); + return tempNodeTypesMap; + } + + private static Map<String, ToscaProperty> findCommonOrInstancePropsInNodeTypes(ToscaNodeType nodeType, + boolean common) { + + var tempCommonPropertyMap = new HashMap<String, ToscaProperty>(); + var tempInstancePropertyMap = new HashMap<String, ToscaProperty>(); + + nodeType.getProperties().forEach((propKey, prop) -> { + + if (prop.getMetadata() != null) { + prop.getMetadata().forEach((k, v) -> { + if (k.equals("common") && v.equals("true") && common) { + tempCommonPropertyMap.put(propKey, prop); + } else if (k.equals("common") && v.equals("false") && !common) { + tempInstancePropertyMap.put(propKey, prop); + } + + }); + } else { + tempInstancePropertyMap.put(propKey, prop); + } + }); + + if (tempCommonPropertyMap.isEmpty() && !common) { + return tempInstancePropertyMap; + } else { + return tempCommonPropertyMap; + } + } + + /** + * Get the node types derived from those that have common properties. + * + * @param initialNodeTypes map of all the node types in the specified template + * @param filteredNodeTypes map of all the node types that have common or instance properties + * @return all node types that have common properties including their children + * @throws PfModelException on errors getting node type with common properties + */ + private static Map<String, ToscaNodeType> getFinalNodeTypesMap(Map<String, ToscaNodeType> initialNodeTypes, + Map<String, ToscaNodeType> filteredNodeTypes) { + for (var i = 0; i < initialNodeTypes.size(); i++) { + initialNodeTypes.forEach((key, nodeType) -> { + var tempToscaNodeType = new ToscaNodeType(); + tempToscaNodeType.setName(key); + + if (filteredNodeTypes.get(nodeType.getDerivedFrom()) != null) { + tempToscaNodeType.setName(key); + + var finalProps = new HashMap<String, ToscaProperty>( + filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties()); + + tempToscaNodeType.setProperties(finalProps); + } else { + return; + } + filteredNodeTypes.putIfAbsent(key, tempToscaNodeType); + + }); + } + return filteredNodeTypes; + } + + /** + * Get the requested node types with common or instance properties. + * + * @param common boolean indicating common or instance properties + * @param serviceTemplate the ToscaServiceTemplate + * @return the node types with common or instance properties + */ + public static Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common, + ToscaServiceTemplate serviceTemplate) { + var tempNodeTypesMap = getInitialNodeTypesMap(serviceTemplate.getNodeTypes(), common); + + return getFinalNodeTypesMap(serviceTemplate.getNodeTypes(), tempNodeTypesMap); + } } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java index 9e4133da5..2c01e9887 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ServiceTemplateProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java @@ -22,7 +22,6 @@ package org.onap.policy.clamp.models.acm.persistence.provider; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -30,18 +29,21 @@ import static org.mockito.Mockito.when; import java.util.List; import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository; import org.onap.policy.clamp.models.acm.persistence.repository.ToscaServiceTemplateRepository; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardYamlCoder; import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; -class ServiceTemplateProviderTest { +class AcDefinitionProviderTest { private static final String TOSCA_SERVICE_TEMPLATE_YAML = "clamp/acm/pmsh/funtional-pmsh-usecase.yaml"; @@ -55,97 +57,69 @@ class ServiceTemplateProviderTest { } @Test - void testGetCommonOrInstancePropertiesFromNodeTypes() throws PfModelException { - var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - - var result = serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(true, inputServiceTemplate); - assertNotNull(result); - assertThat(result).hasSize(6); - } - - @Test void testCreateServiceTemplate() throws PfModelException { - var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); var jpaServiceTemplate = ProviderUtils.getJpaAndValidate(inputServiceTemplate, JpaToscaServiceTemplate::new, - "toscaServiceTemplate"); - when(serviceTemplateRepository.save(jpaServiceTemplate)).thenReturn(jpaServiceTemplate); + "toscaServiceTemplate"); + var acmDefinition = new AutomationCompositionDefinition(); + acmDefinition.setCompositionId(UUID.randomUUID()); + acmDefinition.setServiceTemplate(jpaServiceTemplate.toAuthorative()); - var result = serviceTemplateProvider.createServiceTemplate(inputServiceTemplate); + when(acmDefinitionRepository.save(any(JpaAutomationCompositionDefinition.class))) + .thenReturn(new JpaAutomationCompositionDefinition(acmDefinition)); - assertThat(result).isEqualTo(jpaServiceTemplate.toAuthorative()); - } - - @Test - void testDeleteServiceTemplate() throws PfModelException { - var jpaServiceTemplate = ProviderUtils.getJpaAndValidate(inputServiceTemplate, JpaToscaServiceTemplate::new, - "toscaServiceTemplate"); var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - when(serviceTemplateRepository - .findById(new PfConceptKey(inputServiceTemplate.getName(), inputServiceTemplate.getVersion()))) - .thenReturn(Optional.of(jpaServiceTemplate)); - - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - var result = serviceTemplateProvider.deleteServiceTemplate(inputServiceTemplate.getName(), - inputServiceTemplate.getVersion()); + var acDefinitionProvider = new AcDefinitionProvider(serviceTemplateRepository, acmDefinitionRepository); + var result = acDefinitionProvider.createAutomationCompositionDefinition(inputServiceTemplate); - assertThat(result).isEqualTo(jpaServiceTemplate.toAuthorative()); + assertThat(result.getServiceTemplate()).isEqualTo(jpaServiceTemplate.toAuthorative()); } @Test - void testDeleteServiceTemplateEmpty() throws PfModelException { + void testDeleteAcDefintion() throws PfModelException { var jpaServiceTemplate = ProviderUtils.getJpaAndValidate(inputServiceTemplate, JpaToscaServiceTemplate::new, - "toscaServiceTemplate"); - var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - when(serviceTemplateRepository - .findById(new PfConceptKey(inputServiceTemplate.getName(), inputServiceTemplate.getVersion()))) - .thenReturn(Optional.empty()); - - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - assertThatThrownBy(() -> serviceTemplateProvider.deleteServiceTemplate(inputServiceTemplate.getName(), - inputServiceTemplate.getVersion())) - .hasMessage("delete of serviceTemplate \"NULL:0.0.0\" failed, serviceTemplate does not exist"); - } + "toscaServiceTemplate"); + var acmDefinition = new AutomationCompositionDefinition(); + acmDefinition.setCompositionId(UUID.randomUUID()); + acmDefinition.setServiceTemplate(jpaServiceTemplate.toAuthorative()); - @Test - void testGetServiceTemplateListEmpty() { var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - when(serviceTemplateRepository.findById(any())).thenReturn(Optional.empty()); + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); + when(acmDefinitionRepository.findById(acmDefinition.getCompositionId().toString())) + .thenReturn(Optional.of(new JpaAutomationCompositionDefinition(acmDefinition))); + + var acDefinitionProvider = new AcDefinitionProvider(serviceTemplateRepository, acmDefinitionRepository); + var result = acDefinitionProvider.deleteAcDefintion(acmDefinition.getCompositionId()); - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - assertThatThrownBy(() -> serviceTemplateProvider.getToscaServiceTemplate("Name", "1.0.0")) - .hasMessage("Automation composition definitions not found"); + assertThat(result).isEqualTo(jpaServiceTemplate.toAuthorative()); } @Test - void testGetServiceTemplateList() throws PfModelException { - var jpaServiceTemplate = ProviderUtils.getJpaAndValidate(inputServiceTemplate, JpaToscaServiceTemplate::new, - "toscaServiceTemplate"); + void testDeleteServiceTemplateEmpty() throws PfModelException { var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); - when(serviceTemplateRepository - .findById(new PfConceptKey(inputServiceTemplate.getName(), inputServiceTemplate.getVersion()))) - .thenReturn(Optional.of(jpaServiceTemplate)); - - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - var result = serviceTemplateProvider.getToscaServiceTemplate(inputServiceTemplate.getName(), - inputServiceTemplate.getVersion()); - - assertThat(result).isEqualTo(jpaServiceTemplate.toAuthorative()); + when(serviceTemplateRepository.findAll()).thenReturn(List.of()); + + var compositionId = UUID.randomUUID(); + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); + var acDefinitionProvider = new AcDefinitionProvider(serviceTemplateRepository, acmDefinitionRepository); + assertThatThrownBy(() -> acDefinitionProvider.deleteAcDefintion(compositionId)) + .hasMessage("delete of Automation Composition Definition \"" + compositionId + + "\" failed, Automation Composition Definition does not exist"); } @Test void testGetServiceTemplate() throws PfModelException { var jpaServiceTemplate = ProviderUtils.getJpaAndValidate(inputServiceTemplate, JpaToscaServiceTemplate::new, - "toscaServiceTemplate"); + "toscaServiceTemplate"); var serviceTemplateRepository = mock(ToscaServiceTemplateRepository.class); when(serviceTemplateRepository.getFiltered(JpaToscaServiceTemplate.class, inputServiceTemplate.getName(), - inputServiceTemplate.getVersion())).thenReturn(List.of(jpaServiceTemplate)); + inputServiceTemplate.getVersion())).thenReturn(List.of(jpaServiceTemplate)); - var serviceTemplateProvider = new ServiceTemplateProvider(serviceTemplateRepository); - var result = serviceTemplateProvider.getServiceTemplateList(inputServiceTemplate.getName(), - inputServiceTemplate.getVersion()); + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); + var acDefinitionProvider = new AcDefinitionProvider(serviceTemplateRepository, acmDefinitionRepository); + var result = acDefinitionProvider.getServiceTemplateList(inputServiceTemplate.getName(), + inputServiceTemplate.getVersion()); assertThat(result).hasSize(1); assertThat(result.get(0)).isEqualTo(jpaServiceTemplate.toAuthorative()); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java index 0e68593c2..ccb4b8360 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java @@ -23,6 +23,7 @@ package org.onap.policy.clamp.models.acm.utils; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import java.util.ArrayList; @@ -34,6 +35,8 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; +import org.onap.policy.common.utils.coder.StandardYamlCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; @@ -46,7 +49,9 @@ class AcmUtilsTest { private final ToscaConceptIdentifier id = new ToscaConceptIdentifier("id", "1.0.0"); private final ToscaConceptIdentifier idNode = - new ToscaConceptIdentifier("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", "0.0.0"); + new ToscaConceptIdentifier("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", "0.0.0"); + private static final StandardYamlCoder YAML_TRANSLATOR = new StandardYamlCoder(); + private static final String TOSCA_SERVICE_TEMPLATE_YAML = "clamp/acm/pmsh/funtional-pmsh-usecase.yaml"; @Test void testCommonUtilsParticipantUpdate() { @@ -71,7 +76,7 @@ class AcmUtilsTest { void testCommonUtilsServiceTemplate() { var acElement = new AutomationCompositionElement(); var toscaServiceTemplate = getDummyToscaServiceTemplate(); - AcmUtils.setServiceTemplatePolicyInfo(acElement, toscaServiceTemplate); + AcmUtils.setAcPolicyInfo(acElement, toscaServiceTemplate); assertEquals(getDummyToscaDataTypeMap(), acElement.getToscaServiceTemplateFragment().getDataTypes()); } @@ -87,7 +92,7 @@ class AcmUtilsTest { checkParticipantDefinitionUpdate(toscaServiceTemplate, participantDefinitionUpdates); assertEquals(idNode, participantDefinitionUpdates.get(0).getAutomationCompositionElementDefinitionList().get(0) - .getAcElementDefinitionId()); + .getAcElementDefinitionId()); } @Test @@ -96,10 +101,20 @@ class AcmUtilsTest { toscaServiceTemplate.setPolicyTypes(null); toscaServiceTemplate.getToscaTopologyTemplate().setPolicies(null); AutomationCompositionElement acElement = new AutomationCompositionElement(); - AcmUtils.setServiceTemplatePolicyInfo(new AutomationCompositionElement(), toscaServiceTemplate); + AcmUtils.setAcPolicyInfo(new AutomationCompositionElement(), toscaServiceTemplate); assertNull(acElement.getToscaServiceTemplateFragment()); } + @Test + void testGetCommonOrInstancePropertiesFromNodeTypes() throws Exception { + var inputServiceTemplate = YAML_TRANSLATOR + .decode(ResourceUtils.getResourceAsStream(TOSCA_SERVICE_TEMPLATE_YAML), ToscaServiceTemplate.class); + + var result = AcmUtils.getCommonOrInstancePropertiesFromNodeTypes(true, inputServiceTemplate); + assertNotNull(result); + assertThat(result).hasSize(6); + } + private ToscaServiceTemplate getDummyToscaServiceTemplate() { var toscaServiceTemplate = new ToscaServiceTemplate(); var policyTypes = getDummyPolicyTypesMap(); @@ -146,14 +161,14 @@ class AcmUtilsTest { } private void checkParticipantDefinitionUpdate(ToscaServiceTemplate toscaServiceTemplate, - List<ParticipantDefinition> participantDefinitionUpdates) { + List<ParticipantDefinition> participantDefinitionUpdates) { for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() - .getNodeTemplates().entrySet()) { + .getNodeTemplates().entrySet()) { if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { + toscaServiceTemplate)) { AcmUtils.prepareParticipantDefinitionUpdate(id, toscaInputEntry.getKey(), toscaInputEntry.getValue(), - participantDefinitionUpdates, null); + participantDefinitionUpdates, null); } } } |