package org.alien4cloud.tosca.editor.processors.inputs; import static alien4cloud.utils.AlienUtils.safe; import java.util.Arrays; import java.util.Map; import javax.annotation.Resource; import javax.inject.Inject; import org.alien4cloud.tosca.editor.EditionContextManager; import org.alien4cloud.tosca.editor.operations.inputs.RenameInputOperation; import org.alien4cloud.tosca.editor.processors.IEditorCommitableProcessor; import org.alien4cloud.tosca.model.definitions.AbstractPropertyValue; import org.alien4cloud.tosca.model.definitions.FunctionPropertyValue; import org.alien4cloud.tosca.model.definitions.PropertyDefinition; import org.alien4cloud.tosca.model.definitions.PropertyValue; import org.alien4cloud.tosca.model.templates.Capability; import org.alien4cloud.tosca.model.templates.NodeTemplate; import org.alien4cloud.tosca.model.templates.RelationshipTemplate; import org.alien4cloud.tosca.model.templates.Topology; import org.apache.commons.collections4.MapUtils; import org.springframework.stereotype.Component; import alien4cloud.dao.IGenericSearchDAO; import alien4cloud.deployment.DeploymentTopologyService; import alien4cloud.exception.AlreadyExistException; import alien4cloud.exception.InvalidNameException; import alien4cloud.exception.NotFoundException; import alien4cloud.model.deployment.DeploymentTopology; import alien4cloud.tosca.normative.ToscaFunctionConstants; import lombok.extern.slf4j.Slf4j; /** * Removes an input from the topology and reset the properties values if the input was assigned. */ @Slf4j @Component public class RenameInputProcessor extends AbstractInputProcessor<RenameInputOperation> implements IEditorCommitableProcessor<RenameInputOperation> { @Resource(name = "alien-es-dao") private IGenericSearchDAO alienDAO; @Inject private DeploymentTopologyService deploymentTopologyService; @Override protected void processInputOperation(RenameInputOperation operation, Map<String, PropertyDefinition> inputs) { if (!inputs.containsKey(operation.getInputName())) { throw new NotFoundException("Input " + operation.getInputName() + " not found"); } if (operation.getInputName().equals(operation.getNewInputName())) { return; // nothing has changed. } if (operation.getNewInputName() == null || operation.getNewInputName().isEmpty() || !operation.getNewInputName().matches("\\w+")) { throw new InvalidNameException("newInputName", operation.getNewInputName(), "\\w+"); } if (inputs.containsKey(operation.getNewInputName())) { throw new AlreadyExistException("Input " + operation.getNewInputName() + " already existed"); } PropertyDefinition propertyDefinition = inputs.remove(operation.getInputName()); inputs.put(operation.getNewInputName(), propertyDefinition); Topology topology = EditionContextManager.getTopology(); Map<String, NodeTemplate> nodeTemplates = topology.getNodeTemplates(); for (NodeTemplate nodeTemp : safe(nodeTemplates).values()) { renameInputInProperties(nodeTemp.getProperties(), operation.getInputName(), operation.getNewInputName()); if (nodeTemp.getRelationships() != null) { for (RelationshipTemplate relationshipTemplate : nodeTemp.getRelationships().values()) { renameInputInProperties(relationshipTemplate.getProperties(), operation.getInputName(), operation.getNewInputName()); } } if (nodeTemp.getCapabilities() != null) { for (Capability capability : nodeTemp.getCapabilities().values()) { renameInputInProperties(capability.getProperties(), operation.getInputName(), operation.getNewInputName()); } } } log.debug("Change the name of an input parameter <{}> to <{}> for the topology ", operation.getInputName(), operation.getNewInputName(), topology.getId()); } /** * Update the input name for the {@link FunctionPropertyValue} in a map of properties. * * @param properties The map of properties in which to rename input * @param inputName The name of the input to rename. * @param newInputName The new name for the input. */ private void renameInputInProperties(final Map<String, AbstractPropertyValue> properties, final String inputName, final String newInputName) { if (MapUtils.isNotEmpty(properties)) { for (AbstractPropertyValue propertyValue : properties.values()) { if (propertyValue instanceof FunctionPropertyValue) { FunctionPropertyValue functionPropertyValue = (FunctionPropertyValue) propertyValue; if (ToscaFunctionConstants.GET_INPUT.equals(functionPropertyValue.getFunction()) && functionPropertyValue.getParameters().get(0).equals(inputName)) { functionPropertyValue.setParameters(Arrays.asList(newInputName)); } } } } } @Override public void beforeCommit(RenameInputOperation operation) { Topology topology = EditionContextManager.getTopology(); DeploymentTopology[] deploymentTopologies = deploymentTopologyService.getByTopologyId(topology.getId()); for (DeploymentTopology deploymentTopology : deploymentTopologies) { if (deploymentTopology.getInputProperties() != null && deploymentTopology.getInputProperties().containsKey(operation.getInputName())) { PropertyValue previousValue = deploymentTopology.getInputProperties().remove(operation.getInputName()); deploymentTopology.getInputProperties().put(operation.getNewInputName(), previousValue); alienDAO.save(deploymentTopology); } } } @Override protected boolean create() { return false; } }