Fix the Sdc Controller
[clamp.git] / src / main / java / org / onap / clamp / clds / model / CldsModel.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  * 
22  */
23
24 package org.onap.clamp.clds.model;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import com.fasterxml.jackson.databind.JsonNode;
29
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
34
35 import javax.ws.rs.BadRequestException;
36 import javax.ws.rs.NotFoundException;
37
38 import org.onap.clamp.clds.dao.CldsDao;
39 import org.onap.clamp.clds.util.JacksonUtils;
40
41 /**
42  * Represent a CLDS Model.
43  */
44 public class CldsModel {
45
46     private static final EELFLogger logger = EELFManager.getInstance().getLogger(CldsModel.class);
47     private static final int UUID_LENGTH = 36;
48     private static final String STATUS_DESIGN = "DESIGN";
49     private static final String STATUS_DISTRIBUTED = "DISTRIBUTED";
50     private static final String STATUS_ACTIVE = "ACTIVE";
51     private static final String STATUS_STOPPED = "STOPPED";
52     private static final String STATUS_DELETING = "DELETING";
53     private static final String STATUS_ERROR = "ERROR";
54     private static final String STATUS_UNKNOWN = "UNKNOWN";
55     private String id;
56     private String templateId;
57     private String templateName;
58     private String name;
59     private String controlNamePrefix;
60     private String controlNameUuid;
61     private String bpmnText;
62     private String propText;
63     private String imageText;
64     private String docText;
65     private String blueprintText;
66     private CldsEvent event;
67     private String status;
68     private List<String> permittedActionCd;
69     private List<CldsModelInstance> cldsModelInstanceList;
70     /**
71      * The service type Id received from DCAE by querying it
72      */
73     private String typeId;
74     private String typeName;
75     private String deploymentId;
76
77     /**
78      * Construct empty model.
79      */
80     public CldsModel() {
81         event = new CldsEvent();
82     }
83
84     /**
85      * Retrieve from DB.
86      */
87     public static CldsModel retrieve(CldsDao cldsDao, String name, boolean okIfNotFound) {
88         // get from db
89         CldsModel model = cldsDao.getModelTemplate(name);
90         if (model.getId() == null && !okIfNotFound) {
91             throw new NotFoundException();
92         }
93         model.determineStatus();
94         model.determinePermittedActionCd();
95         return model;
96     }
97
98     public boolean canInventoryCall() {
99         boolean canCall = false;
100         /* Below checks the clds event is submit/resubmit */
101         if ((event.isActionCd(CldsEvent.ACTION_SUBMIT) || event.isActionCd(CldsEvent.ACTION_RESUBMIT)
102                 || event.isActionCd(CldsEvent.ACTION_SUBMITDCAE))) {
103             canCall = true;
104         }
105         return canCall;
106     }
107
108     /**
109      * Save model to DB.
110      */
111     public CldsModel save(CldsDao cldsDao, String userid) {
112         CldsModel cldsModel = cldsDao.setModel(this, userid);
113         determineStatus();
114         determinePermittedActionCd();
115         return cldsModel;
116     }
117
118     /**
119      * set the status in the model
120      */
121     private void determineStatus() {
122         status = STATUS_UNKNOWN;
123         if (event == null || event.getActionCd() == null) {
124             status = STATUS_DESIGN;
125         } else if (event.isActionStateCd(CldsEvent.ACTION_STATE_ERROR)) {
126             status = STATUS_ERROR;
127         } else if (event.isActionAndStateCd(CldsEvent.ACTION_CREATE, CldsEvent.ACTION_STATE_ANY)
128                 || event.isActionAndStateCd(CldsEvent.ACTION_SUBMIT, CldsEvent.ACTION_STATE_ANY)
129                 || event.isActionAndStateCd(CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_STATE_ANY)
130                 || event.isActionAndStateCd(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_STATE_ANY)
131                 || event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_RECEIVED)) {
132             status = STATUS_DESIGN;
133         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DISTRIBUTE, CldsEvent.ACTION_STATE_RECEIVED)
134                 || event.isActionAndStateCd(CldsEvent.ACTION_UNDEPLOY, CldsEvent.ACTION_STATE_RECEIVED)) {
135             status = STATUS_DISTRIBUTED;
136         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_SENT)) {
137             status = STATUS_DELETING;
138         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_STATE_RECEIVED)
139                 || event.isActionAndStateCd(CldsEvent.ACTION_RESTART, CldsEvent.ACTION_STATE_ANY)
140                 || event.isActionAndStateCd(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STATE_ANY)
141                 || event.isActionAndStateCd(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_STATE_ANY)) {
142             status = STATUS_ACTIVE;
143         } else if (event.isActionAndStateCd(CldsEvent.ACTION_STOP, CldsEvent.ACTION_STATE_ANY)) {
144             status = STATUS_STOPPED;
145         }
146     }
147
148     /**
149      * Get the actionCd from current event. If none, default value is
150      * CldsEvent.ACTION_CREATE
151      */
152     private String getCurrentActionCd() {
153         // current default actionCd is CREATE
154         String actionCd = CldsEvent.ACTION_CREATE;
155         if (event != null && event.getActionCd() != null) {
156             actionCd = event.getActionCd();
157         }
158         return actionCd;
159     }
160
161     /**
162      * Get the actionStateCd from current event. If none, default value is
163      * CldsEvent.ACTION_STATE_COMPLETED
164      */
165     private String getCurrentActionStateCd() {
166         // current default actionStateCd is CREATE
167         String actionStateCd = CldsEvent.ACTION_STATE_COMPLETED;
168         if (event != null && event.getActionStateCd() != null) {
169             actionStateCd = event.getActionStateCd();
170         }
171         return actionStateCd;
172     }
173
174     /**
175      * Determine permittedActionCd list using the actionCd from the current
176      * event. It's a states graph, given the next action that can be executed
177      * from the one that has been executed (described in the event object).
178      * ACTION_CREATE being the first one.
179      */
180     private void determinePermittedActionCd() {
181         String actionCd = getCurrentActionCd();
182         switch (actionCd) {
183             case CldsEvent.ACTION_CREATE:
184                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMIT, CldsEvent.ACTION_TEST);
185                 if (isSimplifiedModel()) {
186                     permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_TEST);
187                 }
188                 break;
189             case CldsEvent.ACTION_SUBMIT:
190             case CldsEvent.ACTION_RESUBMIT:
191                 // for 1702 delete is not currently implemented (and resubmit
192                 // requires manually deleting artifact from sdc
193                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_RESUBMIT);
194                 break;
195             case CldsEvent.ACTION_SUBMITDCAE:
196                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMITDCAE);
197                 break;
198             case CldsEvent.ACTION_DISTRIBUTE:
199                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_RESUBMIT);
200                 if (isSimplifiedModel()) {
201                     permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_SUBMITDCAE);
202                 }
203                 break;
204             case CldsEvent.ACTION_UNDEPLOY:
205                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_DEPLOY,
206                         CldsEvent.ACTION_RESUBMIT);
207                 if (isSimplifiedModel()) {
208                     permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_DEPLOY,
209                             CldsEvent.ACTION_SUBMITDCAE);
210                 }
211                 break;
212             case CldsEvent.ACTION_DEPLOY:
213                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_UNDEPLOY,
214                         CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STOP);
215                 break;
216             case CldsEvent.ACTION_RESTART:
217             case CldsEvent.ACTION_UPDATE:
218                 // for 1702 delete is not currently implemented
219                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_UPDATE,
220                         CldsEvent.ACTION_STOP, CldsEvent.ACTION_UNDEPLOY);
221                 break;
222             case CldsEvent.ACTION_DELETE:
223                 if (getCurrentActionStateCd().equals(CldsEvent.ACTION_STATE_SENT)) {
224                     permittedActionCd = Arrays.asList();
225                 } else {
226                     permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMIT);
227                 }
228                 break;
229             case CldsEvent.ACTION_STOP:
230                 // for 1702 delete is not currently implemented
231                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_RESTART,
232                         CldsEvent.ACTION_UNDEPLOY);
233                 break;
234             default:
235                 logger.warn("Invalid current actionCd: " + actionCd);
236         }
237     }
238
239     private boolean isSimplifiedModel() {
240         boolean result = false;
241         try {
242             if (propText != null) {
243                 JsonNode modelJson = JacksonUtils.getObjectMapperInstance().readTree(propText);
244                 JsonNode simpleModelJson = modelJson.get("simpleModel");
245                 if (simpleModelJson != null && simpleModelJson.asBoolean()) {
246                     result = true;
247                 }
248             }
249         } catch (IOException e) {
250             logger.error("Error while parsing propText json", e);
251         }
252         return result;
253     }
254
255     /**
256      * Validate requestedActionCd - determine permittedActionCd and then check
257      * if contained in permittedActionCd Throw IllegalArgumentException if
258      * requested actionCd is not permitted.
259      */
260     public void validateAction(String requestedActionCd) {
261         determinePermittedActionCd();
262         if (!permittedActionCd.contains(requestedActionCd)) {
263             throw new IllegalArgumentException(
264                     "Invalid requestedActionCd: " + requestedActionCd + ".  Given current actionCd: "
265                             + getCurrentActionCd() + ", the permittedActionCd: " + permittedActionCd);
266         }
267     }
268
269     /**
270      * Extract the UUID portion of a given full control name (controlNamePrefix
271      * + controlNameUuid). No fields are populated other than controlNamePrefix
272      * and controlNameUuid. Throws BadRequestException if length of given
273      * control name is less than UUID_LENGTH.
274      */
275     public static CldsModel createUsingControlName(String fullControlName) {
276         if (fullControlName == null || fullControlName.length() < UUID_LENGTH) {
277             throw new BadRequestException(
278                     "closed loop id / control name length, " + (fullControlName != null ? fullControlName.length() : 0)
279                             + ", less than the minimum of: " + UUID_LENGTH);
280         }
281         CldsModel model = new CldsModel();
282         model.setControlNamePrefix(fullControlName.substring(0, fullControlName.length() - UUID_LENGTH));
283         model.setControlNameUuid(fullControlName.substring(fullControlName.length() - UUID_LENGTH));
284         return model;
285     }
286
287     /**
288      * @return the controlName (controlNamePrefix + controlNameUuid)
289      */
290     public String getControlName() {
291         return controlNamePrefix + controlNameUuid;
292     }
293
294     /**
295      * To insert modelInstance to the database
296      */
297     public static CldsModel insertModelInstance(CldsDao cldsDao, DcaeEvent dcaeEvent, String userid) {
298         String controlName = dcaeEvent.getControlName();
299         CldsModel cldsModel = createUsingControlName(controlName);
300         cldsModel = cldsDao.getModelByUuid(cldsModel.getControlNameUuid());
301         cldsModel.determineStatus();
302         if (dcaeEvent.getCldsActionCd().equals(CldsEvent.ACTION_UNDEPLOY) || (dcaeEvent.getCldsActionCd()
303                 .equals(CldsEvent.ACTION_DEPLOY)
304                 && (cldsModel.getStatus().equals(STATUS_DISTRIBUTED) || cldsModel.getStatus().equals(STATUS_DESIGN)))) {
305             CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(),
306                     CldsEvent.ACTION_STATE_RECEIVED, null);
307         }
308         cldsDao.insModelInstance(cldsModel, dcaeEvent.getInstances());
309         return cldsModel;
310     }
311
312     /**
313      * @return the name
314      */
315     public String getName() {
316         return name;
317     }
318
319     /**
320      * @param name
321      *            the name to set
322      */
323     public void setName(String name) {
324         this.name = name;
325     }
326
327     /**
328      * @return the typeName
329      */
330     public String getTypeName() {
331         return typeName;
332     }
333
334     public void setTypeName(String typeName) {
335         this.typeName = typeName;
336     }
337
338     public String getTemplateId() {
339         return templateId;
340     }
341
342     public void setTemplateId(String templateId) {
343         this.templateId = templateId;
344     }
345
346     /**
347      * @return the controlNamePrefix
348      */
349     public String getControlNamePrefix() {
350         return controlNamePrefix;
351     }
352
353     /**
354      * @param controlNamePrefix
355      *            the controlNamePrefix to set
356      */
357     public void setControlNamePrefix(String controlNamePrefix) {
358         this.controlNamePrefix = controlNamePrefix;
359     }
360
361     /**
362      * @return the controlNameUuid
363      */
364     public String getControlNameUuid() {
365         return controlNameUuid;
366     }
367
368     /**
369      * @param controlNameUuid
370      *            the controlNameUuid to set
371      */
372     public void setControlNameUuid(String controlNameUuid) {
373         this.controlNameUuid = controlNameUuid;
374     }
375
376     /**
377      * @return the propText
378      */
379     public String getPropText() {
380         return propText;
381     }
382
383     /**
384      * @param propText
385      *            the propText to set
386      */
387     public void setPropText(String propText) {
388         this.propText = propText;
389     }
390
391     /**
392      * @return the event
393      */
394     public CldsEvent getEvent() {
395         return event;
396     }
397
398     public String getId() {
399         return id;
400     }
401
402     public void setId(String id) {
403         this.id = id;
404     }
405
406     public String getTemplateName() {
407         return templateName;
408     }
409
410     public void setTemplateName(String templateName) {
411         this.templateName = templateName;
412     }
413
414     /**
415      * @param event
416      *            the event to set
417      */
418     public void setEvent(CldsEvent event) {
419         this.event = event;
420     }
421
422     /**
423      * @return the status
424      */
425     public String getStatus() {
426         return status;
427     }
428
429     /**
430      * @param status
431      *            the status to set
432      */
433     public void setStatus(String status) {
434         this.status = status;
435     }
436
437     public String getBlueprintText() {
438         return blueprintText;
439     }
440
441     public void setBlueprintText(String blueprintText) {
442         this.blueprintText = blueprintText;
443     }
444
445     public String getBpmnText() {
446         return bpmnText;
447     }
448
449     public void setBpmnText(String bpmnText) {
450         this.bpmnText = bpmnText;
451     }
452
453     public String getImageText() {
454         return imageText;
455     }
456
457     public void setImageText(String imageText) {
458         this.imageText = imageText;
459     }
460
461     public String getDocText() {
462         return docText;
463     }
464
465     public void setDocText(String docText) {
466         this.docText = docText;
467     }
468
469     public String getTypeId() {
470         return typeId;
471     }
472
473     public void setTypeId(String typeId) {
474         this.typeId = typeId;
475     }
476
477     public List<CldsModelInstance> getCldsModelInstanceList() {
478         if (cldsModelInstanceList == null) {
479             cldsModelInstanceList = new ArrayList<>();
480         }
481         return cldsModelInstanceList;
482     }
483
484     public String getDeploymentId() {
485         return deploymentId;
486     }
487
488     public void setDeploymentId(String deploymentId) {
489         this.deploymentId = deploymentId;
490     }
491
492     public List<String> getPermittedActionCd() {
493         return permittedActionCd;
494     }
495 }