Fix UI behavior
[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     public static final String STATUS_DESIGN = "DESIGN";
49     public static final String STATUS_DISTRIBUTED = "DISTRIBUTED";
50     public static final String STATUS_ACTIVE = "ACTIVE";
51     public static final String STATUS_STOPPED = "STOPPED";
52     public static final String STATUS_DELETING = "DELETING";
53     public static final String STATUS_ERROR = "ERROR";
54     public 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     // This is a transient value used to return the failure message to UI
71     private String errorMessageForUi;
72     /**
73      * The service type Id received from DCAE by querying it
74      */
75     private String typeId;
76     private String typeName;
77     private String deploymentId;
78
79     /**
80      * Construct empty model.
81      */
82     public CldsModel() {
83         event = new CldsEvent();
84     }
85
86     /**
87      * Retrieve from DB.
88      */
89     public static CldsModel retrieve(CldsDao cldsDao, String name, boolean okIfNotFound) {
90         // get from db
91         CldsModel model = cldsDao.getModelTemplate(name);
92         if (model.getId() == null && !okIfNotFound) {
93             throw new NotFoundException();
94         }
95         model.determineStatus();
96         model.determinePermittedActionCd();
97         return model;
98     }
99
100     public boolean canInventoryCall() {
101         boolean canCall = false;
102         /* Below checks the clds event is submit/resubmit/distribute */
103         if (event.isActionCd(CldsEvent.ACTION_SUBMIT) || event.isActionCd(CldsEvent.ACTION_RESUBMIT)
104             || event.isActionCd(CldsEvent.ACTION_DISTRIBUTE) || event.isActionCd(CldsEvent.ACTION_SUBMITDCAE)) {
105             canCall = true;
106         }
107         return canCall;
108     }
109
110     /**
111      * Save model to DB.
112      */
113     public CldsModel save(CldsDao cldsDao, String userid) {
114         CldsModel cldsModel = cldsDao.setModel(this, userid);
115         determineStatus();
116         determinePermittedActionCd();
117         return cldsModel;
118     }
119
120     /**
121      * set the status in the model
122      */
123     private void determineStatus() {
124         status = STATUS_UNKNOWN;
125         if (event == null || event.getActionCd() == null) {
126             status = STATUS_DESIGN;
127         } else if (event.isActionStateCd(CldsEvent.ACTION_STATE_ERROR)) {
128             status = STATUS_ERROR;
129         } else if (event.isActionAndStateCd(CldsEvent.ACTION_CREATE, CldsEvent.ACTION_STATE_ANY)
130             || event.isActionAndStateCd(CldsEvent.ACTION_SUBMIT, CldsEvent.ACTION_STATE_ANY)
131             || event.isActionAndStateCd(CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_STATE_ANY)
132             || event.isActionAndStateCd(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_STATE_ANY)
133             || event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_RECEIVED)
134             || event.isActionAndStateCd(CldsEvent.ACTION_MODIFY, CldsEvent.ACTION_STATE_ANY)) {
135             status = STATUS_DESIGN;
136         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DISTRIBUTE, CldsEvent.ACTION_STATE_RECEIVED)
137             || event.isActionAndStateCd(CldsEvent.ACTION_UNDEPLOY, CldsEvent.ACTION_STATE_RECEIVED)) {
138             status = STATUS_DISTRIBUTED;
139         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_SENT)) {
140             status = STATUS_DELETING;
141         } else if (event.isActionAndStateCd(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_STATE_RECEIVED)
142             || event.isActionAndStateCd(CldsEvent.ACTION_RESTART, CldsEvent.ACTION_STATE_ANY)
143             || event.isActionAndStateCd(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STATE_ANY)
144             || event.isActionAndStateCd(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_STATE_ANY)
145             || event.isActionAndStateCd(CldsEvent.ACTION_SUBMITPOLICY, CldsEvent.ACTION_STATE_ANY)) {
146             status = STATUS_ACTIVE;
147         } else if (event.isActionAndStateCd(CldsEvent.ACTION_STOP, CldsEvent.ACTION_STATE_ANY)) {
148             status = STATUS_STOPPED;
149         }
150     }
151
152     /**
153      * Get the actionCd from current event. If none, default value is
154      * CldsEvent.ACTION_CREATE
155      */
156     private String getCurrentActionCd() {
157         // current default actionCd is CREATE
158         String actionCd = CldsEvent.ACTION_CREATE;
159         if (event != null && event.getActionCd() != null) {
160             actionCd = event.getActionCd();
161         }
162         return actionCd;
163     }
164
165     /**
166      * Get the actionStateCd from current event. If none, default value is
167      * CldsEvent.ACTION_STATE_COMPLETED
168      */
169     private String getCurrentActionStateCd() {
170         // current default actionStateCd is CREATE
171         String actionStateCd = CldsEvent.ACTION_STATE_COMPLETED;
172         if (event != null && event.getActionStateCd() != null) {
173             actionStateCd = event.getActionStateCd();
174         }
175         return actionStateCd;
176     }
177
178     /**
179      * Determine permittedActionCd list using the actionCd from the current
180      * event. It's a states graph, given the next action that can be executed
181      * from the one that has been executed (described in the event object).
182      * ACTION_CREATE being the first one.
183      */
184     private void determinePermittedActionCd() {
185         String actionCd = getCurrentActionCd();
186         switch (actionCd) {
187         case CldsEvent.ACTION_CREATE:
188             permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMIT, CldsEvent.ACTION_TEST,
189                 CldsEvent.ACTION_DELETE);
190             if (isSimplifiedModel()) {
191                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_SUBMITPOLICY,
192                     CldsEvent.ACTION_TEST, CldsEvent.ACTION_DELETE);
193             }
194             break;
195         case CldsEvent.ACTION_MODIFY:
196             permittedActionCd = Arrays.asList(CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_DELETE);
197             if (isSimplifiedModel()) {
198                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_SUBMITPOLICY,
199                     CldsEvent.ACTION_DELETE);
200             }
201             break;
202         case CldsEvent.ACTION_SUBMIT:
203         case CldsEvent.ACTION_RESUBMIT:
204             permittedActionCd = Arrays.asList(CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_DELETE);
205             break;
206         case CldsEvent.ACTION_SUBMITDCAE:
207             permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_DELETE);
208             break;
209         case CldsEvent.ACTION_SUBMITPOLICY:
210             permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STOP);
211             break;
212         case CldsEvent.ACTION_DISTRIBUTE:
213             permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_RESUBMIT,
214                 CldsEvent.ACTION_DELETE);
215             if (isSimplifiedModel()) {
216                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_SUBMITDCAE,
217                     CldsEvent.ACTION_DELETE);
218             }
219             break;
220         case CldsEvent.ACTION_UNDEPLOY:
221             permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_DEPLOY,
222                 CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_DELETE);
223             if (isSimplifiedModel()) {
224                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_DEPLOY,
225                     CldsEvent.ACTION_SUBMITDCAE, CldsEvent.ACTION_DELETE);
226             }
227             break;
228         case CldsEvent.ACTION_DEPLOY:
229             permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_UNDEPLOY,
230                 CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STOP);
231             break;
232         case CldsEvent.ACTION_RESTART:
233         case CldsEvent.ACTION_UPDATE:
234             permittedActionCd = Arrays.asList(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_UPDATE,
235                 CldsEvent.ACTION_STOP, CldsEvent.ACTION_UNDEPLOY);
236             if (isPolicyOnly()) {
237                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STOP);
238             }
239             break;
240         case CldsEvent.ACTION_STOP:
241             permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_RESTART,
242                 CldsEvent.ACTION_UNDEPLOY);
243             if (isPolicyOnly()) {
244                 permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_RESTART,
245                     CldsEvent.ACTION_DELETE);
246             }
247             break;
248         default:
249             logger.warn("Invalid current actionCd: " + actionCd);
250         }
251     }
252
253     private boolean isSimplifiedModel() {
254         boolean result = false;
255         try {
256             if (propText != null) {
257                 JsonNode modelJson = JacksonUtils.getObjectMapperInstance().readTree(propText);
258                 JsonNode simpleModelJson = modelJson.get("simpleModel");
259                 if (simpleModelJson != null && simpleModelJson.asBoolean()) {
260                     result = true;
261                 }
262             }
263         } catch (IOException e) {
264             logger.error("Error while parsing propText json", e);
265         }
266         return result;
267     }
268
269     private boolean isPolicyOnly() {
270         boolean result = false;
271         try {
272             if (propText != null) {
273                 JsonNode modelJson = JacksonUtils.getObjectMapperInstance().readTree(propText);
274                 JsonNode policyOnlyJson = modelJson.get("policyOnly");
275                 if (policyOnlyJson != null && policyOnlyJson.asBoolean()) {
276                     result = true;
277                 }
278             }
279         } catch (IOException e) {
280             logger.error("Error while parsing propText json", e);
281         }
282         return result;
283     }
284
285     /**
286      * Validate requestedActionCd - determine permittedActionCd and then check
287      * if contained in permittedActionCd Throw IllegalArgumentException if
288      * requested actionCd is not permitted.
289      */
290     public void validateAction(String requestedActionCd) {
291         determinePermittedActionCd();
292         if (!permittedActionCd.contains(requestedActionCd)) {
293             throw new IllegalArgumentException(
294                 "Invalid requestedActionCd: " + requestedActionCd + ".  Given current actionCd: "
295                     + getCurrentActionCd() + ", the permittedActionCd: " + permittedActionCd);
296         }
297     }
298
299     /**
300      * Extract the UUID portion of a given full control name (controlNamePrefix
301      * + controlNameUuid). No fields are populated other than controlNamePrefix
302      * and controlNameUuid. Throws BadRequestException if length of given
303      * control name is less than UUID_LENGTH.
304      */
305     public static CldsModel createUsingControlName(String fullControlName) {
306         if (fullControlName == null || fullControlName.length() < UUID_LENGTH) {
307             throw new BadRequestException(
308                 "closed loop id / control name length, " + (fullControlName != null ? fullControlName.length() : 0)
309                 + ", less than the minimum of: " + UUID_LENGTH);
310         }
311         CldsModel model = new CldsModel();
312         model.setControlNamePrefix(fullControlName.substring(0, fullControlName.length() - UUID_LENGTH));
313         model.setControlNameUuid(fullControlName.substring(fullControlName.length() - UUID_LENGTH));
314         return model;
315     }
316
317     /**
318      * @return the controlName (controlNamePrefix + controlNameUuid)
319      */
320     public String getControlName() {
321         return controlNamePrefix + controlNameUuid;
322     }
323
324     /**
325      * To insert modelInstance to the database
326      */
327     public static CldsModel insertModelInstance(CldsDao cldsDao, DcaeEvent dcaeEvent, String userid) {
328         String controlName = dcaeEvent.getControlName();
329         CldsModel cldsModel = createUsingControlName(controlName);
330         cldsModel = cldsDao.getModelByUuid(cldsModel.getControlNameUuid());
331         cldsModel.determineStatus();
332         if (dcaeEvent.getCldsActionCd().equals(CldsEvent.ACTION_UNDEPLOY) || (dcaeEvent.getCldsActionCd()
333             .equals(CldsEvent.ACTION_DEPLOY)
334             && (cldsModel.getStatus().equals(STATUS_DISTRIBUTED) || cldsModel.getStatus().equals(STATUS_DESIGN)))) {
335             CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(),
336                 CldsEvent.ACTION_STATE_RECEIVED, null);
337         }
338         cldsDao.insModelInstance(cldsModel, dcaeEvent.getInstances());
339         return cldsModel;
340     }
341
342     /**
343      * @return the name
344      */
345     public String getName() {
346         return name;
347     }
348
349     /**
350      * @param name
351      *            the name to set
352      */
353     public void setName(String name) {
354         this.name = name;
355     }
356
357     /**
358      * @return the typeName
359      */
360     public String getTypeName() {
361         return typeName;
362     }
363
364     public void setTypeName(String typeName) {
365         this.typeName = typeName;
366     }
367
368     public String getTemplateId() {
369         return templateId;
370     }
371
372     public void setTemplateId(String templateId) {
373         this.templateId = templateId;
374     }
375
376     /**
377      * @return the controlNamePrefix
378      */
379     public String getControlNamePrefix() {
380         return controlNamePrefix;
381     }
382
383     /**
384      * @param controlNamePrefix
385      *            the controlNamePrefix to set
386      */
387     public void setControlNamePrefix(String controlNamePrefix) {
388         this.controlNamePrefix = controlNamePrefix;
389     }
390
391     /**
392      * @return the controlNameUuid
393      */
394     public String getControlNameUuid() {
395         return controlNameUuid;
396     }
397
398     /**
399      * @param controlNameUuid
400      *            the controlNameUuid to set
401      */
402     public void setControlNameUuid(String controlNameUuid) {
403         this.controlNameUuid = controlNameUuid;
404     }
405
406     /**
407      * @return the propText
408      */
409     public String getPropText() {
410         return propText;
411     }
412
413     /**
414      * @param propText
415      *            the propText to set
416      */
417     public void setPropText(String propText) {
418         this.propText = propText;
419     }
420
421     /**
422      * @return the event
423      */
424     public CldsEvent getEvent() {
425         return event;
426     }
427
428     public String getId() {
429         return id;
430     }
431
432     public void setId(String id) {
433         this.id = id;
434     }
435
436     public String getTemplateName() {
437         return templateName;
438     }
439
440     public void setTemplateName(String templateName) {
441         this.templateName = templateName;
442     }
443
444     /**
445      * @param event
446      *            the event to set
447      */
448     public void setEvent(CldsEvent event) {
449         this.event = event;
450     }
451
452     /**
453      * @return the status
454      */
455     public String getStatus() {
456         return status;
457     }
458
459     /**
460      * @param status
461      *            the status to set
462      */
463     public void setStatus(String status) {
464         this.status = status;
465     }
466
467     public String getBlueprintText() {
468         return blueprintText;
469     }
470
471     public void setBlueprintText(String blueprintText) {
472         this.blueprintText = blueprintText;
473     }
474
475     public String getBpmnText() {
476         return bpmnText;
477     }
478
479     public void setBpmnText(String bpmnText) {
480         this.bpmnText = bpmnText;
481     }
482
483     public String getImageText() {
484         return imageText;
485     }
486
487     public void setImageText(String imageText) {
488         this.imageText = imageText;
489     }
490
491     public String getDocText() {
492         return docText;
493     }
494
495     public void setDocText(String docText) {
496         this.docText = docText;
497     }
498
499     public String getTypeId() {
500         return typeId;
501     }
502
503     public void setTypeId(String typeId) {
504         this.typeId = typeId;
505     }
506
507     public List<CldsModelInstance> getCldsModelInstanceList() {
508         if (cldsModelInstanceList == null) {
509             cldsModelInstanceList = new ArrayList<>();
510         }
511         return cldsModelInstanceList;
512     }
513
514     public String getDeploymentId() {
515         return deploymentId;
516     }
517
518     public void setDeploymentId(String deploymentId) {
519         this.deploymentId = deploymentId;
520     }
521
522     public List<String> getPermittedActionCd() {
523         return permittedActionCd;
524     }
525
526     public String getErrorMessageForUi() {
527         return errorMessageForUi;
528     }
529
530     public void setErrorMessageForUi(String errorMessageForUi) {
531         this.errorMessageForUi = errorMessageForUi;
532     }
533 }