<commit_before>package org.opentosca.bus.management.service.impl;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.ProducerTemplate;
import org.apache.commons.lang3.StringUtils;
import org.opentosca.bus.management.deployment.plugin.IManagementBusDeploymentPluginService;
import org.opentosca.bus.management.header.MBHeader;
import org.opentosca.bus.management.invocation.plugin.IManagementBusInvocationPluginService;
import org.opentosca.bus.management.invocation.plugin.script.ManagementBusInvocationPluginScript;
import org.opentosca.bus.management.service.IManagementBusService;
import org.opentosca.bus.management.service.impl.collaboration.Constants;
import org.opentosca.bus.management.service.impl.collaboration.DeploymentDistributionDecisionMaker;
import org.opentosca.bus.management.service.impl.servicehandler.ServiceHandler;
import org.opentosca.bus.management.service.impl.util.DeploymentPluginCapabilityChecker;
import org.opentosca.bus.management.service.impl.util.ParameterHandler;
import org.opentosca.bus.management.utils.MBUtils;
import org.opentosca.container.core.common.Settings;
import org.opentosca.container.core.engine.IToscaEngineService;
import org.opentosca.container.core.model.AbstractArtifact;
import org.opentosca.container.core.model.csar.id.CSARID;
import org.opentosca.container.core.model.endpoint.wsdl.WSDLEndpoint;
import org.opentosca.container.core.next.model.NodeTemplateInstance;
import org.opentosca.container.core.service.ICoreEndpointService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Engine for delegating invoke-requests of implementation artifacts or plans to matching
 * plug-ins.<br>
 * <br>
 *
 * Copyright 2013 IAAS University of Stuttgart <br>
 * <br>
 *
 * The engine gets the invoke-request as a camel exchange object with all needed parameters (e.g.
 * CSARID, ServiceTemplateID,...) in the header and the actual invoke message in the body of it. In
 * case of invoking an operation of an implementation artifact, the engine identify with help of the
 * ToscaEngine and the parameters from the header the right implementation artifact. Via
 * EndpointService the engine determine the endpoint of the implementation artifact or the plan. The
 * engine also handles the plug-ins. To determine which plug-in can execute the invoke-request, the
 * engine needs a specified property like <tt>{@literal <}namespace:InvocationType{@literal >}...
 * {@literal <}/namespace:InvocationType{@literal >}</tt>. The engine also can update request
 * parameters from stored InstanceData.
 *
 * TODO: adapt comment to new functionalities
 *
 * TODO: undeployment logic
 *
 * @see IManagementBusInvocationPluginService
 * @see IToscaEngineService
 * @see ICoreEndpointService
 *
 * @author <NAME> - <EMAIL>
 *
 *
 */

public class ManagementBusServiceImpl implements IManagementBusService {

    private static String BPMNNS = "http://www.omg.org/spec/BPMN/20100524/MODEL";

    private final static Logger LOG = LoggerFactory.getLogger(ManagementBusServiceImpl.class);

    private static Map<String, Object> locks = new HashMap<>();

