/** * If the node to replace is an target of relationship, we should swapped the relationship on source and clean used workflow steps */ private Map<String, Map<String, RelationshipTemplate>> removeTheRelationshipsOnSource(Topology topology, Csar csar, String nodeToReplace) { Map<String, Map<String, RelationshipTemplate>> relationshipDeleted = Maps.newLinkedHashMap(); for (NodeTemplate nodeTemplate : safe(topology.getNodeTemplates()).values()) { if (!nodeToReplace.equals(nodeTemplate.getName())) { List<String> relationshipsToRemove = Lists.newArrayList(); for (RelationshipTemplate relationshipTemplate : safe(nodeTemplate.getRelationships()).values()) { if (nodeToReplace.equals(relationshipTemplate.getTarget())) { relationshipsToRemove.add(relationshipTemplate.getName()); if (!relationshipDeleted.containsKey(relationshipTemplate.getName())) { Map<String, RelationshipTemplate> relationships = Maps.newHashMap(); // we save the RelationshipTemplate, so we will preserve the current properties of this relationship relationshipDeleted.put(nodeTemplate.getName(), relationships); } relationshipDeleted.get(nodeTemplate.getName()).put(relationshipTemplate.getName(), relationshipTemplate); // we should remove this relationship to maintain a great a workflow workflowBuilderService.removeRelationship(topology, csar, nodeTemplate.getName(), relationshipTemplate.getName(), relationshipTemplate); } } } } return relationshipDeleted; }
private void addRebuildRelationshipOperation(NodeTemplate nodeTemplate, RelationshipTemplate relationshipTemplate, List<AbstractEditorOperation> recoveryOperations) { RebuildRelationshipOperation operation = new RebuildRelationshipOperation(); operation.setNodeName(nodeTemplate.getName()); operation.setRelationshipName(relationshipTemplate.getName()); recoveryOperations.add(operation); }
private void addDeleteRelationshipOperation(NodeTemplate nodeTemplate, RelationshipTemplate relationshipTemplate, List<AbstractEditorOperation> recoveryOperations) { DeleteRelationshipOperation operation = new DeleteRelationshipOperation(); operation.setNodeName(nodeTemplate.getName()); operation.setRelationshipName(relationshipTemplate.getName()); recoveryOperations.add(operation); }
/** * Discard all relationship targeting an "external" node. External here in terms of the hostedOn hierarchy * Copy the valid ones * * @param nodeName * @param validTargets A map of oldNodeName -> duplicatedNodeName, we should keep relationships targeting one of these nodes. */ private void copyAndCleanRelationships(String nodeName, Map<String, String> validTargets, Map<String, NodeTemplate> nodeTemplates, TopologyContext topologyContext) { NodeTemplate nodeTemplate = nodeTemplates.get(nodeName); if (MapUtils.isNotEmpty(nodeTemplate.getRelationships())) { Map<String, RelationshipTemplate> relationships = nodeTemplate.getRelationships(); Set<String> keys = Sets.newHashSet(relationships.keySet()); for (String key : keys) { RelationshipTemplate rel = relationships.remove(key); // check if the target is from the valids one // If so, then rename it, its target and keep it if (validTargets.containsKey(rel.getTarget())) { rel.setName(copyName(rel.getName(), relationships.keySet())); rel.setTarget(validTargets.get(rel.getTarget())); relationships.put(rel.getName(), rel); workflowBuilderService.addRelationship(topologyContext, nodeName, rel.getName()); } } if (relationships.isEmpty()) { nodeTemplate.setRelationships(null); } } }
@Override public void process(NodeTemplate instance) { final NodeType nodeType = ToscaContext.get(NodeType.class, instance.getType()); if (nodeType == null) { return; // error managed by the reference post processor. } Map<String, RelationshipTemplate> updated = Maps.newLinkedHashMap(); safe(instance.getRelationships()).entrySet().forEach(entry -> { relationshipPostProcessor.process(nodeType, entry); String relationshipTemplateName = entry.getValue().getName(); if (StringUtils.isEmpty(relationshipTemplateName)) { // from 2.0.0 the relationship's name is filled by the parser relationshipTemplateName = buildRelationShipTemplateName(entry.getValue()); } relationshipTemplateName = getUniqueKey(updated, relationshipTemplateName); updated.put(relationshipTemplateName, entry.getValue()); entry.getValue().setName(relationshipTemplateName); }); instance.setRelationships(updated); }
/** * validate the requirement:<br> * <ul> * <li>Check that a node still has the requirement, by checking directly from the related node type</li> * <li>Check that the requirement type of the node hasn't changed</li> * </ul> * * @param relationshipTemplate The name of the requirement to check * @param nodeTemplate The node template in which to check for the requirement * @param nodeType * @throws InvalidStateException when something is wrong */ private void checkRequirement(RelationshipTemplate relationshipTemplate, NodeTemplate nodeTemplate, NodeType nodeType) { Map<String, RequirementDefinition> requirementMap = AlienUtils.fromListToMap(nodeType.getRequirements(), "id", true); if (!AlienUtils.safe(requirementMap).containsKey(relationshipTemplate.getRequirementName())) { throw new InvalidStateException( "A requirement with name [" + relationshipTemplate.getName() + "] cannot be found in the node [" + nodeTemplate.getName() + "]."); } // check that the requirement type hasn't changed RequirementDefinition requirement = AlienUtils.safe(requirementMap).get(relationshipTemplate.getRequirementName()); if (!Objects.equals(requirement.getType(), relationshipTemplate.getRequirementType())) { // the requirementType has changed. delete the relationship // TODO check if this requirement is compatible with the previous one, and mabey try to rebuild the relationship throw new InvalidStateException( "The type of the requirement [" + relationshipTemplate.getRequirementName() + "], node [" + nodeTemplate.getName() + "] has changed"); } }
.filter(operationEntry -> !sourceIsNative || operationEntry.getValue().getOperationHost() == RelationshipOperationHost.TARGET) .collect(Collectors.toMap(Map.Entry::getKey, operationEntry -> WorkflowUtils.addRelationshipOperationStep(workflow, nodeId, relationshipTemplate.getName(), ToscaRelationshipLifecycleConstants.CONFIGURE_SHORT, operationEntry.getKey(), operationEntry.getValue().getOperationHost().toString())));