All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.cloudsoft.tosca.a4c.brooklyn.Alien4CloudFacade Maven / Gradle / Ivy

package io.cloudsoft.tosca.a4c.brooklyn;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;

import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;

import alien4cloud.application.ApplicationService;
import alien4cloud.component.ICSARRepositorySearchService;
import alien4cloud.component.repository.ICsarRepositry;
import alien4cloud.deployment.DeploymentTopologyService;
import alien4cloud.model.application.Application;
import alien4cloud.model.components.AbstractPropertyValue;
import alien4cloud.model.components.AttributeDefinition;
import alien4cloud.model.components.ComplexPropertyValue;
import alien4cloud.model.components.ConcatPropertyValue;
import alien4cloud.model.components.Csar;
import alien4cloud.model.components.DeploymentArtifact;
import alien4cloud.model.components.FunctionPropertyValue;
import alien4cloud.model.components.IValue;
import alien4cloud.model.components.ImplementationArtifact;
import alien4cloud.model.components.IndexedArtifactToscaElement;
import alien4cloud.model.components.IndexedInheritableToscaElement;
import alien4cloud.model.components.IndexedRelationshipType;
import alien4cloud.model.components.Interface;
import alien4cloud.model.components.Operation;
import alien4cloud.model.components.ScalarPropertyValue;
import alien4cloud.model.deployment.DeploymentTopology;
import alien4cloud.model.templates.TopologyTemplate;
import alien4cloud.model.templates.TopologyTemplateVersion;
import alien4cloud.model.topology.AbstractTemplate;
import alien4cloud.model.topology.NodeTemplate;
import alien4cloud.model.topology.RelationshipTemplate;
import alien4cloud.model.topology.Requirement;
import alien4cloud.model.topology.Topology;
import alien4cloud.paas.IPaaSTemplate;
import alien4cloud.paas.function.FunctionEvaluator;
import alien4cloud.paas.model.PaaSNodeTemplate;
import alien4cloud.paas.model.PaaSRelationshipTemplate;
import alien4cloud.paas.model.PaaSTopology;
import alien4cloud.paas.plan.TopologyTreeBuilderService;
import alien4cloud.paas.plan.ToscaNodeLifecycleConstants;
import alien4cloud.paas.plan.ToscaRelationshipLifecycleConstants;
import alien4cloud.topology.TopologyServiceCore;
import alien4cloud.topology.TopologyTemplateVersionService;
import alien4cloud.tosca.normative.NormativeComputeConstants;
import alien4cloud.tosca.normative.ToscaFunctionConstants;
import alien4cloud.tosca.parser.ParsingResult;
import io.cloudsoft.tosca.a4c.brooklyn.util.NodeTemplates;

@Component
public class Alien4CloudFacade implements ToscaFacade {

    private static final Logger LOG = LoggerFactory.getLogger(Alien4CloudFacade.class);
    public static final String COMPUTE_TYPE = NormativeComputeConstants.COMPUTE_TYPE;

    private static final Map> lifeCycleMapping = ImmutableMap.>builder()
            .put(ToscaRelationshipLifecycleConstants.PRE_CONFIGURE_SOURCE, VanillaSoftwareProcess.PRE_CUSTOMIZE_COMMAND)
            .put(ToscaRelationshipLifecycleConstants.POST_CONFIGURE_SOURCE, VanillaSoftwareProcess.POST_CUSTOMIZE_COMMAND)
            .put(ToscaRelationshipLifecycleConstants.PRE_CONFIGURE_TARGET, VanillaSoftwareProcess.PRE_CUSTOMIZE_COMMAND)
            .put(ToscaRelationshipLifecycleConstants.POST_CONFIGURE_TARGET, VanillaSoftwareProcess.POST_CUSTOMIZE_COMMAND)
            .put(ToscaNodeLifecycleConstants.CREATE, VanillaSoftwareProcess.INSTALL_COMMAND)
            .put(ToscaNodeLifecycleConstants.CONFIGURE, VanillaSoftwareProcess.CUSTOMIZE_COMMAND)
            .put(ToscaNodeLifecycleConstants.START, VanillaSoftwareProcess.LAUNCH_COMMAND)
            .put(ToscaNodeLifecycleConstants.STOP, VanillaSoftwareProcess.STOP_COMMAND)
            .build();

