package org.alien4cloud.tosca.editor.processors.nodetemplate.outputs;
import alien4cloud.exception.NotFoundException;
import org.alien4cloud.tosca.model.types.CapabilityType;
import org.alien4cloud.tosca.model.templates.Capability;
import org.alien4cloud.tosca.model.templates.NodeTemplate;
import org.alien4cloud.tosca.model.templates.Topology;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.alien4cloud.tosca.editor.EditionContextManager;
import org.alien4cloud.tosca.editor.operations.nodetemplate.outputs.SetNodeCapabilityPropertyAsOutputOperation;
import org.alien4cloud.tosca.editor.processors.nodetemplate.AbstractNodeProcessor;
import org.springframework.stereotype.Component;
/**
* Set a given property of a node's capability as output for the topology.
*/
@Slf4j
@Component
public class SetNodeCapabilityPropertyAsOutputProcessor extends AbstractNodeProcessor<SetNodeCapabilityPropertyAsOutputOperation> {
@Override
protected void processNodeOperation(SetNodeCapabilityPropertyAsOutputOperation operation, NodeTemplate nodeTemplate) {
Topology topology = EditionContextManager.getTopology();
// check if the capability / property exists
check(operation, topology, nodeTemplate);
//ensure non null maps and collections
Map<String, Map<String, Set<String>>> outputs = emptyIfNull(topology.getOutputCapabilityProperties());
Map<String, Set<String>> capabilitiesOutputs = emptyIfNull(outputs.get(operation.getNodeName()));
outputs.put(operation.getNodeName(), capabilitiesOutputs);
Set<String> outputProperties = emptyIfNull(capabilitiesOutputs.get(operation.getCapabilityName()));
capabilitiesOutputs.put(operation.getCapabilityName(), outputProperties);
outputProperties.add(operation.getPropertyName());
topology.setOutputCapabilityProperties(outputs);
log.debug("Set node<{}> capability <{}>'s property <{}> as output for the topology <{}>.", operation.getNodeName(), operation.getCapabilityName(),
operation.getPropertyName(), topology.getId());
}
private void check(SetNodeCapabilityPropertyAsOutputOperation operation, Topology topology, NodeTemplate nodeTemplate) {
if (nodeTemplate.getCapabilities() == null || nodeTemplate.getCapabilities().get(operation.getCapabilityName()) == null) {
throw new NotFoundException("Capability " + operation.getCapabilityName() + " not found in node template " + operation.getNodeName());
}
Capability capabilityTemplate = nodeTemplate.getCapabilities().get(operation.getCapabilityName());
CapabilityType indexedCapabilityType = EditionContextManager.get().getToscaContext().getElement(CapabilityType.class,
capabilityTemplate.getType(), true);
if (indexedCapabilityType.getProperties() == null || !indexedCapabilityType.getProperties().containsKey(operation.getPropertyName())) {
throw new NotFoundException("Property " + operation.getPropertyName() + " not found in capability " + operation.getCapabilityName() + " of node "
+ operation.getNodeName());
}
}
private <K, V> Map<K, V> emptyIfNull(Map<K, V> map){
return map==null?Maps.newHashMap():map;
}
private <E> Set<E> emptyIfNull(Set<E> set){
return set==null?Sets.newHashSet():set;
}
}