    @Override
    public void invokeIA(Exchange exchange) {

        ManagementBusServiceImpl.LOG.debug("Starting Management Bus: InvokeIA");

        final Message message = exchange.getIn();

        final CSARID csarID = message.getHeader(MBHeader.CSARID.toString(), CSARID.class);
        ManagementBusServiceImpl.LOG.debug("CSARID: {}", csarID.toString());

        final URI serviceInstanceID = message.getHeader(MBHeader.SERVICEINSTANCEID_URI.toString(), URI.class);
        ManagementBusServiceImpl.LOG.debug("serviceInstanceID: {}", serviceInstanceID);

        final QName serviceTemplateID = message.getHeader(MBHeader.SERVICETEMPLATEID_QNAME.toString(), QName.class);
        ManagementBusServiceImpl.LOG.debug("serviceTemplateID: {}", serviceTemplateID);

        final String nodeTemplateID = message.getHeader(MBHeader.NODETEMPLATEID_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("nodeTemplateID: {}", nodeTemplateID);

        final String relationshipTemplateID =
            message.getHeader(MBHeader.RELATIONSHIPTEMPLATEID_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("relationshipTemplateID: {}", relationshipTemplateID);

        final String neededInterface = message.getHeader(MBHeader.INTERFACENAME_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("Interface: {}", neededInterface);

        final String neededOperation = message.getHeader(MBHeader.OPERATIONNAME_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("Operation: {}", neededOperation);

        // host name of the container that triggered the IA invocation
        final String triggeringContainer = Settings.OPENTOSCA_CONTAINER_HOSTNAME;
        message.setHeader(MBHeader.TRIGGERINGCONTAINER_STRING.toString(), triggeringContainer);

        // get the ServiceTemplateInstance ID Long from the serviceInstanceID URI
        Long serviceTemplateInstanceID = null;
        if (serviceInstanceID != null) {
            try {
                serviceTemplateInstanceID =
                    Long.parseLong(StringUtils.substringAfterLast(serviceInstanceID.toString(), "/"));
                ManagementBusServiceImpl.LOG.debug("ServiceTemplateInstance ID: {}", serviceTemplateInstanceID);
            }
            catch (final NumberFormatException e) {
                ManagementBusServiceImpl.LOG.warn("Unable to parse ServiceTemplateInstance ID out of serviceInstanceID: {}",
                                                  serviceInstanceID);
            }
        } else {
            ManagementBusServiceImpl.LOG.warn("Unable to parse ServiceTemplateInstance ID out of serviceInstanceID because it is null!");
        }

        // operation invocation is only possible with given ServiceTemplateInstance ID
        if (serviceTemplateInstanceID != null) {

            boolean wasFound = false;
            String deploymentType = null;
            String invocationType = null;
            String deploymentLocation = null;

            if (nodeTemplateID != null) {
                // handle operations on NodeTemplates
                ManagementBusServiceImpl.LOG.debug("Invoking operation on NodeTemplate: {}", nodeTemplateID);

                // retrieve the NodeTemplateInstance for the operation call
                final NodeTemplateInstance nodeTemplateInstance =
                    MBUtils.getNodeTemplateInstance(serviceTemplateInstanceID, nodeTemplateID);


                if (nodeTemplateInstance != null) {
                    ManagementBusServiceImpl.LOG.debug("Operation belongs to NodeTemplateInstance with ID: {}",
                                                       nodeTemplateInstance.getId());

                    // get NodeType of the NodeTemplateInstance
                    final QName nodeTypeID = nodeTemplateInstance.getTemplateType();
                    ManagementBusServiceImpl.LOG.debug("NodeType: {}", nodeTypeID);
                    message.setHeader(MBHeader.NODETYPEID_QNAME.toString(), nodeTypeID);

                    // update inputParams with instance data
                    if (message.getBody() instanceof HashMap) {

                        @SuppressWarnings("unchecked")
                        HashMap<String, String> inputParams = (HashMap<String, String>) message.getBody();

                        inputParams = ParameterHandler.updateInputParams(inputParams, csarID, nodeTemplateInstance,
                                                                         neededInterface, neededOperation);
                        message.setBody(inputParams);

                    } else {
                        ManagementBusServiceImpl.LOG.warn("There are no input parameters specified.");
                    }

                    // check whether operation has output parameters
                    final boolean hasOutputParams =
                        ServiceHandler.toscaEngineService.hasOperationOfANodeTypeSpecifiedOutputParams(csarID,
                                                                                                       nodeTypeID, neededInterface, neededOperation);
                    message.setHeader(MBHeader.HASOUTPUTPARAMS_BOOLEAN.toString(), hasOutputParams);

                    ManagementBusServiceImpl.LOG.debug("Getting NodeTypeImplementations of NodeType: {} from CSAR: {}",
                                                       nodeTypeID, csarID);

                    final List<QName> nodeTypeImplementationIDs =
                        ServiceHandler.toscaEngineService.getNodeTypeImplementationsOfNodeType(csarID, nodeTypeID);
                    ManagementBusServiceImpl.LOG.debug("List of NodeTypeImplementations: {}",
                                                       nodeTypeImplementationIDs.toString());

                    // Search for an IA that implements the right operation and which is deployable
                    // and invokable by plug-ins. The jump-Label is used to stop both loops at once
                    // when the IA is found.
                    searchIA: for (final QName nodeTypeImplementationID : nodeTypeImplementationIDs) {
                        ManagementBusServiceImpl.LOG.debug("Looking for Implementation Artifacts in NodeTypeImplementation: {}",
                                                           nodeTypeImplementationID.toString());

                        message.setHeader(MBHeader.NODETYPEIMPLEMENTATIONID_QNAME.toString(), nodeTypeImplementationID);

                        // get all IAs of the current NodeTypeImplementation
                        final List<String> implementationArtifactNames =
                            ServiceHandler.toscaEngineService.getImplementationArtifactNamesOfNodeTypeImplementation(csarID,
                                                                                                                     nodeTypeImplementationID);

                        ManagementBusServiceImpl.LOG.debug("List of Implementation Artifacts: {}",
                                                           implementationArtifactNames.toString());

                        for (final String implementationArtifactName : implementationArtifactNames) {

                            ManagementBusServiceImpl.LOG.debug("Trying to invoke Implementation Artifact: {}",
                                                               implementationArtifactName);

                            // check if requested interface/operation is provided
                            if (isCorrectIA(csarID, nodeTypeID, nodeTypeImplementationID, null, null,
                                            implementationArtifactName, neededOperation, neededInterface)) {

                                message.setHeader(MBHeader.IMPLEMENTATIONARTIFACTNAME_STRING.toString(),
                                                  implementationArtifactName);

                                // get ArtifactTemplate and ArtifactType of the IA
                                final QName artifactTemplateID =
                                    ServiceHandler.toscaEngineService.getArtifactTemplateOfAImplementationArtifactOfANodeTypeImplementation(csarID,
                                                                                                                                            nodeTypeImplementationID, implementationArtifactName);

                                final String artifactType = ServiceHandler.toscaEngineService
                                                                                             .getArtifactTypeOfAImplementationArtifactOfANodeTypeImplementation(csarID,
                                                                                                                                                                nodeTypeImplementationID,
                                                                                                                                                                implementationArtifactName)
                                                                                             .toString();

                                ManagementBusServiceImpl.LOG.debug("ArtifactType: {}", artifactType);
                                ManagementBusServiceImpl.LOG.debug("ArtifactTemplate: {}",
                                                                   artifactTemplateID.toString());

                                message.setHeader(MBHeader.ARTIFACTTEMPLATEID_QNAME.toString(), artifactTemplateID);
                                message.setHeader(MBHeader.ARTIFACTTYPEID_STRING.toString(), artifactType);

                                // retrieve deployment and invocation type for the IA
                                deploymentType = hasSupportedDeploymentType(artifactType);
                                invocationType = hasSupportedInvocationType(artifactType, csarID, artifactTemplateID);

                                // IA invocation can only continue if deployment and invocation type
                                // are supported by a plug-in
                                if (deploymentType != null) {
                                    if (invocationType != null) {
                                        ManagementBusServiceImpl.LOG.debug("Deployment type {} and invocation type {} are supported.",
                                                                           deploymentType, invocationType);

                                        // retrieve portType property if specified
                                        final QName portType = getPortTypeQName(csarID, artifactTemplateID);
                                        message.setHeader(MBHeader.PORTTYPE_QNAME.toString(), portType);

                                        // retrieve specific content for the IA if defined and add
                                        // to the headers
                                        exchange = addSpecificContent(exchange, csarID, nodeTypeImplementationID,
                                                                      implementationArtifactName);

                                        // host name of the container where the IA has to be
                                        // deployed
                                        deploymentLocation =
                                            DeploymentDistributionDecisionMaker.getDeploymentLocation(nodeTemplateInstance);
                                        message.setHeader(MBHeader.DEPLOYMENTLOCATION_STRING.toString(),
                                                          deploymentLocation);
                                        ManagementBusServiceImpl.LOG.debug("Host name of responsible OpenTOSCA Container: {}",
                                                                           deploymentLocation);

                                        // String that identifies an IA uniquely for synchronization
                                        final String identifier = triggeringContainer + "/" + deploymentLocation + "/"
                                            + nodeTypeImplementationID.toString() + "/" + implementationArtifactName;

                                        // Prevent two threads from trying to deploy the same IA<commit_msg>Set invocation type as header in the MB<commit_after>package org.opentosca.bus.management.service.impl;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.ProducerTemplate;
import org.apache.commons.lang3.StringUtils;
import org.opentosca.bus.management.deployment.plugin.IManagementBusDeploymentPluginService;
import org.opentosca.bus.management.header.MBHeader;
import org.opentosca.bus.management.invocation.plugin.IManagementBusInvocationPluginService;
import org.opentosca.bus.management.invocation.plugin.script.ManagementBusInvocationPluginScript;
import org.opentosca.bus.management.service.IManagementBusService;
import org.opentosca.bus.management.service.impl.collaboration.Constants;
import org.opentosca.bus.management.service.impl.collaboration.DeploymentDistributionDecisionMaker;
import org.opentosca.bus.management.service.impl.servicehandler.ServiceHandler;
import org.opentosca.bus.management.service.impl.util.DeploymentPluginCapabilityChecker;
import org.opentosca.bus.management.service.impl.util.ParameterHandler;
import org.opentosca.bus.management.utils.MBUtils;
import org.opentosca.container.core.common.Settings;
import org.opentosca.container.core.engine.IToscaEngineService;
import org.opentosca.container.core.model.AbstractArtifact;
import org.opentosca.container.core.model.csar.id.CSARID;
import org.opentosca.container.core.model.endpoint.wsdl.WSDLEndpoint;
import org.opentosca.container.core.next.model.NodeTemplateInstance;
import org.opentosca.container.core.service.ICoreEndpointService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Engine for delegating invoke-requests of implementation artifacts or plans to matching
 * plug-ins.<br>
 * <br>
 *
 * Copyright 2013 IAAS University of Stuttgart <br>
 * <br>
 *
 * The engine gets the invoke-request as a camel exchange object with all needed parameters (e.g.
 * CSARID, ServiceTemplateID,...) in the header and the actual invoke message in the body of it. In
 * case of invoking an operation of an implementation artifact, the engine identify with help of the
 * ToscaEngine and the parameters from the header the right implementation artifact. Via
 * EndpointService the engine determine the endpoint of the implementation artifact or the plan. The
 * engine also handles the plug-ins. To determine which plug-in can execute the invoke-request, the
 * engine needs a specified property like <tt>{@literal <}namespace:InvocationType{@literal >}...
 * {@literal <}/namespace:InvocationType{@literal >}</tt>. The engine also can update request
 * parameters from stored InstanceData.
 *
 * TODO: adapt comment to new functionalities
 *
 * TODO: undeployment logic
 *
 * @see IManagementBusInvocationPluginService
 * @see IToscaEngineService
 * @see ICoreEndpointService
 *
 * @author <NAME> - <EMAIL>
 *
 *
 */

public class ManagementBusServiceImpl implements IManagementBusService {

    private static String BPMNNS = "http://www.omg.org/spec/BPMN/20100524/MODEL";

    private final static Logger LOG = LoggerFactory.getLogger(ManagementBusServiceImpl.class);

    private static Map<String, Object> locks = new HashMap<>();

    @Override
    public void invokeIA(Exchange exchange) {

        ManagementBusServiceImpl.LOG.debug("Starting Management Bus: InvokeIA");

        final Message message = exchange.getIn();

        final CSARID csarID = message.getHeader(MBHeader.CSARID.toString(), CSARID.class);
        ManagementBusServiceImpl.LOG.debug("CSARID: {}", csarID.toString());

        final URI serviceInstanceID = message.getHeader(MBHeader.SERVICEINSTANCEID_URI.toString(), URI.class);
        ManagementBusServiceImpl.LOG.debug("serviceInstanceID: {}", serviceInstanceID);

        final QName serviceTemplateID = message.getHeader(MBHeader.SERVICETEMPLATEID_QNAME.toString(), QName.class);
        ManagementBusServiceImpl.LOG.debug("serviceTemplateID: {}", serviceTemplateID);

        final String nodeTemplateID = message.getHeader(MBHeader.NODETEMPLATEID_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("nodeTemplateID: {}", nodeTemplateID);

        final String relationshipTemplateID =
            message.getHeader(MBHeader.RELATIONSHIPTEMPLATEID_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("relationshipTemplateID: {}", relationshipTemplateID);

        final String neededInterface = message.getHeader(MBHeader.INTERFACENAME_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("Interface: {}", neededInterface);

        final String neededOperation = message.getHeader(MBHeader.OPERATIONNAME_STRING.toString(), String.class);
        ManagementBusServiceImpl.LOG.debug("Operation: {}", neededOperation);

        // host name of the container that triggered the IA invocation
        final String triggeringContainer = Settings.OPENTOSCA_CONTAINER_HOSTNAME;
        message.setHeader(MBHeader.TRIGGERINGCONTAINER_STRING.toString(), triggeringContainer);

        // get the ServiceTemplateInstance ID Long from the serviceInstanceID URI
        Long serviceTemplateInstanceID = null;
        if (serviceInstanceID != null) {
            try {
                serviceTemplateInstanceID =
                    Long.parseLong(StringUtils.substringAfterLast(serviceInstanceID.toString(), "/"));
                ManagementBusServiceImpl.LOG.debug("ServiceTemplateInstance ID: {}", serviceTemplateInstanceID);
            }
            catch (final NumberFormatException e) {
                ManagementBusServiceImpl.LOG.warn("Unable to parse ServiceTemplateInstance ID out of serviceInstanceID: {}",
                                                  serviceInstanceID);
            }
        } else {
            ManagementBusServiceImpl.LOG.warn("Unable to parse ServiceTemplateInstance ID out of serviceInstanceID because it is null!");
        }

        // operation invocation is only possible with given ServiceTemplateInstance ID
        if (serviceTemplateInstanceID != null) {

            boolean wasFound = false;
            String deploymentType = null;
            String invocationType = null;
            String deploymentLocation = null;

            if (nodeTemplateID != null) {
                // handle operations on NodeTemplates
                ManagementBusServiceImpl.LOG.debug("Invoking operation on NodeTemplate: {}", nodeTemplateID);

                // retrieve the NodeTemplateInstance for the operation call
                final NodeTemplateInstance nodeTemplateInstance =
                    MBUtils.getNodeTemplateInstance(serviceTemplateInstanceID, nodeTemplateID);


                if (nodeTemplateInstance != null) {
                    ManagementBusServiceImpl.LOG.debug("Operation belongs to NodeTemplateInstance with ID: {}",
                                                       nodeTemplateInstance.getId());

                    // get NodeType of the NodeTemplateInstance
                    final QName nodeTypeID = nodeTemplateInstance.getTemplateType();
                    ManagementBusServiceImpl.LOG.debug("NodeType: {}", nodeTypeID);
                    message.setHeader(MBHeader.NODETYPEID_QNAME.toString(), nodeTypeID);

                    // update inputParams with instance data
                    if (message.getBody() instanceof HashMap) {

                        @SuppressWarnings("unchecked")
                        HashMap<String, String> inputParams = (HashMap<String, String>) message.getBody();

                        inputParams = ParameterHandler.updateInputParams(inputParams, csarID, nodeTemplateInstance,
                                                                         neededInterface, neededOperation);
                        message.setBody(inputParams);

                    } else {
                        ManagementBusServiceImpl.LOG.warn("There are no input parameters specified.");
                    }

                    // check whether operation has output parameters
                    final boolean hasOutputParams =
                        ServiceHandler.toscaEngineService.hasOperationOfANodeTypeSpecifiedOutputParams(csarID,
                                                                                                       nodeTypeID, neededInterface, neededOperation);
                    message.setHeader(MBHeader.HASOUTPUTPARAMS_BOOLEAN.toString(), hasOutputParams);

                    ManagementBusServiceImpl.LOG.debug("Getting NodeTypeImplementations of NodeType: {} from CSAR: {}",
                                                       nodeTypeID, csarID);

                    final List<QName> nodeTypeImplementationIDs =
                        ServiceHandler.toscaEngineService.getNodeTypeImplementationsOfNodeType(csarID, nodeTypeID);
                    ManagementBusServiceImpl.LOG.debug("List of NodeTypeImplementations: {}",
                                                       nodeTypeImplementationIDs.toString());

                    // Search for an IA that implements the right operation and which is deployable
                    // and invokable by plug-ins. The jump-Label is used to stop both loops at once
                    // when the IA is found.
                    searchIA: for (final QName nodeTypeImplementationID : nodeTypeImplementationIDs) {
                        ManagementBusServiceImpl.LOG.debug("Looking for Implementation Artifacts in NodeTypeImplementation: {}",
                                                           nodeTypeImplementationID.toString());

                        message.setHeader(MBHeader.NODETYPEIMPLEMENTATIONID_QNAME.toString(), nodeTypeImplementationID);

                        // get all IAs of the current NodeTypeImplementation
                        final List<String> implementationArtifactNames =
                            ServiceHandler.toscaEngineService.getImplementationArtifactNamesOfNodeTypeImplementation(csarID,
                                                                                                                     nodeTypeImplementationID);

                        ManagementBusServiceImpl.LOG.debug("List of Implementation Artifacts: {}",
                                                           implementationArtifactNames.toString());

                        for (final String implementationArtifactName : implementationArtifactNames) {

                            ManagementBusServiceImpl.LOG.debug("Trying to invoke Implementation Artifact: {}",
                                                               implementationArtifactName);

                            // check if requested interface/operation is provided
                            if (isCorrectIA(csarID, nodeTypeID, nodeTypeImplementationID, null, null,
                                            implementationArtifactName, neededOperation, neededInterface)) {

                                message.setHeader(MBHeader.IMPLEMENTATIONARTIFACTNAME_STRING.toString(),
                                                  implementationArtifactName);

                                // get ArtifactTemplate and ArtifactType of the IA
                                final QName artifactTemplateID =
                                    ServiceHandler.toscaEngineService.getArtifactTemplateOfAImplementationArtifactOfANodeTypeImplementation(csarID,
                                                                                                                                            nodeTypeImplementationID, implementationArtifactName);

                                final String artifactType = ServiceHandler.toscaEngineService
                                                                                             .getArtifactTypeOfAImplementationArtifactOfANodeTypeImplementation(csarID,
                                                                                                                                                                nodeTypeImplementationID,
                                                                                                                                                                implementationArtifactName)
                                                                                             .toString();

                                ManagementBusServiceImpl.LOG.debug("ArtifactType: {}", artifactType);
                                ManagementBusServiceImpl.LOG.debug("ArtifactTemplate: {}",
                                                                   artifactTemplateID.toString());

                                message.setHeader(MBHeader.ARTIFACTTEMPLATEID_QNAME.toString(), artifactTemplateID);
                                message.setHeader(MBHeader.ARTIFACTTYPEID_STRING.toString(), artifactType);

                                // retrieve deployment and invocation type for the IA
                                deploymentType = hasSupportedDeploymentType(artifactType);
                                invocationType = hasSupportedInvocationType(artifactType, csarID, artifactTemplateID);

                                // IA invocation can only continue if deployment and invocation type
                                // are supported by a plug-in
                                if (deploymentType != null) {
                                    if (invocationType != null) {
                                        ManagementBusServiceImpl.LOG.debug("Deployment type {} and invocation type {} are supported.",
                                                                           deploymentType, invocationType);
                                        message.setHeader(MBHeader.INVOCATIONTYPE_STRING.toString(), invocationType);

                                        // retrieve portType property if specified
                                        final QName portType = getPortTypeQName(csarID, artifactTemplateID);
                                        message.setHeader(MBHeader.PORTTYPE_QNAME.toString(), portType);

                                        // retrieve specific content for the IA if defined and add
                                        // to the headers
                                        exchange = addSpecificContent(exchange, csarID, nodeTypeImplementationID,
                                                                      implementationArtifactName);

                                        // host name of the container where the IA has to be
                                        // deployed
                                        deploymentLocation =
                                            DeploymentDistributionDecisionMaker.getDeploymentLocation(nodeTemplateInstance);
                                        message.setHeader(MBHeader.DEPLOYMENTLOCATION_STRING.toString(),
                                                          deploymentLocation);
                                        ManagementBusServiceImpl.LOG.debug("Host name of responsible OpenTOSCA Container: {}",
                                                                           deploymentLocation);

                                        // String that identifies an IA uniquely for synchronization
                                        final String identifier = triggeringContainer + "/" + deploymentLocation + "/"
                                            + nodeTypeImplementationID.toString() + "/" + implementationArtifactName;

                                        // Prevent two threads from trying to deploy the same IA
{'fraction_non_alphanumeric': 0.06696709945796042, 'fraction_numerical': 0.0011345014496407413, 'mean_word_length': 1.784329209441081, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 211, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6726612', 'n_tokens_mistral': 6618, 'n_tokens_neox': 6349, 'n_words': 1490}