    private ICSARRepositorySearchService repositorySearchService;
    private TopologyTreeBuilderService treeBuilder;
    private ICsarRepositry csarFileRepository;
    private TopologyServiceCore topologyService;
    private TopologyTemplateVersionService topologyTemplateVersionService;
    private DeploymentTopologyService deploymentTopologyService;
    private ApplicationService applicationService;

    private final File tmpRoot;

    @Inject
    public Alien4CloudFacade(ICSARRepositorySearchService repositorySearchService, TopologyTreeBuilderService treeBuilder, ICsarRepositry csarFileRepository, TopologyServiceCore topologyService, TopologyTemplateVersionService topologyTemplateVersionService, DeploymentTopologyService deploymentTopologyService, ApplicationService applicationService) {
        this.repositorySearchService = repositorySearchService;
        this.treeBuilder = treeBuilder;
        this.csarFileRepository = csarFileRepository;
        this.topologyService = topologyService;
        this.topologyTemplateVersionService = topologyTemplateVersionService;
        this.deploymentTopologyService = deploymentTopologyService;
        this.applicationService = applicationService;

        tmpRoot = Os.newTempDir("brooklyn-a4c");
        Os.deleteOnExitRecursively(tmpRoot);
    }

    private Topology getTopologyOfCsar(Csar cs) {
        TopologyTemplate tt = topologyService.searchTopologyTemplateByName(cs.getName());
        if (tt == null) return null;
        TopologyTemplateVersion[] ttv = topologyTemplateVersionService.getByDelegateId(tt.getId());
        if (ttv == null || ttv.length == 0) return null;
        return topologyService.getTopology(ttv[0].getTopologyId());
    }

