1 /*******************************************************************************
2 * Copyright (c) 2013 Pascal Hirmer.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * Pascal Hirmer - initial API and implementation
11 *******************************************************************************/
13 package org.eclipse.winery.topologymodeler.addons.topologycompleter.topologycompletion;
15 import java.util.List;
18 import org.eclipse.winery.model.tosca.TEntityTemplate;
19 import org.eclipse.winery.model.tosca.TNodeTemplate;
20 import org.eclipse.winery.model.tosca.TNodeType;
21 import org.eclipse.winery.model.tosca.TRelationshipTemplate;
22 import org.eclipse.winery.model.tosca.TRelationshipType;
23 import org.eclipse.winery.model.tosca.TRequirementType;
24 import org.eclipse.winery.model.tosca.TTopologyTemplate;
25 import org.eclipse.winery.repository.client.IWineryRepositoryClient;
26 import org.eclipse.winery.repository.client.WineryRepositoryClientFactory;
27 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.DeferredAnalyzer;
28 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.PlaceHolderAnalyzer;
29 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.RequirementAnalyzer;
30 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.TOSCAAnalyzer;
31 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.Constants;
32 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.JAXBHelper;
33 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.RESTHelper;
34 import org.slf4j.LoggerFactory;
37 * This class is the entry point of the TOSCA topology completion which is called by the Winery Topology Modeler.
38 * It receives an incomplete {@link TTopologyTemplate} from Winery.
39 * The completion of the incomplete {@link TTopologyTemplate} is managed by this class.
41 public class CompletionInterface {
44 * Logger for debug reasons.
46 private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CompletionInterface.class.getName());
49 * This global variable is returned to the Winery Topology Modelerer via getCurrentTopology() to display intermediate results when an user interaction is necessary.
51 private TTopologyTemplate currentTopology;
54 * This list contains {@link TTopologyTemplate}s to be chosen by the user when the topology solution isn't unique.
56 private List<TTopologyTemplate> topologyTemplateChoices;
59 * This List contains {@link TRelationshipTemplate}s to be chosen by the user.
61 private List<TEntityTemplate> relationshipTemplateChoices;
64 * This Map contains {@link TNodeTemplate}s and {@link TRelationshipTemplate}s to be chosen by the user during the step-by-step approach.
66 private Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> nodeTemplateChoices;
69 * String containing an error message to be displayed in Winery if necessary.
71 private String errorMessage = "";
74 * This method receives an incomplete {@link TTopologyTemplate} and the repository content from Winery. After analyzing the {@link TTopologyTemplate}, the topology is completed. This method will
75 * return a message after the completion whether the completion was successful, has failed or the user has to interact.
78 * (XMLString) the {@link TTopologyTemplate} to be completed as XMLString
79 * @param serviceTemplateName
80 * the name of the ServiceTemplate for REST calls
81 * @param topologyTemplateURL
82 * the URL where the template is saved to
83 * @param overwriteTopology
84 * determines in which way the {@link TTopologyTemplate} is saved. The current {@link TTopologyTemplate} can either be overwritten or a new topology can be created.
86 * the name of the {@link TTopologyTemplate} when a new {@link TTopologyTemplate} shall be created
87 * @param topologyNamespace
88 * the namespace of the {@link TTopologyTemplate} when a new {@link TTopologyTemplate} shall be created
89 * @param repositoryURL
90 * the URL to the repository to receive and write TOSCA specific information
92 * whether the topology completion is processed step-by-step or not
94 * whether the topology completion is restarted or started for the first time
96 * @return a message to Winery that contains information whether the topology is complete, the user has to interact or an error occurred.
98 public String complete(String topology, String serviceTemplateName, String topologyTemplateURL, Boolean overwriteTopology,
99 String topologyName, String topologyNamespace, String repositoryURL, boolean stepByStep, boolean restarted) {
101 logger.info("Starting completion...");
103 ////////////////////////////////////////
104 // STEP 1: Receive topology from Winery
105 ////////////////////////////////////////
107 logger.info("Saving to: " + topologyTemplateURL);
109 logger.info("The service template to be completed is: " + serviceTemplateName);
111 // receive types from repository
112 IWineryRepositoryClient client = WineryRepositoryClientFactory.getWineryRepositoryClient();
113 client.addRepository(repositoryURL);
115 List<TNodeType> nodeTypeList = (List<TNodeType>) client.getAllTypes(TNodeType.class);
116 List<TRelationshipType> relationshipTypeList = (List<TRelationshipType>) client.getAllTypes(TRelationshipType.class);
117 List<TRequirementType> requirementTypeList = (List<TRequirementType>) client.getAllTypes(TRequirementType.class);
119 /////////////////////////////////////
120 // Step 2: Analyze topology content
121 /////////////////////////////////////
123 logger.info("The modelled topology as XML: " + topology);
125 TTopologyTemplate topologyTemplate = JAXBHelper.getTopologyAsJaxBObject(topology);
127 logger.info("Analyzing topology...");
129 // analyze the received topology
130 TOSCAAnalyzer toscaAnalyzer = new TOSCAAnalyzer();
131 toscaAnalyzer.analyzeTOSCATopology(topologyTemplate);
132 toscaAnalyzer.setTypes(nodeTypeList, relationshipTypeList, requirementTypeList);
134 // if the topology is already complete, a message is displayed
135 if (checkCompletnessOfTopology(toscaAnalyzer) && !restarted) {
136 return Constants.CompletionMessages.TOPOLOGYCOMPLETE.toString();
139 /////////////////////////////////////////
140 // Step 3: Invoke the topology completion
141 /////////////////////////////////////////
142 logger.info("Invoking Topology Completion...");
144 CompletionManager completionManager = new CompletionManager(toscaAnalyzer, stepByStep);
145 List<TTopologyTemplate> completedTopology = completionManager.manageCompletion(topologyTemplate);
147 // the user has to interact by choosing a RelationshipTemplate, send message to Winery which will display a dialog
148 if (completionManager.getUserInteraction() && !stepByStep) {
149 currentTopology = completedTopology.get(0);
150 relationshipTemplateChoices = completionManager.getChoices();
152 return Constants.CompletionMessages.USERINTERACTION.toString();
154 } else if (completionManager.getNodeTemplateUserInteraction() && stepByStep) {
155 // the topology completion is processed Step-by-Step, the user has to choose Node and RelationshipTemplates to be inserted
156 currentTopology = completedTopology.get(0);
157 nodeTemplateChoices = completionManager.getTemplateChoices();
159 for (TNodeTemplate nodeTemplate : nodeTemplateChoices.keySet()) {
160 Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = nodeTemplateChoices.get(nodeTemplate);
162 for (TNodeTemplate entity : entityTemplates.keySet()) {
163 for (TEntityTemplate relationshipTemplate : entityTemplates.get(entity)) {
164 // remove entity that has to be chosen next
165 if (currentTopology.getNodeTemplateOrRelationshipTemplate().contains(relationshipTemplate)) {
166 currentTopology.getNodeTemplateOrRelationshipTemplate().remove(relationshipTemplate);
167 } else if (currentTopology.getNodeTemplateOrRelationshipTemplate().contains(entity)) {
168 currentTopology.getNodeTemplateOrRelationshipTemplate().remove(entity);
174 return Constants.CompletionMessages.STEPBYSTEP.toString();
177 logger.info("Completion successful!");
179 if (completedTopology.size() == 1) {
180 // solution is unique, save the topology
181 RESTHelper.saveCompleteTopology(completedTopology.get(0), topologyTemplateURL, overwriteTopology, topologyName, topologyNamespace, repositoryURL);
182 return Constants.CompletionMessages.SUCCESS.toString();
183 } else if (completedTopology.size() > 1) {
184 // if there are several topology solutions, let the user choose
185 this.topologyTemplateChoices = completedTopology;
186 return Constants.CompletionMessages.USERTOPOLOGYSELECTION.toString();
189 errorMessage = "Error: No suitable NodeTemplate could be found for a Requirement or PlaceHolder.";
190 return Constants.CompletionMessages.FAILURE.toString();
196 * This method checks if the topology is already complete. It will be called before executing the topology completion but
197 * only in case the topology completion isn't restarted after a user selection.
199 * @param toscaAnalyzer
200 * the topology to be checked
201 * @return whether the topology is complete or not
203 public boolean checkCompletnessOfTopology(TOSCAAnalyzer toscaAnalyzer) {
205 if (RequirementAnalyzer.analyzeRequirements(toscaAnalyzer).isEmpty() && PlaceHolderAnalyzer.analyzePlaceHolders(toscaAnalyzer).isEmpty()
206 && DeferredAnalyzer.analyzeDeferredRelations(toscaAnalyzer).isEmpty()) {
214 * Returns the current state of the completion.
216 * @return the current {@link TTopologyTemplate}
218 public TTopologyTemplate getCurrentTopology() {
219 return currentTopology;
223 * Returns the choices whenever there are several possible complete {@link TTopologyTemplate}s. They will be displayed in Winery and chosen by the user.
225 * @return the possible {@link TTopologyTemplate} choices as a list.
227 public List<TTopologyTemplate> getTopologyTemplateChoices() {
228 return topologyTemplateChoices;
232 * Returns the {@link TRelationshipTemplate} choices
234 * @return the {@link TRelationshipTemplate}s to be chosen
236 public List<TEntityTemplate> getRelationshipTemplateChoices() {
237 return relationshipTemplateChoices;
241 * Returns several {@link TNodeTemplate} and {@link TRelationshipTemplate} choices when the user selected the step-by-step approach.
243 * @return the {@link TNodeTemplate} choices
245 public Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> getNodeTemplateChoices() {
246 return nodeTemplateChoices;
250 * Returns a message when an error occurred during the completion.
252 * @return the error message
254 public String getErrorMessage() {