Merge "Fix build errors in autorelease full clean build"
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.topologymodeler / src / main / java / org / eclipse / winery / topologymodeler / addons / topologycompleter / topologycompletion / CompletionInterface.java
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
8  *
9  * Contributors:
10  *    Pascal Hirmer - initial API and implementation
11  *******************************************************************************/
12
13 package org.eclipse.winery.topologymodeler.addons.topologycompleter.topologycompletion;
14
15 import java.util.List;
16 import java.util.Map;
17
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;
35
36 /**
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.
40  */
41 public class CompletionInterface {
42
43         /**
44          * Logger for debug reasons.
45          */
46         private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CompletionInterface.class.getName());
47
48         /**
49          * This global variable is returned to the Winery Topology Modelerer via getCurrentTopology() to display intermediate results when an user interaction is necessary.
50          */
51         private TTopologyTemplate currentTopology;
52
53         /**
54          * This list contains {@link TTopologyTemplate}s to be chosen by the user when the topology solution isn't unique.
55          */
56         private List<TTopologyTemplate> topologyTemplateChoices;
57
58         /**
59          * This List contains {@link TRelationshipTemplate}s to be chosen by the user.
60          */
61         private List<TEntityTemplate> relationshipTemplateChoices;
62
63         /**
64          * This Map contains {@link TNodeTemplate}s and {@link TRelationshipTemplate}s to be chosen by the user during the step-by-step approach.
65          */
66         private Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> nodeTemplateChoices;
67
68         /**
69          * String containing an error message to be displayed in Winery if necessary.
70          */
71         private String errorMessage = "";
72
73         /**
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.
76          *
77          * @param topology
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.
85          * @param topologyName
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
91          * @param stepByStep
92          *            whether the topology completion is processed step-by-step or not
93          * @param restarted
94          *            whether the topology completion is restarted or started for the first time
95          *
96          * @return a message to Winery that contains information whether the topology is complete, the user has to interact or an error occurred.
97          */
98         public String complete(String topology, String serviceTemplateName, String topologyTemplateURL, Boolean overwriteTopology,
99                         String topologyName, String topologyNamespace, String repositoryURL, boolean stepByStep, boolean restarted) {
100
101                 logger.info("Starting completion...");
102
103                 ////////////////////////////////////////
104                 // STEP 1: Receive topology from Winery
105                 ////////////////////////////////////////
106
107                 logger.info("Saving to: " + topologyTemplateURL);
108
109                 logger.info("The service template to be completed is: " + serviceTemplateName);
110
111                 // receive types from repository
112                 IWineryRepositoryClient client = WineryRepositoryClientFactory.getWineryRepositoryClient();
113                 client.addRepository(repositoryURL);
114
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);
118
119                 /////////////////////////////////////
120                 // Step 2: Analyze topology content
121                 /////////////////////////////////////
122
123                 logger.info("The modelled topology as XML: " + topology);
124
125                 TTopologyTemplate topologyTemplate = JAXBHelper.getTopologyAsJaxBObject(topology);
126
127                 logger.info("Analyzing topology...");
128
129                 // analyze the received topology
130                 TOSCAAnalyzer toscaAnalyzer = new TOSCAAnalyzer();
131                 toscaAnalyzer.analyzeTOSCATopology(topologyTemplate);
132                 toscaAnalyzer.setTypes(nodeTypeList, relationshipTypeList, requirementTypeList);
133
134                 // if the topology is already complete, a message is displayed
135                 if (checkCompletnessOfTopology(toscaAnalyzer) && !restarted) {
136                         return Constants.CompletionMessages.TOPOLOGYCOMPLETE.toString();
137                 } else {
138
139                         /////////////////////////////////////////
140                         // Step 3: Invoke the topology completion
141                         /////////////////////////////////////////
142                         logger.info("Invoking Topology Completion...");
143
144                         CompletionManager completionManager = new CompletionManager(toscaAnalyzer, stepByStep);
145                         List<TTopologyTemplate> completedTopology = completionManager.manageCompletion(topologyTemplate);
146
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();
151
152                                 return Constants.CompletionMessages.USERINTERACTION.toString();
153
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();
158
159                                 for (TNodeTemplate nodeTemplate : nodeTemplateChoices.keySet()) {
160                                         Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = nodeTemplateChoices.get(nodeTemplate);
161
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);
169                                                         }
170                                                 }
171                                         }
172                                 }
173
174                                 return Constants.CompletionMessages.STEPBYSTEP.toString();
175                         }
176
177                         logger.info("Completion successful!");
178
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();
187                         } else {
188                                 // an error occurred
189                                 errorMessage = "Error: No suitable NodeTemplate could be found for a Requirement or PlaceHolder.";
190                                 return Constants.CompletionMessages.FAILURE.toString();
191                         }
192                 }
193         }
194
195         /**
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.
198          *
199          * @param toscaAnalyzer
200          *            the topology to be checked
201          * @return whether the topology is complete or not
202          */
203         public boolean checkCompletnessOfTopology(TOSCAAnalyzer toscaAnalyzer) {
204
205                 if (RequirementAnalyzer.analyzeRequirements(toscaAnalyzer).isEmpty() && PlaceHolderAnalyzer.analyzePlaceHolders(toscaAnalyzer).isEmpty()
206                                 && DeferredAnalyzer.analyzeDeferredRelations(toscaAnalyzer).isEmpty()) {
207                         return true;
208                 } else {
209                         return false;
210                 }
211         }
212
213         /**
214          * Returns the current state of the completion.
215          *
216          * @return the current {@link TTopologyTemplate}
217          */
218         public TTopologyTemplate getCurrentTopology() {
219                 return currentTopology;
220         }
221
222         /**
223          * Returns the choices whenever there are several possible complete {@link TTopologyTemplate}s. They will be displayed in Winery and chosen by the user.
224          *
225          * @return the possible {@link TTopologyTemplate} choices as a list.
226          */
227         public List<TTopologyTemplate> getTopologyTemplateChoices() {
228                 return topologyTemplateChoices;
229         }
230
231         /**
232          * Returns the {@link TRelationshipTemplate} choices
233          *
234          * @return the {@link TRelationshipTemplate}s to be chosen
235          */
236         public List<TEntityTemplate> getRelationshipTemplateChoices() {
237                 return relationshipTemplateChoices;
238         }
239
240         /**
241          * Returns several {@link TNodeTemplate} and {@link TRelationshipTemplate} choices when the user selected the step-by-step approach.
242          *
243          * @return the {@link TNodeTemplate} choices
244          */
245         public Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> getNodeTemplateChoices() {
246                 return nodeTemplateChoices;
247         }
248
249         /**
250          * Returns a message when an error occurred during the completion.
251          *
252          * @return the error message
253          */
254         public String getErrorMessage() {
255                 return errorMessage;
256         }
257 }