    /**
     * Resolves the parent dependency of the given node template.
     * 

* The parent dependency is: *

    *
  • The target node of a requirement called "host"
  • *
  • The resolved value of a property called "host"
  • *
  • Null
  • *
* * @param nodeId The node to examine * @param toscaApplication The tosca application * @return The id of the parent or null. */ @Override public String getParentId(String nodeId, Alien4CloudApplication toscaApplication) { NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); Requirement host = nodeTemplate.getRequirements() != null ? nodeTemplate.getRequirements().get("host") : null; if (host != null) { for (RelationshipTemplate r : nodeTemplate.getRelationships().values()) { if (r.getRequirementName().equals("host")) { return r.getTarget(); } } } // temporarily, fall back to looking for a *property* called 'host' // todo: why? Optional parentId = resolve(nodeTemplate.getProperties(), "host"); if (parentId.isPresent()) { LOG.warn("Using legacy 'host' *property* to resolve host; use *requirement* instead."); } return (String) parentId.orNull(); } private IndexedArtifactToscaElement getIndexedNodeTemplate(String nodeId, Alien4CloudApplication toscaApplication) { return repositorySearchService.getRequiredElementInDependencies( IndexedArtifactToscaElement.class, toscaApplication.getNodeTemplate(nodeId).getType(), toscaApplication.getTopology().getDependencies()); } private Optional getIndexedRelationshipTemplate(String nodeId, Alien4CloudApplication toscaApplication, String requirementId) { Optional optionalRelationshipTemplate = findRelationshipRequirement(nodeId, toscaApplication, requirementId); if(optionalRelationshipTemplate.isPresent()) { RelationshipTemplate relationshipTemplate = optionalRelationshipTemplate.get(); return Optional.of(repositorySearchService.getRequiredElementInDependencies( IndexedRelationshipType.class, relationshipTemplate.getType(), toscaApplication.getTopology().getDependencies() )); } return Optional.absent(); } @Override public boolean isDerivedFrom(String nodeId, Alien4CloudApplication toscaApplication, String type) { NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); return nodeTemplate.getType().equals(type) || getIndexedNodeTemplate(nodeId, toscaApplication) .getDerivedFrom() .contains(type); } private Map getAllNodes(Alien4CloudApplication toscaApplication) { return treeBuilder.buildPaaSTopology(toscaApplication.getTopology()).getAllNodes(); } @Override public Map getTemplatePropertyObjects(String nodeId, Alien4CloudApplication toscaApplication, String computeName) { Map builtPaaSNodeTemplates = getAllNodes(toscaApplication); PaaSNodeTemplate paasNodeTemplate = builtPaaSNodeTemplates.get(computeName); NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); return getTemplatePropertyObjects(nodeTemplate, paasNodeTemplate, builtPaaSNodeTemplates, toscaApplication.getKeywordMap(nodeTemplate)); } private Map getTemplatePropertyObjects(AbstractTemplate template, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates, Map keywordMap) { return getPropertyObjects(template.getProperties(), paasNodeTemplate, builtPaaSNodeTemplates, keywordMap); } private Map getPropertyObjects(Map propertyValueMap, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates, Map keywordMap) { Map propertyMap = MutableMap.of(); for (String propertyKey : ImmutableSet.copyOf(propertyValueMap.keySet())) { propertyMap.put(propertyKey, resolve(propertyValueMap, propertyKey, paasNodeTemplate, builtPaaSNodeTemplates, keywordMap).orNull()); } return propertyMap; } private Optional resolve(IValue v) { if (v instanceof ScalarPropertyValue) { return Optional.fromNullable(((ScalarPropertyValue) v).getValue()); } if (v instanceof ComplexPropertyValue) { return Optional.fromNullable(((ComplexPropertyValue) v).getValue()); } if (!(v instanceof FunctionPropertyValue)) { LOG.warn("Ignoring unsupported property value " + v); } return Optional.absent(); } private Optional resolve(Map props, String key) { IValue v = props.get(key); if (v == null) { LOG.warn("No value available for {}", key); return Optional.absent(); } return resolve(v); } private Optional resolve(IValue v, IPaaSTemplate template, Map builtPaaSNodeTemplates, Map keywordMap) { Optional value = resolve(v); if (!value.isPresent()) { if (v instanceof FunctionPropertyValue) { FunctionPropertyValue functionPropertyValue = (FunctionPropertyValue) v; String node = Optional.fromNullable(keywordMap.get(functionPropertyValue.getTemplateName())).or(functionPropertyValue.getTemplateName()); switch (functionPropertyValue.getFunction()) { case ToscaFunctionConstants.GET_PROPERTY: value = Optional.fromNullable(FunctionEvaluator.evaluateGetPropertyFunction(functionPropertyValue, template, builtPaaSNodeTemplates)); break; case ToscaFunctionConstants.GET_ATTRIBUTE: value = Optional.fromNullable(BrooklynDslCommon.entity(node).attributeWhenReady(functionPropertyValue.getElementNameToFetch())); break; case ToscaFunctionConstants.GET_INPUT: case ToscaFunctionConstants.GET_OPERATION_OUTPUT: default: value = Optional.absent(); } } } return value; } private Optional resolve(Map props, String key, IPaaSTemplate template, Map builtPaaSNodeTemplates, Map keywordMap) { IValue v = props.get(key); if (v == null) { LOG.warn("No value available for {}", key); return Optional.absent(); } return resolve(v, template, builtPaaSNodeTemplates, keywordMap); } private Optional getCsarPath(DeploymentArtifact artifact) { return getCsarPath(artifact.getArchiveName(), artifact.getArchiveVersion()); } @Override public Optional getCsarPath(String archiveName, String archiveVersion) { try { return Optional.of(csarFileRepository.getCSAR(archiveName, archiveVersion)); } catch (Exception e) { return Optional.absent(); } } private Optional> getArtifactsMap(String nodeId, Alien4CloudApplication toscaApplication) { Map artifacts = getIndexedNodeTemplate(nodeId, toscaApplication).getArtifacts(); if (artifacts == null || artifacts.isEmpty()) { return Optional.absent(); } return Optional.of(artifacts); } @Override public Iterable getArtifacts(String nodeId, Alien4CloudApplication toscaApplication) { Optional> optionalArtifacts = getArtifactsMap(nodeId, toscaApplication); if (!optionalArtifacts.isPresent()) { return Collections.emptyList(); } return optionalArtifacts.get().keySet(); } private Optional getArtifact(String nodeId, Alien4CloudApplication toscaApplication, String artifactId) { return Optional.fromNullable(getArtifactsMap(nodeId, toscaApplication).get().get(artifactId)); } private Map getStandardInterfaceOperationsMap(String nodeId, Alien4CloudApplication toscaApplication) { Map operations = MutableMap.of(); NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); IndexedArtifactToscaElement indexedNodeTemplate = getIndexedNodeTemplate(nodeId, toscaApplication); List validInterfaceNames = ImmutableList.of("tosca.interfaces.node.lifecycle.Standard", "Standard", "standard"); operations.putAll(getInterfaceOperationsMap(indexedNodeTemplate, validInterfaceNames)); Optional optionalNodeTemplateInterface = NodeTemplates.findInterfaceOfNodeTemplate( nodeTemplate.getInterfaces(), validInterfaceNames); if (optionalNodeTemplateInterface.isPresent()) { operations.putAll(optionalNodeTemplateInterface.get().getOperations()); } return operations; } private Map getConfigureInterfaceOperationsMap(Alien4CloudApplication toscaApplication, ToscaApplication.Relationship relationship) { Map operations = MutableMap.of(); Optional indexedRelationshipTemplate = Optional.of(repositorySearchService.getRequiredElementInDependencies( IndexedRelationshipType.class, relationship.getRelationshipType(), toscaApplication.getTopology().getDependencies() )); if(!indexedRelationshipTemplate.isPresent()){ return operations; } List validInterfaceNames = ImmutableList.of("tosca.interfaces.relationship.Configure", "Configure", "configure"); return getInterfaceOperationsMap(indexedRelationshipTemplate.get(), validInterfaceNames); } private Map getInterfaceOperationsMap(IndexedArtifactToscaElement indexedRelationshipTemplate, List validInterfaceNames) { Map operations = MutableMap.of(); Optional optionalIndexedNodeTemplateInterface = NodeTemplates.findInterfaceOfNodeTemplate( indexedRelationshipTemplate.getInterfaces(), validInterfaceNames ); if (!optionalIndexedNodeTemplateInterface.isPresent()) { return operations; } return MutableMap.copyOf(optionalIndexedNodeTemplateInterface.get().getOperations()); } @Override public Iterable getInterfaceOperations(String nodeId, Alien4CloudApplication toscaApplication) { return getStandardInterfaceOperationsMap(nodeId, toscaApplication).keySet(); } @Override public Iterable getInterfaceOperationsByRelationship(Alien4CloudApplication toscaApplication, ToscaApplication.Relationship relationship) { return getConfigureInterfaceOperationsMap(toscaApplication, relationship).keySet(); } private Optional getPaasNodeTemplate(String nodeId, Alien4CloudApplication toscaApplication) { NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); PaaSTopology paaSTopology = treeBuilder.buildPaaSTopology(toscaApplication.getTopology()); if (paaSTopology != null) { Map builtPaaSNodeTemplates = paaSTopology.getAllNodes(); String computeName = nodeTemplate.getName(); return Optional.of(builtPaaSNodeTemplates.get(computeName)); } return Optional.absent(); } private Optional findRelationshipRequirement(String nodeId, Alien4CloudApplication toscaApplication, String requirementId) { NodeTemplate node = toscaApplication.getNodeTemplate(nodeId); if (node.getRelationships() != null) { for (Map.Entry entry : node.getRelationships().entrySet()) { if (entry.getValue().getRequirementName().equals(requirementId)) { return Optional.of(entry.getValue()); } } } LOG.warn("Requirement {} is not described by any relationship ", requirementId); return Optional.absent(); } private Set findRelationshipsRequirement(String nodeId, Alien4CloudApplication toscaApplication, String requirementId) { Set result = MutableSet.of(); NodeTemplate node = toscaApplication.getNodeTemplate(nodeId); if (node.getRelationships() != null) { for (Map.Entry entry : node.getRelationships().entrySet()) { if ((entry.getValue() != null) && entry.getValue().getRequirementName().equals(requirementId)) { result.add(entry.getValue()); } } } LOG.warn("Requirement {} is not described by any relationship ", requirementId); return result; } private Map getRelationProperties(String nodeId, String computeName, Alien4CloudApplication toscaApplication, RelationshipTemplate relationshipTemplate) { Map builtPaaSNodeTemplates = getAllNodes(toscaApplication); PaaSNodeTemplate paasNodeTemplate = builtPaaSNodeTemplates.get(computeName); NodeTemplate nodeTemplate = toscaApplication.getNodeTemplate(nodeId); return getTemplatePropertyObjects(relationshipTemplate, paasNodeTemplate, builtPaaSNodeTemplates, toscaApplication.getKeywordMap(nodeTemplate, relationshipTemplate)); } private Object resolveAttribute(Map.Entry attribute, Alien4CloudApplication toscaApplication, String nodeId, PaaSNodeTemplate paaSNodeTemplate, Map allNodes) { Map builtPaaSNodeTemplates = getAllNodes(toscaApplication); PaaSNodeTemplate paasNodeTemplate = builtPaaSNodeTemplates.get(nodeId); IValue attributeValue = attribute.getValue(); if (attributeValue instanceof AttributeDefinition) { String defaultValue = ((AttributeDefinition) attribute.getValue()).getDefault(); if (Strings.isBlank(defaultValue)) { return null; } return defaultValue; } else if (attributeValue instanceof ConcatPropertyValue) { return resolveConcat((ConcatPropertyValue) attributeValue, paasNodeTemplate, builtPaaSNodeTemplates, toscaApplication.getKeywordMap(nodeId)); } else if (attributeValue instanceof FunctionPropertyValue) { Optional optionalResolvedAttribute = resolve(attributeValue, paasNodeTemplate, builtPaaSNodeTemplates, toscaApplication.getKeywordMap(nodeId)); return optionalResolvedAttribute.orNull(); } else { LOG.warn("Unable to resolve attribute {} of type {}", attribute.getKey(), attributeValue.getClass()); return null; } } private Object resolveConcat(ConcatPropertyValue attributeValue, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates, Map keywordMap) { Object[] vals = new Object[attributeValue.getParameters().size()]; for (int i = 0; i < attributeValue.getParameters().size(); i++) { IValue param = attributeValue.getParameters().get(i); Optional optionalResolvedAttribute = resolve(param, paasNodeTemplate, builtPaaSNodeTemplates, keywordMap); vals[i] = optionalResolvedAttribute.or(""); } String format = Strings.repeat("%s", vals.length); return BrooklynDslCommon.formatString(format, vals); } @Override public Object resolveProperty(String nodeId, Alien4CloudApplication toscaApplication, String key) { Map properties = toscaApplication.getNodeTemplate(nodeId).getProperties(); return resolve(properties, key).orNull(); } @Override public Optional getScript(String opKey, String nodeId, Alien4CloudApplication toscaApplication, String computeName, String expandedFolder) { return new NodeScriptGenerator(opKey, nodeId, toscaApplication, computeName, expandedFolder).makeScript(); } @Override public Optional getRelationshipScript(String opKey, Alien4CloudApplication toscaApplication, ToscaApplication.Relationship relationship, String computeName, String expandedFolder) { return new RelationshipScriptGenerator(opKey, toscaApplication, relationship, computeName, expandedFolder).makeScript(); } @Override public ConfigKey getLifeCycle(String opKey) { return lifeCycleMapping.get(opKey); } @Override public Map getResolvedAttributes(String nodeId, Alien4CloudApplication toscaApplication) { Map resolvedAttributes = MutableMap.of(); Optional optionalPaaSNodeTemplate = getPaasNodeTemplate(nodeId, toscaApplication); if (optionalPaaSNodeTemplate.isPresent()) { Map allNodes = getAllNodes(toscaApplication); final Map attributes = getIndexedNodeTemplate(nodeId, toscaApplication).getAttributes(); for (Map.Entry attribute : attributes.entrySet()) { String key = attribute.getKey().replaceAll("\\s+", "."); Object value = resolveAttribute(attribute, toscaApplication, nodeId, optionalPaaSNodeTemplate.get(), allNodes); if (value == null) { LOG.warn("Unable to resolve value for attribute {}", key); continue; } resolvedAttributes.put(key, value); } } return resolvedAttributes; } @Override public Map getPropertiesAndTypeValuesByRelationshipId(String nodeId, Alien4CloudApplication toscaApplication, String relationshipId, String computeName) { Map result = MutableMap.of(); RelationshipTemplate relationshipTemplate = toscaApplication.getNodeTemplate(nodeId).getRelationships().get(relationshipId); Preconditions.checkNotNull(relationshipTemplate, "Could not find relationship " + relationshipId + " on node " + nodeId); if (relationshipTemplate.getType().equals("brooklyn.relationships.Configure")) { Map relationProperties = getRelationProperties(nodeId, computeName, toscaApplication, relationshipTemplate); result = getPropertiesAndTypedValues(relationshipTemplate, relationProperties, computeName); } return result; } @SuppressWarnings("unchecked") private Map joinPropertiesAndValueTypes(Map properties, Map newProperties) { for(Map.Entry newPropertyEntry: newProperties.entrySet()) { String newPropertyKey = newPropertyEntry.getKey(); Object newPropertyValue = newPropertyEntry.getValue(); if (!properties.containsKey(newPropertyKey)) { properties.put(newPropertyKey, newPropertyValue); } else { Object oldPropertyValue = properties.get(newPropertyKey); if ((oldPropertyValue instanceof Map) && (newPropertyValue instanceof Map)) { ((Map) oldPropertyValue).putAll((Map) newPropertyValue); } else if ((oldPropertyValue instanceof List) && (newPropertyValue instanceof List)) { ((List) oldPropertyValue).addAll((List) newPropertyValue); } else { LOG.debug("New Property type {} can not be classified in {}, " + "it should be a Map or a List", newPropertyValue.getClass(), this); } } } return properties; } private Map getPropertiesAndTypedValues(RelationshipTemplate relationshipTemplate, Map relationProperties, String nodeName) { // TODO: Use target properly. String target = relationshipTemplate.getTarget(); String propName = (relationProperties.get("prop.name") != null) ? relationProperties.get("prop.name").toString() : Strings.EMPTY; String propCollection = (relationProperties.get("prop.collection") != null) ? relationProperties.get("prop.collection").toString() : Strings.EMPTY; String propValue = (relationProperties.get("prop.value") != null) ? relationProperties.get("prop.value").toString() : Strings.EMPTY; if (Strings.isBlank(propCollection) && (Strings.isBlank(propName))) { throw new IllegalStateException("Relationship for Requirement " + relationshipTemplate.getRequirementName() + " on NodeTemplate " + nodeName + ". Collection Name or Property Name should" + " be defined for RelationsType " + relationshipTemplate.getType()); } return (Strings.isBlank(propName)) ? MutableMap.of(propCollection, MutableList.of(propValue)) : MutableMap.of(propCollection, MutableMap.of(propName, propValue)); } @Override public Optional getArtifactPath(String nodeId, Alien4CloudApplication toscaApplication, String artifactId) { Optional optionalArtifact = getArtifact(nodeId, toscaApplication, artifactId); if (!optionalArtifact.isPresent()) return Optional.absent(); DeploymentArtifact artifact = optionalArtifact.get(); Optional csarPath = getCsarPath(artifact); if (!csarPath.isPresent()) { LOG.warn("CSAR " + artifactId + ":" + artifact.getArchiveVersion() + " does not exist"); return Optional.absent(); } else { return Optional.of(Paths.get(csarPath.get().getParent().toAbsolutePath().toString(), "expanded", artifact.getArtifactName())); } } private Alien4CloudApplication newToscaApplication(Csar csar) { return new Alien4CloudApplication(csar.getName(), getTopologyOfCsar(csar), ""); } @Override public Alien4CloudApplication newToscaApplication(String id) { DeploymentTopology deploymentTopology = deploymentTopologyService.getOrFail(id); Application application = applicationService.getOrFail(deploymentTopology.getDelegateId()); return new Alien4CloudApplication(application.getName(), deploymentTopology, id); } @Override public Alien4CloudApplication parsePlan(String plan, Uploader uploader) { ParsingResult tp = new ToscaParser(uploader).parse(plan); Csar csar = tp.getResult(); return newToscaApplication(csar); } @Override public Alien4CloudApplication parsePlan(Path path, Uploader uploader) { ParsingResult tp = uploader.uploadArchive(path.toFile(), "submitted-tosca-archive"); Csar csar = tp.getResult(); return newToscaApplication(csar); } abstract class ScriptGenerator { protected final String opKey; protected final String nodeId; protected final Alien4CloudApplication toscaApplication; protected final String computeName; protected final String expandedFolder; public ScriptGenerator(String opKey, String nodeId, Alien4CloudApplication toscaApplication, String computeName, String expandedFolder) { this.opKey = opKey; this.nodeId = nodeId; this.toscaApplication = toscaApplication; this.computeName = computeName; this.expandedFolder = expandedFolder; } public Optional makeScript() { if (!lifeCycleMapping.containsKey(opKey)) { LOG.warn("Could not translate operation, {}, for node template, {}.", opKey, toscaApplication.getNodeName(nodeId).orNull()); return Optional.absent(); } Operation op = getOperation(); ImplementationArtifact artifact = op.getImplementationArtifact(); if (artifact == null) { LOG.warn("Unsupported operation implementation for " + op.getDescription() + ": artifact has no impl"); return Optional.absent(); } String ref = artifact.getArtifactRef(); if (ref == null) { LOG.warn("Unsupported operation implementation for " + op.getDescription() + ": " + artifact + " has no ref"); return Optional.absent(); } return Optional.of(getScript(artifact, op)); } abstract Object getScript(ImplementationArtifact artifact, Operation op); abstract Operation getOperation(); protected String getScript(ImplementationArtifact artifact) { // Trying to get the CSAR file based on the artifact reference. If it fails, then we try to get the // content of the script from any resources String artifactRef = artifact.getArtifactRef(); Optional csarPath = getCsarPath(artifact.getArchiveName(), artifact.getArchiveVersion()); if(!csarPath.isPresent()) { return new ResourceUtils(this).getResourceAsString(artifactRef); } return new ResourceUtils(this).getResourceAsString(csarPath.get().getParent().toString() + expandedFolder + artifactRef); } protected Optional buildExportStatements(Operation op, String script) { Map builtPaaSNodeTemplates = getAllNodes(toscaApplication); PaaSNodeTemplate paasNodeTemplate = builtPaaSNodeTemplates.get(computeName); Map inputParameters = op.getInputParameters(); if (inputParameters == null) { return Optional.absent(); } List dsls = Lists.newArrayList(); for (Map.Entry entry : inputParameters.entrySet()) { Optional value = resolve(inputParameters, entry.getKey(), paasNodeTemplate, builtPaaSNodeTemplates); if (value.isPresent() && !Strings.isBlank(entry.getKey())) { dsls.add(BrooklynDslCommon.formatString("export %s=\"%s\"", entry.getKey(), value.get())); } } dsls.add(script); return Optional.of(BrooklynDslCommon.formatString(Strings.repeat("%s\n", dsls.size()), dsls.toArray())); } protected abstract Optional resolve(Map inputParameters, String key, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates); } class NodeScriptGenerator extends ScriptGenerator { public NodeScriptGenerator(String opKey, String nodeId, Alien4CloudApplication toscaApplication, String computeName, String expandedFolder) { super(opKey, nodeId, toscaApplication, computeName, expandedFolder); } @Override Object getScript(ImplementationArtifact artifact, Operation op) { String script = getScript(artifact); return buildExportStatements(op, script).or(script); } @Override Operation getOperation() { return getStandardInterfaceOperationsMap(nodeId, toscaApplication).get(opKey); } @Override protected Optional resolve(Map inputParameters, String key, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates) { return Alien4CloudFacade.this.resolve(inputParameters, key, paasNodeTemplate, builtPaaSNodeTemplates, toscaApplication.getKeywordMap(nodeId)); } } class RelationshipScriptGenerator extends ScriptGenerator { private ToscaApplication.Relationship relationship; private RelationshipTemplate relationshipTemplate; public RelationshipScriptGenerator(String opKey, Alien4CloudApplication toscaApplication, ToscaApplication.Relationship relationship, String computeName, String expandedFolder) { super(opKey, relationship.getSourceNodeId(), toscaApplication, computeName, expandedFolder); this.relationship = relationship; } @Override Object getScript(ImplementationArtifact artifact, Operation op) { Optional optionalRelationshipTemplate = Optional.fromNullable(toscaApplication.getNodeTemplate(nodeId).getRelationships().get(relationship.getRelationshipId())); if (!optionalRelationshipTemplate.isPresent()) { LOG.warn("Unsupported operation implementation for " + op.getDescription() + ": no relationship template"); return null; } this.relationshipTemplate = optionalRelationshipTemplate.get(); String script = getScript(artifact); return buildExportStatements(op, script).or(script); } @Override Operation getOperation() { return getConfigureInterfaceOperationsMap(toscaApplication, relationship).get(opKey); } @Override protected Optional resolve(Map inputParameters, String key, PaaSNodeTemplate paasNodeTemplate, Map builtPaaSNodeTemplates) { PaaSRelationshipTemplate paaSRelationshipTemplate = paasNodeTemplate.getRelationshipTemplate(relationship.getRelationshipId(), nodeId); Map keywordMap = toscaApplication.getKeywordMap(toscaApplication.getNodeTemplate(nodeId), relationshipTemplate); return Alien4CloudFacade.this.resolve(inputParameters, key, paaSRelationshipTemplate, builtPaaSNodeTemplates, keywordMap); } } }