diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index cfcff6618..df8c5b8e9 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -31,77 +31,3 @@ jobs: with: project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} coverage-reports: org.opentosca.container.reporting/target/site/jacoco-aggregate/jacoco.xml - - tests: - strategy: - matrix: - test: - - AdaptMultiMyTinyToDoIntegrationTest - - ApacheWebAppIntegrationTest - - ConnectToIntegrationTest - - MigrateMyTinyToDo2MultiMyTinyToDoIntegrationTest - - MultiMyTinyToDoIntegrationTest - - MyTinyToDoBPMNIntegrationTest - - MyTinyToDoIntegrationTest - #- MyTinyToDoSqlIntegrationTest - #- PlanQKServiceIntegrationTest - - QHAnaTest - runs-on: ubuntu-latest - timeout-minutes: 80 - needs: build - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: 17 - cache: maven - distribution: temurin - - name: Check out TOSCA internal repository - uses: actions/checkout@v3 - with: - repository: OpenTOSCA/tosca-definitions-test-applications - ref: 'main' - path: 'tosca-definitions-test-applications' - lfs: 'true' - - name: Copy TOSCA internal repository to tmp - run: cp -R $GITHUB_WORKSPACE/tosca-definitions-test-applications /tmp/ - - name: Show TOSCA internal repository content - run: ls -a /tmp/tosca-definitions-test-applications - - name: Setup Docker Remote API - run: sudo sed -ie "s@ExecStart=\/usr\/bin\/dockerd -H fd:\/\/@ExecStart=\/usr\/bin\/dockerd -H fd:\/\/ -H tcp:\/\/0.0.0.0:2375 -H unix:///var/run/docker.sock@g" /lib/systemd/system/docker.service - - name: Reload Daemons - run: sudo systemctl daemon-reload - - name: Restart Docker - run: sudo service docker restart - - name: Configure runtime with test properties - run: cp test.properties ./org.opentosca.container.core/src/main/resources/application.properties - - name: Show application properties - run: cat ./org.opentosca.container.core/src/main/resources/application.properties - - name: Test Docker Remote API - run: curl -X GET http://localhost:2375/images/json - - name: Start test environment - run: docker-compose -f test.yml up -d - - name: Save engine-ia-java17 log to file - run: docker-compose -f test.yml logs -f engine-ia-java17 > engine-ia-java17.log & - - name: Save engine-ia-java8 log to file - run: docker-compose -f test.yml logs -f engine-ia-java8 > engine-ia-java8.log & - - name: Sleep for 120 seconds - uses: whatnick/wait-action@master - with: - time: '120s' - - name: Test with Maven - timeout-minutes: 60 - run: mvn -B -DfailIfNoTests=false -Dtest=org.opentosca.container.war.tests.${{ matrix.test }} test --file pom.xml --fail-at-end - env: - PlanqkApiKey: ${{ secrets.PLANQK_API_KEY }} - OrganizationID: "eecfa1d7-5f52-45d4-accc-b470ad05959f" - - name: Store engine-ia log - uses: actions/upload-artifact@v3 - if: ${{ always() }} - with: - name: engine-ia-log - path: | - engine-ia-java17.log - engine-ia-java8.log diff --git a/Dockerfile b/Dockerfile index e7777a075..dfe7c963b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ RUN rm /dev/random && ln -s /dev/urandom /dev/random WORKDIR /tmp/opentosca/container COPY . /tmp/opentosca/container -RUN apt-get update && apt-get -y install --no-install-recommends unzip=6.0-26ubuntu3 +RUN apt-get update && apt-get -y install --no-install-recommends unzip RUN mvn package -DskipTests=true -Dmaven.javadoc.skip=true -B \ && mkdir /tmp/build \ && unzip /tmp/opentosca/container/org.opentosca.container.war/target/OpenTOSCA-container.war -d /tmp/build/container diff --git a/org.opentosca.bus/org.opentosca.bus.management.deployment.plugin.tomcat/src/main/java/org/opentosca/bus/management/deployment/plugin/tomcat/ManagementBusDeploymentPluginTomcat.java b/org.opentosca.bus/org.opentosca.bus.management.deployment.plugin.tomcat/src/main/java/org/opentosca/bus/management/deployment/plugin/tomcat/ManagementBusDeploymentPluginTomcat.java index 66641e328..2acf3d106 100644 --- a/org.opentosca.bus/org.opentosca.bus.management.deployment.plugin.tomcat/src/main/java/org/opentosca/bus/management/deployment/plugin/tomcat/ManagementBusDeploymentPluginTomcat.java +++ b/org.opentosca.bus/org.opentosca.bus.management.deployment.plugin.tomcat/src/main/java/org/opentosca/bus/management/deployment/plugin/tomcat/ManagementBusDeploymentPluginTomcat.java @@ -1,11 +1,19 @@ package org.opentosca.bus.management.deployment.plugin.tomcat; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLConnection; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.nio.charset.StandardCharsets; @@ -319,7 +327,22 @@ private File getWarFile(final URL warURL) { // store WAR artifact as temporary file final File tempFile = File.createTempFile("Artifact", ".war"); tempFile.deleteOnExit(); - FileUtils.copyURLToFile(warURL, tempFile); + + URLConnection urlConn = warURL.openConnection(); + urlConn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"); + urlConn.setRequestProperty("Accept-Encoding", "gzip, deflate"); + urlConn.setRequestProperty("Accept-Language", "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"); + urlConn.setRequestProperty("Accept-Charset", "UTF-8"); + InputStream stream = urlConn.getInputStream(); + OutputStream os = new FileOutputStream(tempFile); + byte[] buffer = new byte[4096]; + int len; + while ((len = stream.read(buffer)) != -1) { + os.write(buffer, 0, len); + } + os.close(); + stream.close(); + return tempFile; } catch (final IOException e) { LOG.error("Failed to retrieve WAR-File: {}", e.getMessage()); diff --git a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/java/org/opentosca/bus/management/invocation/plugin/script/ManagementBusInvocationPluginScript.java b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/java/org/opentosca/bus/management/invocation/plugin/script/ManagementBusInvocationPluginScript.java index 27688c378..cf3892c40 100644 --- a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/java/org/opentosca/bus/management/invocation/plugin/script/ManagementBusInvocationPluginScript.java +++ b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/java/org/opentosca/bus/management/invocation/plugin/script/ManagementBusInvocationPluginScript.java @@ -290,15 +290,17 @@ private TNodeTemplate getNodeTemplate(Message message, Csar csar, TRelationshipT * @param operation The script service operation to check */ private void addOutputParametersToResultMap(final Map resultMap, final Object result, final TOperation operation) throws UnsupportedEncodingException { + LOG.debug("Checking if operation has output parameters to update: {}", operation.getName()); final boolean hasOutputParams = operation.getOutputParameters() != null; if (!hasOutputParams) { + LOG.debug("No output parameters defined!"); return; } + LOG.debug("Adding output parameters to the response message."); if (!(result instanceof HashMap)) { LOG.warn("Result of type {} not supported. The bus should return a HashMap as result class when it is used as input.", result.getClass()); return; } - LOG.debug("Adding output parameters to the response message."); final Map resultHashMap = (HashMap) result; // get ScriptResult part of the response which contains the parameters @@ -317,11 +319,15 @@ private void addOutputParametersToResultMap(final Map resultMap, // split result in line breaks as every parameter is returned in a separate "echo" command final String[] resultParameters = scriptResultString.split("[\\r\\n]+"); + LOG.debug("Searching for {} output parameters...", operation.getOutputParameters().size()); // add each parameter that is defined in the operation and passed back for (final TParameter outputParameter : operation.getOutputParameters()) { + LOG.debug("Searching for output parameter: {}", outputParameter.getName()); // we expect the outputparameters at the end of the result in multiple lines + LOG.debug("Found {} lines in script result...", resultParameters.length); for (int i = resultParameters.length - 1; i >= 0; i--) { if (resultParameters[i].startsWith(outputParameter.getName())) { + LOG.debug("Found parameter with given name: {}", outputParameter.getName()); final String value = resultParameters[i].substring(resultParameters[i].indexOf("=") + 1); LOG.debug("Adding parameter {} with value: {}", outputParameter, value); @@ -473,12 +479,17 @@ private String createArtifactTypeSpecificCommandString(final TArtifactType artif if (commandsString.contains("{{") && commandsString.contains("}}")) { LOG.debug("Replacing the placeholder of the generic command with properties data and/or provided input parameter..."); - final Map paramsMap; + Map paramsMap; if (params instanceof HashMap) { paramsMap = (HashMap) params; } else if (params instanceof Document) { final Document paramsDoc = (Document) params; - paramsMap = MBUtils.docToMap(paramsDoc, true); + paramsMap = new HashMap<>(); + try { + paramsMap = MBUtils.docToMap(paramsDoc, true); + } catch (Exception e) { + LOG.error("Error while parsing doc to map!"); + } } else { paramsMap = new HashMap<>(); } diff --git a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/resources/artifacttypes/Script.xml b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/resources/artifacttypes/Script.xml index 7701fee12..d87412838 100644 --- a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/resources/artifacttypes/Script.xml +++ b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.script/src/main/resources/artifacttypes/Script.xml @@ -5,6 +5,6 @@ chmod +x {TARGET_FILE_PATH} - CAN_SUDO=$(sudo -n uptime 2>&1|grep "load"|wc -l); if [ ${CAN_SUDO} -gt 0 ]; then sudo -E {DA_NAME_PATH_MAP}{INPUT_PARAMETER}{TARGET_FILE_PATH}; else {DA_NAME_PATH_MAP}{INPUT_PARAMETER}{TARGET_FILE_PATH}; fi + CAN_SUDO=$(sudo -n uptime 2>&1|grep "load"|wc -l); if [ ${CAN_SUDO} -gt 0 ]; then sudo -E {DA_NAME_PATH_MAP}{INPUT_PARAMETER} bash {TARGET_FILE_PATH}; else {DA_NAME_PATH_MAP}{INPUT_PARAMETER} bash {TARGET_FILE_PATH}; fi - \ No newline at end of file + diff --git a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.soaphttp/src/main/java/org/opentosca/bus/management/invocation/plugin/soaphttp/ManagementBusInvocationPluginSoapHttp.java b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.soaphttp/src/main/java/org/opentosca/bus/management/invocation/plugin/soaphttp/ManagementBusInvocationPluginSoapHttp.java index a6b5a3289..83b95c517 100644 --- a/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.soaphttp/src/main/java/org/opentosca/bus/management/invocation/plugin/soaphttp/ManagementBusInvocationPluginSoapHttp.java +++ b/org.opentosca.bus/org.opentosca.bus.management.invocation.plugin.soaphttp/src/main/java/org/opentosca/bus/management/invocation/plugin/soaphttp/ManagementBusInvocationPluginSoapHttp.java @@ -237,7 +237,12 @@ public Exchange invoke(Exchange exchange) { if (exchange.getIn().getHeader("ParamsMode") != null && exchange.getIn().getHeader("ParamsMode").equals("HashMap")) { LOG.debug("Transforming Document to HashMap..."); - final HashMap responseMap = MBUtils.docToMap(response, false); + HashMap responseMap = new HashMap<>(); + try { + responseMap = MBUtils.docToMap(response, false); + } catch (Exception e) { + LOG.error("Error while parsing doc to map!"); + } exchange.getIn().setBody(responseMap); } else { exchange.getIn().setBody(response); diff --git a/org.opentosca.bus/org.opentosca.bus.management.service/src/main/java/org/opentosca/bus/management/service/impl/ManagementBusServiceImpl.java b/org.opentosca.bus/org.opentosca.bus.management.service/src/main/java/org/opentosca/bus/management/service/impl/ManagementBusServiceImpl.java index 346fa1b0d..2a738adea 100644 --- a/org.opentosca.bus/org.opentosca.bus.management.service/src/main/java/org/opentosca/bus/management/service/impl/ManagementBusServiceImpl.java +++ b/org.opentosca.bus/org.opentosca.bus.management.service/src/main/java/org/opentosca/bus/management/service/impl/ManagementBusServiceImpl.java @@ -4,15 +4,18 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -62,13 +65,17 @@ import org.opentosca.container.core.model.csar.CsarId; import org.opentosca.container.core.next.model.Endpoint; import org.opentosca.container.core.next.model.NodeTemplateInstance; +import org.opentosca.container.core.next.model.NodeTemplateInstanceProperty; import org.opentosca.container.core.next.model.PlanInstance; import org.opentosca.container.core.next.model.PlanInstanceEvent; import org.opentosca.container.core.next.model.PlanLanguage; import org.opentosca.container.core.next.model.PlanType; import org.opentosca.container.core.next.model.RelationshipTemplateInstance; import org.opentosca.container.core.next.model.ServiceTemplateInstance; +import org.opentosca.container.core.next.repository.NodeTemplateInstanceRepository; import org.opentosca.container.core.next.repository.PlanInstanceRepository; +import org.opentosca.container.core.next.repository.RelationshipTemplateInstanceRepository; +import org.opentosca.container.core.next.repository.ServiceTemplateInstanceRepository; import org.opentosca.container.core.next.trigger.SituationTriggerInstanceListener; import org.opentosca.container.core.plan.ChoreographyHandler; import org.opentosca.container.core.service.CsarStorageService; @@ -79,6 +86,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; +import static org.opentosca.container.core.convention.Types.hostedOnRelationType; + /** * Engine for delegating invoke-requests of implementation artifacts or plans to matching plug-ins.
*
@@ -135,14 +144,19 @@ public class ManagementBusServiceImpl implements IManagementBusService { private final PlanInstanceHandler planInstanceHandler; private final PlanInstanceRepository planInstanceRepository; + private final NodeTemplateInstanceRepository nodeTemplateInstanceRepository; + private final ServiceTemplateInstanceRepository serviceTemplateInstanceRepository; + @Inject public ManagementBusServiceImpl(DeploymentDistributionDecisionMaker decisionMaker, CollaborationContext collaborationContext, ICoreEndpointService endpointService, ParameterHandler parameterHandler, PluginHandler pluginHandler, PluginRegistry pluginRegistry, DeploymentPluginCapabilityChecker capabilityChecker, CsarStorageService storage, ChoreographyHandler choreographyHandler, MBUtils mbUtils, - PlanInstanceHandler planInstanceHandler, PlanInstanceRepository planInstanceRepository) { + PlanInstanceHandler planInstanceHandler, PlanInstanceRepository planInstanceRepository, NodeTemplateInstanceRepository nodeTemplateInstanceRepository, ServiceTemplateInstanceRepository serviceTemplateInstanceRepository) { LOG.info("Instantiating ManagementBus Service"); + this.nodeTemplateInstanceRepository = nodeTemplateInstanceRepository; + this.serviceTemplateInstanceRepository = serviceTemplateInstanceRepository; this.planInstanceRepository = planInstanceRepository; this.planInstanceHandler = planInstanceHandler; this.mbUtils = mbUtils; @@ -1286,9 +1300,72 @@ private void handleResponse(Exchange exchange) { if (exchange == null) { return; } + + // get message to retrieve headers and result body + Message in = exchange.getIn(); + // Response message back to caller. final ProducerTemplate template = this.collaborationContext.getProducer(); - final String caller = exchange.getIn().getHeader(MBHeader.APIID_STRING.toString(), String.class); + final String caller = in.getHeader(MBHeader.APIID_STRING.toString(), String.class); + + // check if IA invocation is performed and update properties + final String nodeTemplate = in.getHeader(MBHeader.NODETEMPLATEID_STRING.toString(), String.class); + final String nodeTemplateInstanceId = in.getHeader(MBHeader.NODEINSTANCEID_STRING.toString(), String.class); + if (Objects.nonNull(nodeTemplateInstanceId) && Objects.nonNull(nodeTemplate)) { + LOG.debug("Handling response for NodeTemplate {} and corresponding ID {}!", nodeTemplate, nodeTemplateInstanceId); + + // load NodeTemplateInstance and corresponding properties from repository + NodeTemplateInstance nodeTemplateInstance = nodeTemplateInstanceRepository.findWithPropertiesAndOutgoingById(Long.parseLong(nodeTemplateInstanceId)).get(); + Map properties = nodeTemplateInstance.getPropertiesAsMap(); + LOG.debug("Properties to update: {}", properties); + + if (in.getBody() instanceof HashMap) { + HashMap result = (HashMap) in.getBody(); + LOG.debug("Result is of type HashMap and contains properties: {}", result); + + if(result.containsKey("xml")) { + String xmlProperties = result.get("xml"); + LOG.debug("Found XML properties: {}", result); + + // update properties with the same name if defined at NodeTemplateInstance + for (Entry property : result.entrySet()) { + + LOG.debug("Checking if XML contains property with name: {}", property.getKey()); + if(xmlProperties.contains(property.getKey())) { + LOG.debug("Updating XML for property: {}", property.getValue()); + + // split string to adapt content + String[] propertyParts = xmlProperties.split(property.getKey()); + xmlProperties = propertyParts[0] + property.getKey() + ">" + property.getValue() + " propertySet = new HashSet<>(); + NodeTemplateInstanceProperty instanceProperty = new NodeTemplateInstanceProperty(); + instanceProperty.setNodeTemplateInstance(nodeTemplateInstance); + instanceProperty.setName("xml"); + instanceProperty.setValue(xmlProperties); + propertySet.add(instanceProperty); + nodeTemplateInstance.setProperties(propertySet); + } else { + LOG.debug("Result is not based on XML properties. Updating HashMap..."); + for (Entry property : result.entrySet()) { + LOG.debug("Searching for NodeTemplateInstance with given property name... "); + updateNodeTemplateInstances(nodeTemplateInstance, property); + } + } + nodeTemplateInstanceRepository.save(nodeTemplateInstance); + } else { + LOG.warn("Result is not of type HashMap, unable to parse result: {}", in.getBody().getClass()); + } + } else { + LOG.warn("Unable to find properties for NodeTemplate {} and corresponding ID {}", nodeTemplate, nodeTemplateInstanceId); + } if (caller == null) { // notably the Java API does not set the APIID, because it never uses the information returned. @@ -1303,6 +1380,71 @@ private void handleResponse(Exchange exchange) { } } + private void updateNodeTemplateInstances(NodeTemplateInstance nodeTemplateInstance, Entry property) { + LOG.debug("Trying to find NodeTemplateInstance with property name: {}", property.getKey()); + + ServiceTemplateInstance serviceTemplateInstance = serviceTemplateInstanceRepository.findWithNodeTemplateInstancesById(nodeTemplateInstance.getServiceTemplateInstance().getId()).get(); + for (NodeTemplateInstance instance : serviceTemplateInstance.getNodeTemplateInstances()) { + LOG.debug("Searching for NodeTemplateInstance with ID: {}", instance.getTemplateId()); + NodeTemplateInstance newNodeTemplateInstance = nodeTemplateInstanceRepository.findWithPropertiesAndOutgoingById(instance.getId()).get(); + + // get properties of connected NodeTemplateInstance + Collection properties = newNodeTemplateInstance.getProperties(); + LOG.debug("Found {} properties of NodeTemplateInstance: {}", properties.size(), properties); + for (NodeTemplateInstanceProperty nodeTemplateInstanceProperty : properties) { + LOG.debug("Found property with name: {}", nodeTemplateInstanceProperty.getName()); + if (property.getKey().equals(nodeTemplateInstanceProperty.getName())) { + LOG.debug("Found matching property. Changing value from {} to {}!", nodeTemplateInstanceProperty.getValue(), property.getValue()); + nodeTemplateInstanceProperty.setValue(property.getValue()); + newNodeTemplateInstance.setProperties(new HashSet<>(properties)); + nodeTemplateInstanceRepository.save(newNodeTemplateInstance); + + // abort once property is updated + return; + } + + // handle XML properties + if (nodeTemplateInstanceProperty.getName().equals("xml")) { + + LOG.debug("Checking if XML contains property with name: {}", property.getKey()); + + String xmlProperties = nodeTemplateInstanceProperty.getValue(); + LOG.debug("Found XML properties: {}", xmlProperties); + + if(xmlProperties.contains(property.getKey())) { + LOG.debug("Updating XML for property: {}", property.getValue()); + + // split string to adapt content + if (xmlProperties.contains("<" + property.getKey() + "/>")) { + String[] propertyParts = xmlProperties.split("<" + property.getKey() + "/>"); + xmlProperties = propertyParts[0] + "<" + property.getKey() + ">" + property.getValue() + "" + propertyParts[1]; + } else{ + String[] propertyParts = xmlProperties.split(property.getKey()); + xmlProperties = propertyParts[0] + property.getKey() + ">" + property.getValue() + " propertySet = new HashSet<>(); + NodeTemplateInstanceProperty instanceProperty = new NodeTemplateInstanceProperty(); + instanceProperty.setNodeTemplateInstance(newNodeTemplateInstance); + instanceProperty.setName("xml"); + instanceProperty.setType(nodeTemplateInstanceProperty.getType()); + instanceProperty.setValue(xmlProperties); + propertySet.add(instanceProperty); + newNodeTemplateInstance.setProperties(propertySet); + nodeTemplateInstanceRepository.save(newNodeTemplateInstance); + + // abort once property is updated + return; + } else { + LOG.debug("XML does not contain property with name: {}", property.getKey()); + } + } + } + } + LOG.debug("No NodeTemplateInstance with given property found. Aborting property update!"); + } + @Override public synchronized void addPartnerToReadyList(final String correlationID, final String partnerID) { activePartners.putIfAbsent(correlationID, new LinkedList()); diff --git a/org.opentosca.container.api/src/main/java/org/opentosca/container/api/controller/NodeTemplateInstanceController.java b/org.opentosca.container.api/src/main/java/org/opentosca/container/api/controller/NodeTemplateInstanceController.java index a959fe88d..47d07f418 100644 --- a/org.opentosca.container.api/src/main/java/org/opentosca/container/api/controller/NodeTemplateInstanceController.java +++ b/org.opentosca.container.api/src/main/java/org/opentosca/container/api/controller/NodeTemplateInstanceController.java @@ -191,7 +191,7 @@ public Response updateNodeTemplateInstanceState(@PathParam("id") final Long id, @Produces( {MediaType.APPLICATION_XML}) @ApiOperation(hidden = true, value = "") public Response getNodeTemplateInstanceProperties(@PathParam("id") final Long id) { - logger.debug("Invoking getNodeTemplateInstanceProperties"); + logger.debug("Invoking getNodeTemplateInstanceProperties for ID: {}", id); final Document properties = this.nodeTemplateInstanceService.getNodeTemplateInstancePropertiesDocument(id); if (properties == null) { diff --git a/org.opentosca.container.api/src/main/java/org/opentosca/container/api/dto/plan/PlanInstanceDTO.java b/org.opentosca.container.api/src/main/java/org/opentosca/container/api/dto/plan/PlanInstanceDTO.java index aec845716..a89d0263e 100644 --- a/org.opentosca.container.api/src/main/java/org/opentosca/container/api/dto/plan/PlanInstanceDTO.java +++ b/org.opentosca.container.api/src/main/java/org/opentosca/container/api/dto/plan/PlanInstanceDTO.java @@ -115,7 +115,9 @@ public static PlanInstanceDTO convert(final PlanInstance object) { dto.setCorrelationId(object.getCorrelationId()); - dto.setServiceTemplateInstanceId(object.getServiceTemplateInstance().getId()); + if (object.getServiceTemplateInstance() != null) { + dto.setServiceTemplateInstanceId(object.getServiceTemplateInstance().getId()); + } dto.setType(object.getType()); dto.setLogs(new ArrayList<>()); diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Types.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Types.java index 14c99ae1f..30e8bbad9 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Types.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Types.java @@ -27,6 +27,10 @@ public class Types { new QName("http://opentosca.org/nodetypes", "OpenStack_Train-w1"); public final static QName openStackTrainNodeType = new QName("http://opentosca.org/nodetypes", "OpenStack_15-Train-w1"); + + public final static QName ec2NEWNodeType = + new QName("http://opentosca.org/nodetypes", "EC2-w1"); + public final static QName vmWareVsphere55NodeType = new QName("http://opentosca.org/nodetypes", "VSphere_5.5"); public final static QName amazonEc2NodeType = new QName("http://opentosca.org/NodeTypes", "AmazonEC2"); diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Utils.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Utils.java index 9c8913125..621143c26 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Utils.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/convention/Utils.java @@ -97,6 +97,7 @@ public static boolean isCloudProvider(QName nodeType) { || nodeType.equals(Types.openStackLiberty12NodeType) || nodeType.equals(Types.openStackTrainNodeType_legacy) || nodeType.equals(Types.openStackTrainNodeType) + || nodeType.equals(Types.ec2NEWNodeType) || ( nodeType.getNamespaceURI().equals(Types.openStackLiberty12NodeTypeGenerated.getNamespaceURI()) && (nodeType.getLocalPart().startsWith(Types.openStackLiberty12NodeTypeGenerated.getLocalPart()) diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/NodeTemplateInstanceRepository.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/NodeTemplateInstanceRepository.java index df620cc99..5c99e10a7 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/NodeTemplateInstanceRepository.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/NodeTemplateInstanceRepository.java @@ -26,6 +26,9 @@ public interface NodeTemplateInstanceRepository extends JpaRepository findByServiceTemplateInstanceAndTemplateId(ServiceTemplateInstance serviceTemplateInstance, String templateId); + @EntityGraph(attributePaths = {"properties"}) + Optional findById(Long id); + @EntityGraph(attributePaths = {"properties"}) Optional findWithPropertiesById(Long id); diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/RelationshipTemplateInstanceRepository.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/RelationshipTemplateInstanceRepository.java index afcd6c4dc..5d577edae 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/RelationshipTemplateInstanceRepository.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/repository/RelationshipTemplateInstanceRepository.java @@ -12,6 +12,6 @@ public interface RelationshipTemplateInstanceRepository extends JpaRepository findByTemplateId(String templateId); - @EntityGraph(attributePaths = {"properties"}) + @EntityGraph(attributePaths = {"properties", "target"}) RelationshipTemplateInstance findWithPropertiesById(Long id); } diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/services/instances/ServiceTemplateInstanceService.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/services/instances/ServiceTemplateInstanceService.java index c4b01928f..efffd5101 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/services/instances/ServiceTemplateInstanceService.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/services/instances/ServiceTemplateInstanceService.java @@ -16,6 +16,7 @@ import org.opentosca.container.core.next.model.ServiceTemplateInstance; import org.opentosca.container.core.next.model.ServiceTemplateInstanceProperty; import org.opentosca.container.core.next.model.ServiceTemplateInstanceState; +import org.opentosca.container.core.next.repository.NodeTemplateInstanceRepository; import org.opentosca.container.core.next.repository.PlanInstanceRepository; import org.opentosca.container.core.next.repository.ServiceTemplateInstanceRepository; import org.opentosca.container.core.next.services.templates.ServiceTemplateService; @@ -37,18 +38,21 @@ public class ServiceTemplateInstanceService { private final PlanInstanceRepository planInstanceRepository; private final PlanInstanceService planInstanceService; + private final NodeTemplateInstanceRepository nodeTemplateInstanceRepository; + private final PropertyMappingsHelper helper; public ServiceTemplateInstanceService(ServiceTemplateInstanceRepository serviceTemplateInstanceRepository, ServiceTemplateService serviceTemplateService, PlanInstanceRepository planInstanceRepository, - PlanInstanceService planInstanceService, CsarStorageService storage) { + PlanInstanceService planInstanceService, NodeTemplateInstanceRepository nodeTemplateInstanceRepository, CsarStorageService storage) { this.serviceTemplateInstanceRepository = serviceTemplateInstanceRepository; this.serviceTemplateService = serviceTemplateService; this.planInstanceRepository = planInstanceRepository; this.planInstanceService = planInstanceService; + this.nodeTemplateInstanceRepository = nodeTemplateInstanceRepository; - helper = new PropertyMappingsHelper(storage); + helper = new PropertyMappingsHelper(storage, this.nodeTemplateInstanceRepository); } /** diff --git a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/utils/PropertyMappingsHelper.java b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/utils/PropertyMappingsHelper.java index e7be745e4..1a94ab1a9 100644 --- a/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/utils/PropertyMappingsHelper.java +++ b/org.opentosca.container.core/src/main/java/org/opentosca/container/core/next/utils/PropertyMappingsHelper.java @@ -25,6 +25,7 @@ import org.opentosca.container.core.next.model.NodeTemplateInstanceProperty; import org.opentosca.container.core.next.model.ServiceTemplateInstance; import org.opentosca.container.core.next.model.ServiceTemplateInstanceProperty; +import org.opentosca.container.core.next.repository.NodeTemplateInstanceRepository; import org.opentosca.container.core.service.CsarStorageService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,12 +34,18 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import static org.opentosca.container.core.next.model.NodeTemplateInstanceState.STARTED; + public class PropertyMappingsHelper { private static final Logger logger = LoggerFactory.getLogger(PropertyMappingsHelper.class); private final CsarStorageService storage; - public PropertyMappingsHelper(CsarStorageService storage) { + + private final NodeTemplateInstanceRepository nodeTemplateInstanceRepository; + + public PropertyMappingsHelper(CsarStorageService storage, NodeTemplateInstanceRepository nodeTemplateInstanceRepository) { this.storage = storage; + this.nodeTemplateInstanceRepository = nodeTemplateInstanceRepository; } /** @@ -110,18 +117,18 @@ private void updateServiceInstanceProperties(final ServiceTemplateInstance servi continue; } - final Document nodeProperties = new DocumentConverter().convertToEntityAttribute(firstProperty.get().getValue()); - final Element nodePropertiesRoot = (Element) nodeProperties.getFirstChild(); - final String nodeTemplatePropertyQuery = mapping.getTargetPropertyRef(); - final List nodePropertyElements = queryElementList(nodePropertiesRoot, nodeTemplatePropertyQuery); + if (mapping.getTargetPropertyRef().trim().split(".Properties.").length == 2) { + // "DSL" Query + final String[] queryParts = mapping.getTargetPropertyRef().trim().split(".Properties."); - if (nodePropertyElements.size() != 1) { - // skip this property, we expect only one - continue; - } + NodeTemplateInstance nodeTemplateInstance = getNodeInstanceWithName(serviceInstance.getNodeTemplateInstances(), queryParts[0]); + if (Objects.nonNull(nodeTemplateInstance)) { + final String propValue = fetchPropertyValueFromNodeInstance(nodeTemplateInstance, queryParts[1]); - // change the serviceTemplateProperty - serviceTemplatePropertyElements.get(0).setTextContent(nodePropertyElements.get(0).getTextContent()); + // change the serviceTemplateProperty + serviceTemplatePropertyElements.get(0).setTextContent(propValue); + } + } } } @@ -200,16 +207,12 @@ private String generatePropertyValueFromConcatQuery(final String targetPropertyR if (functionPart.trim().startsWith("'")) { // string function part, just add to list augmentedFunctionParts.add(functionPart.trim()); - } else if (functionPart.trim().split("\\.").length == 3) { + } else if (functionPart.trim().split(".Properties.").length == 2) { // "DSL" Query - final String[] queryParts = functionPart.trim().split("\\."); - // fast check for validity - if (!queryParts[1].equals("Properties")) { - return null; - } + final String[] queryParts = functionPart.trim().split(".Properties."); final String nodeTemplateName = queryParts[0]; - final String propertyName = queryParts[2]; + final String propertyName = queryParts[1]; if (getNodeInstanceWithName(nodeInstance, nodeTemplateName) != null) { @@ -238,8 +241,8 @@ private NodeTemplateInstance getNodeInstanceWithName(final Collection - - org.opentosca - org.opentosca.broker.mqtt - ${project.version} - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - - - org.opentosca org.opentosca.container.war diff --git a/org.opentosca.container.war/pom.xml b/org.opentosca.container.war/pom.xml index c67cad9e3..f9eb23ded 100644 --- a/org.opentosca.container.war/pom.xml +++ b/org.opentosca.container.war/pom.xml @@ -459,22 +459,6 @@ - - org.opentosca - org.opentosca.broker.mqtt - ${project.version} - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - - diff --git a/org.opentosca.container.war/src/main/java/org/opentosca/container/war/Config.java b/org.opentosca.container.war/src/main/java/org/opentosca/container/war/Config.java index 1295e4d25..7321b91e4 100644 --- a/org.opentosca.container.war/src/main/java/org/opentosca/container/war/Config.java +++ b/org.opentosca.container.war/src/main/java/org/opentosca/container/war/Config.java @@ -4,7 +4,6 @@ import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; -import org.opentosca.broker.mqtt.BrokerSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -17,18 +16,10 @@ public class Config implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { LOGGER.info("STARTING APPLICATION CONTEXT CONFIGURATION FOR OPENTOSCA CONTAINER API"); - BrokerSupport mqttBroker = WebApplicationContextUtils - .getRequiredWebApplicationContext(event.getServletContext()) - .getBean(BrokerSupport.class); - mqttBroker.start(); } @Override public void contextDestroyed(ServletContextEvent event) { LOGGER.info("SHUTTING DOWN APPLICATION CONTEXT"); - BrokerSupport mqttBroker = WebApplicationContextUtils - .getRequiredWebApplicationContext(event.getServletContext()) - .getBean(BrokerSupport.class); - mqttBroker.stop(); } } diff --git a/org.opentosca.container.war/src/main/resources/logback.xml b/org.opentosca.container.war/src/main/resources/logback.xml index 274ee0954..37b3607b8 100644 --- a/org.opentosca.container.war/src/main/resources/logback.xml +++ b/org.opentosca.container.war/src/main/resources/logback.xml @@ -17,8 +17,12 @@ --> - - + + + + + + diff --git a/org.opentosca.container.war/src/main/resources/spring/root-context.xml b/org.opentosca.container.war/src/main/resources/spring/root-context.xml index 3e5f67fd2..bdb4d04c3 100644 --- a/org.opentosca.container.war/src/main/resources/spring/root-context.xml +++ b/org.opentosca.container.war/src/main/resources/spring/root-context.xml @@ -33,5 +33,4 @@ - diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/handlers/ServiceTemplateBoundaryPropertyMappingsToOutputHandler.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/handlers/ServiceTemplateBoundaryPropertyMappingsToOutputHandler.java index 928d5d83e..df54dd487 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/handlers/ServiceTemplateBoundaryPropertyMappingsToOutputHandler.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/handlers/ServiceTemplateBoundaryPropertyMappingsToOutputHandler.java @@ -326,6 +326,7 @@ private String injectBPELVariables(final String targetPropertyRef, final Propert if (var.getPropertyName().equals(propertyName)) { addedVar = true; augmentedFunctionParts.add("$" + var.getVariableName()); + break; } } diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasednodehandler/BPELPluginHandler.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasednodehandler/BPELPluginHandler.java index 69baaed9b..bd9cf4462 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasednodehandler/BPELPluginHandler.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasednodehandler/BPELPluginHandler.java @@ -197,21 +197,29 @@ private boolean handleProvisioningActivity(final BPELPlanContext context, final } } - // generate code for the provisioning, e.g., call install, start or create - // methods - final IPlanBuilderTypePlugin plugin = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, context.getCsar()); - if (plugin != null) { - LOG.debug("Handling NodeTemplate {} with type plugin {}", nodeTemplate.getId(), plugin.getID()); - result &= plugin.handleCreate(context, nodeTemplate); - } else { + // generate code for the provisioning, e.g., call install, start or create methods + final List> plugins = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, context.getCsar()); + if (plugins.isEmpty()) { LOG.debug("Couldn't handle provisioning code generation of NodeTemplate {} with type plugin", nodeTemplate.getId()); + // generate code the post handling, e.g., update instance data, logs etc. + for (final IPlanBuilderPostPhasePlugin postPhasePlugin : this.pluginRegistry.getPostPlugins()) { + if (postPhasePlugin.canHandleCreate(context, bpelScope.getNodeTemplate())) { + LOG.debug("Handling NodeTemplate {} with post plugin {}", nodeTemplate.getId(), postPhasePlugin.getID()); + result &= postPhasePlugin.handleCreate(context, bpelScope.getNodeTemplate()); + } + } } - } - // generate code the post handling, e.g., update instance data, logs etc. - for (final IPlanBuilderPostPhasePlugin postPhasePlugin : this.pluginRegistry.getPostPlugins()) { - if (postPhasePlugin.canHandleCreate(context, bpelScope.getNodeTemplate())) { - LOG.debug("Handling NodeTemplate {} with post plugin {}", nodeTemplate.getId(), postPhasePlugin.getID()); - result &= postPhasePlugin.handleCreate(context, bpelScope.getNodeTemplate()); + for (final IPlanBuilderTypePlugin plugin : plugins) { + LOG.debug("Handling NodeTemplate {} with type plugin {}", nodeTemplate.getId(), plugin.getID()); + result &= plugin.handleCreate(context, nodeTemplate); + + // generate code the post handling, e.g., update instance data, logs etc. + for (final IPlanBuilderPostPhasePlugin postPhasePlugin : this.pluginRegistry.getPostPlugins()) { + if (postPhasePlugin.canHandleCreate(context, bpelScope.getNodeTemplate())) { + LOG.debug("Handling NodeTemplate {} with post plugin {}", nodeTemplate.getId(), postPhasePlugin.getID()); + result &= postPhasePlugin.handleCreate(context, bpelScope.getNodeTemplate()); + } + } } } return result; diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELPolicyAwareBuildProcessBuilder.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELPolicyAwareBuildProcessBuilder.java index e4dee72cf..368d0de83 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELPolicyAwareBuildProcessBuilder.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELPolicyAwareBuildProcessBuilder.java @@ -276,7 +276,7 @@ private boolean runPlugins(final BPELPlan buildPlan, final Property2VariableMapp } if (nodeTemplate.getPolicies().isEmpty()) { - final IPlanBuilderTypePlugin plugin = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, csar); + final IPlanBuilderTypePlugin plugin = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, csar).stream().findFirst().orElse(null); if (plugin != null) { LOG.info("Handling NodeTemplate {} with type plugin {}", nodeTemplate.getId(), plugin.getID()); diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELScaleOutProcessBuilder.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELScaleOutProcessBuilder.java index 301ca6ac8..bca6f8096 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELScaleOutProcessBuilder.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.core.bpel/src/main/java/org/opentosca/planbuilder/core/bpel/typebasedplanbuilder/BPELScaleOutProcessBuilder.java @@ -675,7 +675,7 @@ private void runProvisioningLogicGeneration(final BPELPlan plan, final TNodeTemp } } - final IPlanBuilderTypePlugin plugin = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, context.getCsar()); + final IPlanBuilderTypePlugin plugin = this.pluginRegistry.findTypePluginForCreation(nodeTemplate, context.getCsar()).stream().findFirst().orElse(null); if (plugin != null) { LOG.debug("Handling NodeTemplate {} with type plugin {}", nodeTemplate.getId(), diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.core/src/main/java/org/opentosca/planbuilder/core/plugins/registry/PluginRegistry.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.core/src/main/java/org/opentosca/planbuilder/core/plugins/registry/PluginRegistry.java index c78153d1d..136a445f2 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.core/src/main/java/org/opentosca/planbuilder/core/plugins/registry/PluginRegistry.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.core/src/main/java/org/opentosca/planbuilder/core/plugins/registry/PluginRegistry.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; @@ -226,13 +227,12 @@ public IPlanBuilderTypePlugin findTypePluginForTermination(final TNodeTemplat .orElse(null); } - public IPlanBuilderTypePlugin findTypePluginForCreation(final TNodeTemplate nodeTemplate, Csar csar) { + public List> findTypePluginForCreation(final TNodeTemplate nodeTemplate, Csar csar) { return getTypePlugins().stream() .filter(p -> p.canHandleCreate(csar, nodeTemplate)) // sort highest priority first .sorted(Comparator.comparingInt(IPlanBuilderPlugin::getPriority).reversed()) - .findFirst() - .orElse(null); + .collect(Collectors.toList()); } public IPlanBuilderTypePlugin findTypePluginForUpdate(final TNodeTemplate nodeTemplate, Csar csar) { diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/LifecyclePatternBasedHandler.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/LifecyclePatternBasedHandler.java index 2d53527aa..8458102c4 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/LifecyclePatternBasedHandler.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/LifecyclePatternBasedHandler.java @@ -17,9 +17,12 @@ import org.opentosca.container.core.model.ModelUtils; import org.opentosca.container.core.model.csar.Csar; import org.opentosca.planbuilder.core.bpel.context.BPELPlanContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Element; public class LifecyclePatternBasedHandler extends PatternBasedHandler { + private final static Logger LOG = LoggerFactory.getLogger(LifecyclePatternBasedHandler.class); public boolean handleCreate(final BPELPlanContext context, final TNodeTemplate nodeTemplate, Element elementToAppendTo) { @@ -153,41 +156,54 @@ private Set filterForNodesInCreation(BPELPlanContext context, Set } public boolean isProvisionableByLifecyclePattern(final TNodeTemplate nodeTemplate, Csar csar) { - + LOG.debug("Checking if nodeTemplate {} can be handled by lifecycle pattern", nodeTemplate.getId()); if (!hasLifecycleProvisioningMethods(nodeTemplate, csar)) { + LOG.debug("No lifecycle method available..."); return false; } Set nodesForMatching = this.getNodesForMatching(nodeTemplate, csar); + LOG.debug("Number of nodes for matching: {}", nodesForMatching.size()); // Small check if we have to find runScript and transferFile operations boolean hasScriptImplementation; // check if the lifecycle operations can be matched against the nodes - TOperation op; TInterface iface = this.getLifecyclePatternInterface(nodeTemplate, csar); - if (((op = this.getLifecyclePatternInstallMethod(nodeTemplate, csar)) != null) - && !hasCompleteMatching(nodesForMatching, iface, op)) { - return false; + + TOperation op = this.getLifecyclePatternInstallMethod(nodeTemplate, csar); + if (op != null) { + LOG.debug("Found lifecycle install operation, searching for matching..."); + if (!hasCompleteMatching(nodesForMatching, iface, op)) { + LOG.debug("No matching for lifecycle install operation..."); + return false; + } } hasScriptImplementation = this.isImplementedAsScript(iface, nodeTemplate, csar); - if (((op = this.getLifecyclePatternConfigureMethod(nodeTemplate, csar)) != null) - && !hasCompleteMatching(nodesForMatching, iface, op)) { - return false; + op = this.getLifecyclePatternConfigureMethod(nodeTemplate, csar); + if (op != null) { + LOG.debug("Found lifecycle configure operation, searching for matching..."); + if (!hasCompleteMatching(nodesForMatching, iface, op)) { + LOG.debug("No matching for lifecycle configure operation..."); + return false; + } } hasScriptImplementation |= this.isImplementedAsScript(iface, nodeTemplate, csar); if (((op = this.getLifecyclePatternStartMethod(nodeTemplate, csar)) != null) && !hasCompleteMatching(nodesForMatching, iface, op)) { + LOG.debug("No matching for lifecycle start operation..."); return false; } hasScriptImplementation |= this.isImplementedAsScript(iface, nodeTemplate, csar); + LOG.debug("Checking availability of operations to handle scripts required: {}", hasScriptImplementation); if (hasScriptImplementation) { + LOG.debug("Searching for run script and transfer file operations..."); return this.checkForRunScriptAndTransferFile(nodeTemplate, csar); } diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/PatternBasedHandler.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/PatternBasedHandler.java index 8f7ae60b2..91d4fbfb6 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/PatternBasedHandler.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.patternbased/src/main/java/org/opentosca/planbuilder/type/plugin/patternbased/bpel/PatternBasedHandler.java @@ -21,9 +21,12 @@ import org.opentosca.planbuilder.core.plugins.context.PropertyVariable; import org.opentosca.planbuilder.core.plugins.context.Variable; import org.opentosca.planbuilder.provphase.plugin.invoker.bpel.BPELInvokerPlugin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Element; public abstract class PatternBasedHandler { + private final static Logger LOG = LoggerFactory.getLogger(PatternBasedHandler.class); protected static final BPELInvokerPlugin invoker = new BPELInvokerPlugin(); @@ -142,16 +145,22 @@ protected boolean hasCompleteMatching(final Collection nodesForMa final TInterface ifaceToMatch, final TOperation operationToMatch) { + LOG.debug("Searching for matching for operation: {}", operationToMatch.getName()); + final OperationMatching matching = createPropertyToParameterMatching(nodesForMatching, ifaceToMatch, operationToMatch); int inputParamSize = 0; if (operationToMatch.getInputParameters() != null) { - inputParamSize = operationToMatch.getInputParameters().size(); + inputParamSize = operationToMatch.getInputParameters().stream().filter(TParameter::getRequired).toList().size(); } - return matching.inputMatching.size() == inputParamSize; + LOG.debug("Required input parameters: {}", inputParamSize); + LOG.debug("Matched input parameters: {}", matching.inputMatching.size()); + LOG.debug("Matching? {}", matching.inputMatching.size() == inputParamSize); + // TODO: refactor to check that all required input parameters are available + return matching.inputMatching.size() >= inputParamSize; } protected OperationMatching createPropertyToParameterMatching(final Collection nodesForMatching, diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePlugin.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePlugin.java index bea71c2d8..60bc738db 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePlugin.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePlugin.java @@ -292,6 +292,6 @@ public boolean handleTerminate(final BPELPlanContext templateContext, @Override public int getPriority() { // - return 0; + return 2; } } diff --git a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePluginHandler.java b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePluginHandler.java index c6fa74f11..a8cc74514 100644 --- a/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePluginHandler.java +++ b/org.opentosca.planbuilder/org.opentosca.planbuilder.type.plugin.ubuntuvm/src/main/java/org/opentosca/planbuilder/type/plugin/ubuntuvm/bpel/BPELUbuntuVmTypePluginHandler.java @@ -57,12 +57,13 @@ public class BPELUbuntuVmTypePluginHandler { private final static org.slf4j.Logger LOG = LoggerFactory.getLogger(BPELUbuntuVmTypePluginHandler.class); // create method external input parameters without CorrelationId (old) private final static String[] createEC2InstanceExternalInputParams = - {"securityGroup", "keyPairName", "secretKey", "accessKey", "regionEndpoint", "AMIid", "instanceType"}; + {"VMKeyPairName", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "VMImageID", "VMType", + "VMUserPassword", "VMPublicKey", "VMKeyPairName", "VMOpenPorts", "VMNetworks"}; // new possible external params private final static String[] createVMInstanceExternalInputParams = {"VMKeyPairName", "HypervisorUserPassword", "HypervisorUserName", "HypervisorEndpoint", "VMImageID", "VMType", - "HypervisorTenantID", "VMUserPassword", "VMPublicKey", "VMKeyPairName"}; + "HypervisorTenantID", "VMUserPassword", "VMPublicKey", "VMKeyPairName", "VMOpenPorts", "VMNetworks"}; // mandatory params for the local hypervisor node private final static String[] localCreateVMInstanceExternalInputParams = @@ -609,7 +610,15 @@ private boolean setExternalParameters(BPELPlanContext context, TNodeTemplate ubu * property is found but not set, we will set an input param and take the value from plan input. * Everything else aborts this method */ - for (final String externalParameter : BPELUbuntuVmTypePluginHandler.createVMInstanceExternalInputParams) { + String[] properties; + if (findCloudProviderNode(ubuntuNodeTemplate, context.getCsar()).getType().equals(Types.ec2NEWNodeType)){ + LOG.debug("Searching EC2 properties"); + properties = BPELUbuntuVmTypePluginHandler.createEC2InstanceExternalInputParams; + } else { + LOG.debug("Searching Openstack properties"); + properties = BPELUbuntuVmTypePluginHandler.createVMInstanceExternalInputParams; + } + for (final String externalParameter : properties) { // find the variable for the inputParam PropertyVariable variable = context.getPropertyVariable(ubuntuNodeTemplate, externalParameter); diff --git a/pom.xml b/pom.xml index 9aee64861..c66f80655 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,11 @@ central https://repo1.maven.org/maven2/ + + maven.restlet.org + maven.restlet.org + https://maven.restlet.talend.com + JCenter Public Repository jcenter @@ -57,7 +62,6 @@ - org.opentosca.broker.mqtt org.opentosca.bus org.opentosca.container.control org.opentosca.container.core