diff options
Diffstat (limited to 'runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java')
-rw-r--r-- | runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java | 637 |
1 files changed, 637 insertions, 0 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 new file mode 100644 index 000000000..39d84026b --- /dev/null +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -0,0 +1,637 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.instantiation; + +import com.google.gson.Gson; +import com.google.gson.internal.LinkedTreeMap; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import lombok.AllArgsConstructor; +import org.onap.policy.clamp.acm.runtime.commissioning.CommissioningProvider; +import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler; +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException; +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.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.messages.rest.GenericNameVersion; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AutomationCompositionOrderStateResponse; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AutomationCompositionPrimed; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AutomationCompositionPrimedResponse; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstancePropertiesResponse; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationCommand; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; +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.ToscaNameVersion; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * This class is dedicated to the Instantiation of Commissioned automation composition. + */ +@Service +@Transactional +@AllArgsConstructor +public class AutomationCompositionInstantiationProvider { + private static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; + private static final String AUTOMATION_COMPOSITION_NODE_ELEMENT_TYPE = "AutomationCompositionElement"; + private static final String PARTICIPANT_ID_PROPERTY_KEY = "participant_id"; + private static final String PARTICIPANT_TYPE_PROPERTY_KEY = "participantType"; + private static final String AC_ELEMENT_NAME = "name"; + private static final String AC_ELEMENT_VERSION = "version"; + private static final String INSTANCE_TEXT = "_Instance"; + + private static final Gson GSON = new Gson(); + + private final AutomationCompositionProvider automationCompositionProvider; + private final CommissioningProvider commissioningProvider; + private final SupervisionHandler supervisionHandler; + private final ParticipantProvider participantProvider; + private static final String ENTRY = "entry "; + + /** + * Creates Instance Properties and automation composition. + * + * @param serviceTemplate the service template + * @return the result of the instantiation operation + * @throws PfModelException on creation errors + */ + public InstancePropertiesResponse createInstanceProperties(ToscaServiceTemplate serviceTemplate) + throws PfModelException { + + String instanceName = generateSequentialInstanceName(); + AutomationComposition automationComposition = new AutomationComposition(); + Map<UUID, AutomationCompositionElement> automationCompositionElements = new HashMap<>(); + + ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getAllToscaServiceTemplate().get(0); + + Map<String, ToscaNodeTemplate> persistedNodeTemplateMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + + Map<String, ToscaNodeTemplate> nodeTemplates = deepCloneNodeTemplate(serviceTemplate); + + nodeTemplates.forEach((key, template) -> { + ToscaNodeTemplate newNodeTemplate = new ToscaNodeTemplate(); + String name = key + instanceName; + String version = template.getVersion(); + String description = template.getDescription() + instanceName; + newNodeTemplate.setName(name); + newNodeTemplate.setVersion(version); + newNodeTemplate.setDescription(description); + newNodeTemplate.setProperties(new HashMap<>(template.getProperties())); + newNodeTemplate.setType(template.getType()); + newNodeTemplate.setTypeVersion(template.getTypeVersion()); + newNodeTemplate.setMetadata(template.getMetadata()); + + crateNewAutomationCompositionInstance(instanceName, automationComposition, automationCompositionElements, + template, newNodeTemplate); + + persistedNodeTemplateMap.put(name, newNodeTemplate); + }); + + AutomationCompositions automationCompositions = new AutomationCompositions(); + + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().putAll(persistedNodeTemplateMap); + + automationComposition.setElements(automationCompositionElements); + automationCompositions.getAutomationCompositionList().add(automationComposition); + + return saveInstancePropertiesAndAutomationComposition(serviceTemplate, automationCompositions); + } + + /** + * Deletes Instance Properties. + * + * @param name the name of the automation composition to delete + * @param version the version of the automation composition to delete + * @return the result of the deletion + * @throws PfModelException on deletion errors + */ + public InstantiationResponse deleteInstanceProperties(String name, String version) throws PfModelException { + + String instanceName = getInstancePropertyName(name, version); + + Map<String, ToscaNodeTemplate> filteredToscaNodeTemplateMap = new HashMap<>(); + + ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getAllToscaServiceTemplate().get(0); + + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, nodeTemplate) -> { + if (!nodeTemplate.getName().contains(instanceName)) { + filteredToscaNodeTemplateMap.put(key, nodeTemplate); + } + }); + + List<ToscaNodeTemplate> filteredToscaNodeTemplateList = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().values().stream() + .filter(nodeTemplate -> nodeTemplate.getName().contains(instanceName)).collect(Collectors.toList()); + + InstantiationResponse response = this.deleteAutomationComposition(name, version); + + automationCompositionProvider.deleteInstanceProperties(filteredToscaNodeTemplateMap, + filteredToscaNodeTemplateList); + + return response; + } + + /** + * Create automation compositions. + * + * @param automationCompositions the automation composition + * @return the result of the instantiation operation + * @throws PfModelException on creation errors + */ + public InstantiationResponse createAutomationCompositions(AutomationCompositions automationCompositions) + throws PfModelException { + for (AutomationComposition automationComposition : automationCompositions.getAutomationCompositionList()) { + var checkAutomationCompositionOpt = + automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); + if (checkAutomationCompositionOpt.isPresent()) { + throw new PfModelException(Response.Status.BAD_REQUEST, + automationComposition.getKey().asIdentifier() + " already defined"); + } + } + BeanValidationResult validationResult = validateAutomationCompositions(automationCompositions); + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } + automationCompositionProvider.saveAutomationCompositions(automationCompositions.getAutomationCompositionList()); + + var response = new InstantiationResponse(); + response.setAffectedAutomationCompositions(automationCompositions.getAutomationCompositionList().stream() + .map(ac -> ac.getKey().asIdentifier()).collect(Collectors.toList())); + + return response; + } + + /** + * Update automation compositions. + * + * @param automationCompositions the automation composition + * @return the result of the instantiation operation + * @throws PfModelException on update errors + */ + public InstantiationResponse updateAutomationCompositions(AutomationCompositions automationCompositions) + throws PfModelException { + BeanValidationResult validationResult = validateAutomationCompositions(automationCompositions); + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } + automationCompositionProvider.saveAutomationCompositions(automationCompositions.getAutomationCompositionList()); + + var response = new InstantiationResponse(); + response.setAffectedAutomationCompositions(automationCompositions.getAutomationCompositionList().stream() + .map(ac -> ac.getKey().asIdentifier()).collect(Collectors.toList())); + + return response; + } + + /** + * Validate AutomationCompositions. + * + * @param automationCompositions AutomationCompositions to validate + * @return the result of validation + * @throws PfModelException if automationCompositions is not valid + */ + private BeanValidationResult validateAutomationCompositions(AutomationCompositions automationCompositions) + throws PfModelException { + + var result = new BeanValidationResult("AutomationCompositions", automationCompositions); + + for (AutomationComposition automationComposition : automationCompositions.getAutomationCompositionList()) { + var subResult = new BeanValidationResult(ENTRY + automationComposition.getDefinition().getName(), + automationComposition); + + List<ToscaNodeTemplate> toscaNodeTemplates = commissioningProvider.getAutomationCompositionDefinitions( + automationComposition.getDefinition().getName(), automationComposition.getDefinition().getVersion()); + + if (toscaNodeTemplates.isEmpty()) { + subResult.addResult( + new ObjectValidationResult("AutomationComposition", automationComposition.getDefinition().getName(), + ValidationStatus.INVALID, "Commissioned automation composition definition not found")); + } else if (toscaNodeTemplates.size() > 1) { + subResult.addResult( + new ObjectValidationResult("AutomationComposition", automationComposition.getDefinition().getName(), + ValidationStatus.INVALID, "Commissioned automation composition definition not valid")); + } else { + + List<ToscaNodeTemplate> acElementDefinitions = + commissioningProvider.getAutomationCompositionElementDefinitions(toscaNodeTemplates.get(0)); + + // @formatter:off + Map<String, ToscaConceptIdentifier> definitions = acElementDefinitions + .stream() + .map(nodeTemplate -> nodeTemplate.getKey().asIdentifier()) + .collect(Collectors.toMap(ToscaConceptIdentifier::getName, UnaryOperator.identity())); + // @formatter:on + + for (AutomationCompositionElement element : automationComposition.getElements().values()) { + subResult.addResult(validateDefinition(definitions, element.getDefinition())); + } + } + result.addResult(subResult); + } + return result; + } + + /** + * Validate ToscaConceptIdentifier, checking if exist in ToscaConceptIdentifiers map. + * + * @param definitions map of all ToscaConceptIdentifiers + * @param definition ToscaConceptIdentifier to validate + * @return the validation result + */ + private ValidationResult validateDefinition(Map<String, ToscaConceptIdentifier> definitions, + ToscaConceptIdentifier definition) { + var result = new BeanValidationResult(ENTRY + definition.getName(), definition); + ToscaConceptIdentifier 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); + } + + /** + * Delete the automation composition with the given name and version. + * + * @param name the name of the automation composition to delete + * @param version the version of the automation composition to delete + * @return the result of the deletion + * @throws PfModelException on deletion errors + */ + public InstantiationResponse deleteAutomationComposition(String name, String version) throws PfModelException { + var automationCompositionOpt = automationCompositionProvider.findAutomationComposition(name, version); + if (automationCompositionOpt.isEmpty()) { + throw new PfModelException(Response.Status.NOT_FOUND, "Automation composition not found"); + } + var automationComposition = automationCompositionOpt.get(); + if (!AutomationCompositionState.UNINITIALISED.equals(automationComposition.getState())) { + throw new PfModelException(Response.Status.BAD_REQUEST, + "Automation composition state is still " + automationComposition.getState()); + } + var response = new InstantiationResponse(); + response.setAffectedAutomationCompositions( + List.of(automationCompositionProvider.deleteAutomationComposition(name, version).getKey().asIdentifier())); + return response; + } + + /** + * Get the requested automation compositions. + * + * @param name the name of the automation composition to get, null for all automation compositions + * @param version the version of the automation composition to get, null for all automation compositions + * @return the automation compositions + * @throws PfModelException on errors getting automation compositions + */ + @Transactional(readOnly = true) + public AutomationCompositions getAutomationCompositions(String name, String version) throws PfModelException { + var automationCompositions = new AutomationCompositions(); + automationCompositions + .setAutomationCompositionList(automationCompositionProvider.getAutomationCompositions(name, version)); + + return automationCompositions; + } + + /** + * Issue a command to automation compositions, setting their ordered state. + * + * @param command the command to issue to automation compositions + * @return the result of the initiation command + * @throws PfModelException on errors setting the ordered state on the automation compositions + * @throws AutomationCompositionException on ordered state invalid + */ + public InstantiationResponse issueAutomationCompositionCommand(InstantiationCommand command) + throws AutomationCompositionException, PfModelException { + + if (command.getOrderedState() == null) { + throw new AutomationCompositionException(Status.BAD_REQUEST, + "ordered state invalid or not specified on command"); + } + + var participants = participantProvider.getParticipants(); + if (participants.isEmpty()) { + throw new AutomationCompositionException(Status.BAD_REQUEST, "No participants registered"); + } + var validationResult = new BeanValidationResult("InstantiationCommand", command); + List<AutomationComposition> automationCompositions = + new ArrayList<>(command.getAutomationCompositionIdentifierList().size()); + for (ToscaConceptIdentifier id : command.getAutomationCompositionIdentifierList()) { + var automationCompositionOpt = automationCompositionProvider.findAutomationComposition(id); + if (automationCompositionOpt.isEmpty()) { + validationResult.addResult("ToscaConceptIdentifier", id, ValidationStatus.INVALID, + "AutomationComposition with id " + id + " not found"); + } else { + var automationComposition = automationCompositionOpt.get(); + automationComposition.setCascadedOrderedState(command.getOrderedState()); + automationCompositions.add(automationComposition); + } + } + if (validationResult.isValid()) { + validationResult = validateIssueAutomationCompositions(automationCompositions, participants); + } + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } + automationCompositionProvider.saveAutomationCompositions(automationCompositions); + + supervisionHandler.triggerAutomationCompositionSupervision(command.getAutomationCompositionIdentifierList()); + var response = new InstantiationResponse(); + response.setAffectedAutomationCompositions(command.getAutomationCompositionIdentifierList()); + + return response; + } + + private BeanValidationResult validateIssueAutomationCompositions(List<AutomationComposition> automationCompositions, + List<Participant> participants) { + var result = new BeanValidationResult("AutomationCompositions", automationCompositions); + + Map<ToscaConceptIdentifier, Participant> participantMap = participants.stream() + .collect(Collectors.toMap(participant -> participant.getKey().asIdentifier(), Function.identity())); + + for (AutomationComposition automationComposition : automationCompositions) { + + for (var element : automationComposition.getElements().values()) { + + var subResult = new BeanValidationResult(ENTRY + element.getDefinition().getName(), element); + Participant p = participantMap.get(element.getParticipantId()); + if (p == null) { + subResult.addResult(new ObjectValidationResult(AUTOMATION_COMPOSITION_NODE_ELEMENT_TYPE, + element.getDefinition().getName(), ValidationStatus.INVALID, + "Participant with ID " + element.getParticipantId() + " is not registered")); + } else if (!p.getParticipantType().equals(element.getParticipantType())) { + subResult.addResult(new ObjectValidationResult(AUTOMATION_COMPOSITION_NODE_ELEMENT_TYPE, + element.getDefinition().getName(), ValidationStatus.INVALID, + "Participant with ID " + element.getParticipantType() + " - " + element.getParticipantId() + + " is not registered")); + } + result.addResult(subResult); + } + + } + + return result; + } + + /** + * Gets a list of automation compositions with it's ordered state. + * + * @param name the name of the automation composition to get, null for all automation compositions + * @param version the version of the automation composition to get, null for all automation compositions + * @return a list of Instantiation Command + * @throws PfModelException on errors getting automation compositions + */ + @Transactional(readOnly = true) + public AutomationCompositionOrderStateResponse getInstantiationOrderState(String name, String version) + throws PfModelException { + + List<AutomationComposition> automationCompositions = + automationCompositionProvider.getAutomationCompositions(name, version); + + var response = new AutomationCompositionOrderStateResponse(); + + automationCompositions.forEach(automationComposition -> { + var genericNameVersion = new GenericNameVersion(); + genericNameVersion.setName(automationComposition.getName()); + genericNameVersion.setVersion(automationComposition.getVersion()); + response.getAutomationCompositionIdentifierList().add(genericNameVersion); + }); + + return response; + } + + /** + * Saves Instance Properties and automation composition. + * Gets a list of automation compositions which are primed or de-primed. + * + * @param name the name of the automation composition to get, null for all automation compositions + * @param version the version of the automation composition to get, null for all automation compositions + * @return a list of Instantiation Command + * @throws PfModelException on errors getting automation compositions + */ + @Transactional(readOnly = true) + public AutomationCompositionPrimedResponse getAutomationCompositionPriming(String name, String version) + throws PfModelException { + + List<AutomationComposition> automationCompositions = + automationCompositionProvider.getAutomationCompositions(name, version); + + var response = new AutomationCompositionPrimedResponse(); + + automationCompositions.forEach(automationComposition -> { + var primed = new AutomationCompositionPrimed(); + primed.setName(automationComposition.getName()); + primed.setVersion(automationComposition.getVersion()); + primed.setPrimed(automationComposition.getPrimed()); + response.getPrimedAutomationCompositionsList().add(primed); + }); + + return response; + } + + /** + * Creates instance element name. + * + * @param serviceTemplate the service template + * @param automationCompositions a list of automation compositions + * @return the result of the instance properties and instantiation operation + * @throws PfModelException on creation errors + */ + private InstancePropertiesResponse saveInstancePropertiesAndAutomationComposition( + ToscaServiceTemplate serviceTemplate, AutomationCompositions automationCompositions) throws PfModelException { + + for (var automationComposition : automationCompositions.getAutomationCompositionList()) { + var checkAutomationCompositionOpt = + automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); + if (checkAutomationCompositionOpt.isPresent()) { + throw new PfModelException(Response.Status.BAD_REQUEST, "Automation composition with id " + + automationComposition.getKey().asIdentifier() + " already defined"); + } + } + Map<String, ToscaNodeTemplate> toscaSavedNodeTemplate = + automationCompositionProvider.saveInstanceProperties(serviceTemplate); + automationCompositionProvider.saveAutomationCompositions(automationCompositions.getAutomationCompositionList()); + List<ToscaConceptIdentifier> affectedAutomationCompositions = automationCompositions + .getAutomationCompositionList().stream().map(ac -> ac.getKey().asIdentifier()).collect(Collectors.toList()); + + List<ToscaConceptIdentifier> toscaAffectedProperties = toscaSavedNodeTemplate.values().stream() + .map(template -> template.getKey().asIdentifier()).collect(Collectors.toList()); + + var response = new InstancePropertiesResponse(); + response.setAffectedInstanceProperties(Stream.of(affectedAutomationCompositions, toscaAffectedProperties) + .flatMap(Collection::stream).collect(Collectors.toList())); + + return response; + } + + /** + * Crates a new automation composition instance. + * + * @param instanceName automation composition Instance name + * @param automationComposition empty automation composition + * @param automationCompositionElements new automation composition Element map + * @param template original Cloned Tosca Node Template + * @param newNodeTemplate new Tosca Node Template + */ + private void crateNewAutomationCompositionInstance(String instanceName, AutomationComposition automationComposition, + Map<UUID, AutomationCompositionElement> automationCompositionElements, ToscaNodeTemplate template, + ToscaNodeTemplate newNodeTemplate) { + if (template.getType().equals(AUTOMATION_COMPOSITION_NODE_TYPE)) { + automationComposition.setDefinition(getAutomationCompositionDefinition(newNodeTemplate)); + } + + if (template.getType().contains(AUTOMATION_COMPOSITION_NODE_ELEMENT_TYPE)) { + AutomationCompositionElement automationCompositionElement = + getAutomationCompositionElement(newNodeTemplate); + automationCompositionElements.put(automationCompositionElement.getId(), automationCompositionElement); + } + + automationComposition.setName("PMSH" + instanceName); + automationComposition.setVersion(template.getVersion()); + automationComposition.setDescription("PMSH automation composition " + instanceName); + automationComposition.setState(AutomationCompositionState.UNINITIALISED); + automationComposition.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + } + + /** + * Get's the instance property name of the automation composition. + * + * @param name the name of the automation composition to get, null for all automation compositions + * @param version the version of the automation composition to get, null for all automation compositions + * @return the instance name of the automation composition instance properties + * @throws PfModelException on errors getting automation compositions + */ + private String getInstancePropertyName(String name, String version) throws PfModelException { + List<String> toscaDefinitionsNames = + automationCompositionProvider.getAutomationCompositions(name, version).stream() + .map(AutomationComposition::getDefinition).map(ToscaNameVersion::getName).collect(Collectors.toList()); + + return toscaDefinitionsNames.stream().reduce("", (s1, s2) -> { + + if (s2.contains(INSTANCE_TEXT)) { + String[] instances = s2.split(INSTANCE_TEXT); + + return INSTANCE_TEXT + instances[1]; + } + + return s1; + }); + } + + /** + * Generates Instance Name in sequential order and return it to append to the Node Template Name. + * + * @return instanceName + */ + private String generateSequentialInstanceName() { + List<ToscaNodeTemplate> nodeTemplates = automationCompositionProvider.getAllNodeTemplates(); + + int instanceNumber = nodeTemplates.stream().map(ToscaNodeTemplate::getName) + .filter(name -> name.contains(INSTANCE_TEXT)).map(n -> { + String[] defNameArr = n.split(INSTANCE_TEXT); + + return Integer.parseInt(defNameArr[1]); + }).reduce(0, Math::max); + + return INSTANCE_TEXT + (instanceNumber + 1); + } + + /** + * Retrieves automation composition Definition. + * + * @param template tosca node template + * @return automation composition definition + */ + private ToscaConceptIdentifier getAutomationCompositionDefinition(ToscaNodeTemplate template) { + ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); + definition.setName(template.getName()); + definition.setVersion(template.getVersion()); + return definition; + } + + /** + * Retrieves automation composition Element. + * + * @param template tosca node template + * @return a automation composition element + */ + @SuppressWarnings("unchecked") + private AutomationCompositionElement getAutomationCompositionElement(ToscaNodeTemplate template) { + AutomationCompositionElement automationCompositionElement = new AutomationCompositionElement(); + ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); + definition.setName(template.getName()); + definition.setVersion(template.getVersion()); + automationCompositionElement.setDefinition(definition); + LinkedTreeMap<String, Object> participantId = + (LinkedTreeMap<String, Object>) template.getProperties().get(PARTICIPANT_ID_PROPERTY_KEY); + if (participantId != null) { + ToscaConceptIdentifier participantIdProperty = new ToscaConceptIdentifier(); + participantIdProperty.setName(String.valueOf(participantId.get(AC_ELEMENT_NAME))); + participantIdProperty.setVersion(String.valueOf(participantId.get(AC_ELEMENT_VERSION))); + automationCompositionElement.setParticipantId(participantIdProperty); + } + LinkedTreeMap<String, Object> participantType = + (LinkedTreeMap<String, Object>) template.getProperties().get(PARTICIPANT_TYPE_PROPERTY_KEY); + if (participantType != null) { + ToscaConceptIdentifier participantTypeProperty = new ToscaConceptIdentifier(); + participantTypeProperty.setName(String.valueOf(participantType.get(AC_ELEMENT_NAME))); + participantTypeProperty.setVersion(participantType.get(AC_ELEMENT_VERSION).toString()); + automationCompositionElement.setParticipantType(participantTypeProperty); + } + return automationCompositionElement; + } + + /** + * Deep clones ToscaNodeTemplate. + * + * @param serviceTemplate ToscaServiceTemplate + * @return a cloned Hash Map of ToscaNodeTemplate + */ + private Map<String, ToscaNodeTemplate> deepCloneNodeTemplate(ToscaServiceTemplate serviceTemplate) { + String jsonString = GSON.toJson(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()); + Type type = new TypeToken<HashMap<String, ToscaNodeTemplate>>() {}.getType(); + return GSON.fromJson(jsonString, type); + } +} |