Merge "Validate ids"
[clamp.git] / src / main / java / org / onap / clamp / clds / service / CldsService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Modifications Copyright (c) 2019 Samsung
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END============================================
22  * Modifications copyright (c) 2018 Nokia
23  * ===================================================================
24  *
25  */
26
27 package org.onap.clamp.clds.service;
28
29 import com.att.eelf.configuration.EELFLogger;
30 import com.att.eelf.configuration.EELFManager;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33 import com.google.gson.reflect.TypeToken;
34 import java.io.IOException;
35 import java.lang.reflect.Type;
36 import java.util.Date;
37 import java.util.List;
38 import java.util.UUID;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.ws.rs.BadRequestException;
41 import javax.xml.transform.TransformerException;
42 import org.apache.camel.Produce;
43 import org.json.simple.parser.ParseException;
44 import org.onap.clamp.clds.camel.CamelProxy;
45 import org.onap.clamp.clds.client.DcaeDispatcherServices;
46 import org.onap.clamp.clds.client.DcaeInventoryServices;
47 import org.onap.clamp.clds.config.ClampProperties;
48 import org.onap.clamp.clds.dao.CldsDao;
49 import org.onap.clamp.clds.exception.policy.PolicyClientException;
50 import org.onap.clamp.clds.exception.sdc.SdcCommunicationException;
51 import org.onap.clamp.clds.model.CldsEvent;
52 import org.onap.clamp.clds.model.CldsInfo;
53 import org.onap.clamp.clds.model.CldsModel;
54 import org.onap.clamp.clds.model.CldsModelProp;
55 import org.onap.clamp.clds.model.CldsMonitoringDetails;
56 import org.onap.clamp.clds.model.CldsTemplate;
57 import org.onap.clamp.clds.model.DcaeEvent;
58 import org.onap.clamp.clds.model.ValueItem;
59 import org.onap.clamp.clds.model.properties.ModelProperties;
60 import org.onap.clamp.clds.model.sdc.SdcServiceInfo;
61 import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;
62 import org.onap.clamp.clds.transform.XslTransformer;
63 import org.onap.clamp.clds.util.JsonUtils;
64 import org.onap.clamp.clds.util.LoggingUtils;
65 import org.onap.clamp.clds.util.ONAPLogConstants;
66 import org.slf4j.event.Level;
67 import org.springframework.beans.factory.annotation.Autowired;
68 import org.springframework.beans.factory.annotation.Value;
69 import org.springframework.http.HttpStatus;
70 import org.springframework.http.ResponseEntity;
71 import org.springframework.stereotype.Component;
72 import org.springframework.web.client.HttpClientErrorException;
73
74 /**
75  * Service to save and retrieve the CLDS model attributes.
76  */
77 @Component
78 public class CldsService extends SecureServiceBase {
79
80     /**
81      * The constant LIST_OF_SDC_SERVICE_INFO_TYPE.
82      */
83     public static final Type LIST_OF_SDC_SERVICE_INFO_TYPE = new TypeToken<List<SdcServiceInfo>>() {
84         }.getType();
85     @Produce(uri = "direct:processSubmit")
86     private CamelProxy camelProxy;
87     /**
88      * The constant securityLogger.
89      */
90     protected static final EELFLogger securityLogger = EELFManager.getInstance().getSecurityLogger();
91     /**
92      * The constant logger.
93      */
94     protected static final EELFLogger logger = EELFManager.getInstance().getLogger(CldsService.class);
95
96     /**
97      * The constant GLOBAL_PROPERTIES_KEY.
98      */
99     public static final String GLOBAL_PROPERTIES_KEY = "files.globalProperties";
100     private final String cldsPermissionTypeClManage;
101     private final String cldsPermissionTypeClEvent;
102     private final String cldsPermissionTypeFilterVf;
103     private final String cldsPermissionInstance;
104     /**
105      * The Permission read cl.
106      */
107     final SecureServicePermission permissionReadCl;
108     /**
109      * The Permission update cl.
110      */
111     final SecureServicePermission permissionUpdateCl;
112     /**
113      * The Permission read template.
114      */
115     final SecureServicePermission permissionReadTemplate;
116     /**
117      * The Permission update template.
118      */
119     final SecureServicePermission permissionUpdateTemplate;
120     /**
121      * The Permission read tosca.
122      */
123     final SecureServicePermission permissionReadTosca;
124     /**
125      * The Permission update tosca.
126      */
127     final SecureServicePermission permissionUpdateTosca;
128
129     private final CldsDao cldsDao;
130     private final XslTransformer cldsBpmnTransformer;
131     private final ClampProperties refProp;
132     private final DcaeDispatcherServices dcaeDispatcherServices;
133     private final DcaeInventoryServices dcaeInventoryServices;
134     private LoggingUtils util = new LoggingUtils(logger);
135
136     @Autowired
137     private HttpServletRequest request;
138
139     /**
140      * Instantiates a new Clds service.
141      *
142      * @param cldsDao                    the clds dao
143      * @param cldsBpmnTransformer        the clds bpmn transformer
144      * @param refProp                    the ref prop
145      * @param dcaeDispatcherServices     the dcae dispatcher services
146      * @param dcaeInventoryServices      the dcae inventory services
147      * @param cldsPersmissionTypeCl      the clds persmission type cl
148      * @param cldsPermissionTypeClManage the clds permission type cl manage
149      * @param cldsPermissionTypeClEvent  the clds permission type cl event
150      * @param cldsPermissionTypeFilterVf the clds permission type filter vf
151      * @param cldsPermissionTypeTemplate the clds permission type template
152      * @param cldsPermissionTypeTosca    the clds permission type tosca
153      * @param cldsPermissionInstance     the clds permission instance
154      */
155     @Autowired
156     public CldsService(CldsDao cldsDao, XslTransformer cldsBpmnTransformer, ClampProperties refProp,
157         DcaeDispatcherServices dcaeDispatcherServices,
158         DcaeInventoryServices dcaeInventoryServices,
159         @Value("${clamp.config.security.permission.type.cl:permission-type-cl}")
160                                    String cldsPersmissionTypeCl,
161         @Value("${clamp.config.security.permission.type.cl.manage:permission-type-cl-manage}")
162                                    String cldsPermissionTypeClManage,
163         @Value("${clamp.config.security.permission.type.cl.event:permission-type-cl-event}")
164                                    String cldsPermissionTypeClEvent,
165         @Value("${clamp.config.security.permission.type.filter.vf:permission-type-filter-vf}")
166                                    String cldsPermissionTypeFilterVf,
167         @Value("${clamp.config.security.permission.type.template:permission-type-template}")
168                                    String cldsPermissionTypeTemplate,
169         @Value("${clamp.config.security.permission.type.tosca:permission-type-tosca}")
170                                    String cldsPermissionTypeTosca,
171         @Value("${clamp.config.security.permission.instance:dev}")
172                                    String cldsPermissionInstance) {
173         this.cldsDao = cldsDao;
174         this.cldsBpmnTransformer = cldsBpmnTransformer;
175         this.refProp = refProp;
176         this.dcaeDispatcherServices = dcaeDispatcherServices;
177         this.dcaeInventoryServices = dcaeInventoryServices;
178         this.cldsPermissionTypeClManage = cldsPermissionTypeClManage;
179         this.cldsPermissionTypeClEvent = cldsPermissionTypeClEvent;
180         this.cldsPermissionTypeFilterVf = cldsPermissionTypeFilterVf;
181         this.cldsPermissionInstance = cldsPermissionInstance;
182         permissionReadCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "read");
183         permissionUpdateCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "update");
184         permissionReadTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
185             "read");
186         permissionUpdateTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
187             "update");
188         permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read");
189         permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance,
190             "update");
191     }
192
193     /**
194      * Gets clds details.
195      * list of CLDS-Monitoring-Details: CLOSELOOP_NAME | Close loop name
196      * used in the CLDS application (prefix: ClosedLoop- + unique ClosedLoop ID)
197      * MODEL_NAME | Model Name in CLDS application SERVICE_TYPE_ID | TypeId returned
198      * from the DCAE application when the ClosedLoop is submitted
199      * (DCAEServiceTypeRequest generated in DCAE application). DEPLOYMENT_ID | Id
200      * generated when the ClosedLoop is deployed in DCAE. TEMPLATE_NAME | Template
201      * used to generate the ClosedLoop model. ACTION_CD | Current state of the
202      * ClosedLoop in CLDS application.
203      * @return the clds details
204      */
205     public List<CldsMonitoringDetails> getCldsDetails() {
206         util.entering(request, "CldsService: GET model details");
207         Date startTime = new Date();
208         final List<CldsMonitoringDetails> cldsMonitoringDetailsList = cldsDao.getCldsMonitoringDetails();
209         // audit log
210         LoggingUtils.setTimeContext(startTime, new Date());
211         auditLogger.info("GET cldsDetails completed");
212         util.exiting("200", "Get cldsDetails success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
213         return cldsMonitoringDetailsList;
214     }
215
216     /**
217      * Gets clds info.
218      * CLDS IFO service will return 3 things 1. User Name 2. CLDS code version that
219      * is currently installed from pom.xml file 3. User permissions
220      * @return the clds info
221      */
222     public CldsInfo getCldsInfo() {
223         util.entering(request, "CldsService: GET cldsInfo");
224         Date startTime = new Date();
225         LoggingUtils.setTimeContext(startTime, new Date());
226
227         CldsInfoProvider cldsInfoProvider = new CldsInfoProvider(this);
228         final CldsInfo cldsInfo = cldsInfoProvider.getCldsInfo();
229
230         // audit log
231         LoggingUtils.setTimeContext(startTime, new Date());
232         securityLogger.info("GET cldsInfo completed");
233         util.exiting("200", "Get cldsInfo success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
234         return cldsInfo;
235     }
236
237     /**
238      * REST service that retrieves BPMN for a CLDS model name from the database.
239      * This is subset of the json getModel. This is only expected to be used for
240      * testing purposes, not by the UI.
241      *
242      * @param modelName the model name
243      * @return bpmn xml text - content of bpmn given name
244      */
245     public String getBpmnXml(String modelName) {
246         util.entering(request, "CldsService: GET model bpmn");
247         Date startTime = new Date();
248         isAuthorized(permissionReadCl);
249         logger.info("GET bpmnText for modelName={}", modelName);
250         final CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
251         // audit log
252         LoggingUtils.setTimeContext(startTime, new Date());
253         auditLogger.info("GET model bpmn completed");
254         util.exiting("200", "Get model bpmn success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
255         return model.getBpmnText();
256     }
257
258     /**
259      * REST service that retrieves image for a CLDS model name from the database.
260      * This is subset of the json getModel. This is only expected to be used for
261      * testing purposes, not by the UI.
262      *
263      * @param modelName the model name
264      * @return image xml text - content of image given name
265      */
266     public String getImageXml(String modelName) {
267         util.entering(request, "CldsService: GET model image");
268         Date startTime = new Date();
269         isAuthorized(permissionReadCl);
270         logger.info("GET imageText for modelName={}", modelName);
271         final CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
272         // audit log
273         LoggingUtils.setTimeContext(startTime, new Date());
274         auditLogger.info("GET model image completed");
275         util.exiting("200", "Get model image success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
276         return model.getImageText();
277     }
278
279     /**
280      * REST service that retrieves a CLDS model by name from the database.
281      *
282      * @param modelName the model name
283      * @return clds model - clds model for the given model name
284      */
285     public CldsModel getModel(String modelName) {
286         util.entering(request, "CldsService: GET model");
287         final Date startTime = new Date();
288         isAuthorized(permissionReadCl);
289         logger.debug("GET model for  modelName={}", modelName);
290         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, false);
291         isAuthorizedForVf(cldsModel);
292         // Try an update for DCAE status
293         // Checking condition whether our CLDS model can call Inventory Method
294         try {
295             // Method to call dcae inventory and invoke insert event method
296             if (cldsModel.canDcaeInventoryCall()
297                 && !cldsModel.getTemplateName().startsWith(CsarInstaller.TEMPLATE_NAME_PREFIX)) {
298                 dcaeInventoryServices.setEventInventory(cldsModel, getUserId());
299             }
300             // This is a blocking call
301             if (cldsModel.getEvent().isActionCd(CldsEvent.ACTION_DEPLOY)
302                 && !CldsModel.STATUS_ACTIVE.equals(cldsModel.getStatus()) && cldsModel.getDeploymentId() != null
303                 && cldsModel.getDeploymentStatusUrl() != null) {
304                 checkDcaeDeploymentStatus(cldsModel, CldsEvent.ACTION_DEPLOY, false);
305                 // Refresh the model object in any cases for new event
306                 cldsModel = CldsModel.retrieve(cldsDao, cldsModel.getName(), false);
307             }
308         } catch (Exception e) {
309             LoggingUtils.setErrorContext("900", "Set event inventory error");
310             logger.error("getModel set event Inventory error:" + e);
311         }
312         // audit log
313         LoggingUtils.setTimeContext(startTime, new Date());
314         auditLogger.info("GET model completed");
315         util.exiting("200", "Get model success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
316         return cldsModel;
317     }
318
319     /**
320      * REST service that saves a CLDS model by name in the database.
321      *
322      * @param modelName the model name
323      * @param cldsModel the clds model
324      * @return the clds model
325      */
326     public CldsModel putModel(String modelName, CldsModel cldsModel) {
327         util.entering(request, "CldsService: PUT model");
328         final Date startTime = new Date();
329         isAuthorized(permissionUpdateCl);
330         isAuthorizedForVf(cldsModel);
331         logger.info("PUT model for  modelName={}", modelName);
332         logger.info("PUT bpmnText={}", cldsModel.getBpmnText());
333         logger.info("PUT propText={}", cldsModel.getPropText());
334         logger.info("PUT imageText={}", cldsModel.getImageText());
335         fillInCldsModel(cldsModel);
336         cldsModel.save(cldsDao, getUserId());
337
338         // audit log
339         LoggingUtils.setTimeContext(startTime, new Date());
340         auditLogger.info("PUT model completed");
341         util.exiting("200", "Put model success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
342         return cldsModel;
343     }
344
345     /**
346      * REST service that retrieves a list of CLDS model names.
347      *
348      * @return model names in JSON
349      */
350     public List<ValueItem> getModelNames() {
351         util.entering(request, "CldsService: GET model names");
352         Date startTime = new Date();
353         isAuthorized(permissionReadCl);
354         logger.info("GET list of model names");
355         final List<ValueItem> names = cldsDao.getModelNames();
356         // audit log
357         LoggingUtils.setTimeContext(startTime, new Date());
358         auditLogger.info("GET model names completed");
359         util.exiting("200", "Get model names success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
360         return names;
361     }
362
363     private void fillInCldsModel(CldsModel model) {
364         if (model.getTemplateName() != null) {
365             CldsTemplate template = cldsDao.getTemplate(model.getTemplateName());
366             if (template != null) {
367                 model.setTemplateId(template.getId());
368                 model.setDocText(template.getPropText());
369                 // This is to provide the Bpmn XML when Template part in UI
370                 // is
371                 // disabled
372                 model.setBpmnText(template.getBpmnText());
373             }
374         }
375     }
376
377     /**
378      * REST service that saves and processes an action for a CLDS model by name.
379      *
380      * @param action    the action
381      * @param modelName the model name
382      * @param test      the test
383      * @param model     the model
384      * @return response entity
385      * @throws TransformerException In case of issues when doing the XSLT of the BPMN flow
386      * @throws ParseException       In case of issues when parsing the JSON
387      */
388     public ResponseEntity<?> putModelAndProcessAction(String action, String modelName, String test, CldsModel model)
389         throws TransformerException, ParseException {
390         util.entering(request, "CldsService: Process model action");
391         Date startTime = new Date();
392         String errorMessage = "";
393         String actionCd = "";
394         try {
395             actionCd = action.toUpperCase();
396             SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage,
397                 cldsPermissionInstance, actionCd);
398             isAuthorized(permisionManage);
399             isAuthorizedForVf(model);
400             String userId = getUserId();
401             logger.info("PUT actionCd={}", actionCd);
402             logger.info("PUT modelName={}", modelName);
403             logger.info("PUT test={}", test);
404             logger.info("PUT bpmnText={}", model.getBpmnText());
405             logger.info("PUT propText={}", model.getPropText());
406             logger.info("PUT userId={}", userId);
407             logger.info("PUT getTypeId={}", model.getTypeId());
408             logger.info("PUT deploymentId={}", model.getDeploymentId());
409             this.fillInCldsModel(model);
410             // save model to db just in case
411             model.save(cldsDao, getUserId());
412
413             // get vars and format if necessary
414             final String prop = model.getPropText();
415             final String bpmn = model.getBpmnText();
416             final String docText = model.getDocText();
417             final String controlName = model.getControlName();
418             final String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn);
419             logger.info("PUT bpmnJson={}", bpmnJson);
420             // Test flag coming from UI or from Clamp config
421             boolean isTest = Boolean.parseBoolean(test)
422                 || Boolean.parseBoolean(refProp.getStringValue("action.test.override"));
423             logger.info("PUT isTest={}", isTest);
424             boolean isInsertTestEvent = Boolean.parseBoolean(refProp.getStringValue("action.insert.test.event"));
425             logger.info("PUT isInsertTestEvent={}", isInsertTestEvent);
426             // determine if requested action is permitted
427             model.validateAction(actionCd);
428             logger.info("modelProp - " + prop);
429             logger.info("docText - " + docText);
430             try {
431                 String result = camelProxy.executeAction(actionCd, prop, bpmnJson, modelName, controlName, docText,
432                     isTest, userId, isInsertTestEvent, model.getEvent().getActionCd());
433                 logger.info("Starting Camel flow on request, result is: ", result);
434             } catch (SdcCommunicationException | PolicyClientException | BadRequestException e) {
435                 logger.error("Exception occured during invoking Camel process", e);
436                 errorMessage = e.getMessage();
437             }
438             // audit log
439             LoggingUtils.setTimeContext(startTime, new Date());
440             auditLogger.info("Process model action completed");
441         } catch (Exception e) {
442             logger.error("Exception occured during putModelAndProcessAction", e);
443             errorMessage = e.getMessage();
444         }
445
446         if (null == errorMessage || (null != errorMessage && !errorMessage.isEmpty())) {
447             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), actionCd, CldsEvent.ACTION_STATE_ERROR,
448                 null);
449             // Need a refresh as new events have been inserted
450             model = CldsModel.retrieve(cldsDao, modelName, false);
451             if (null == errorMessage) {
452                 errorMessage = "No response from Policy";
453             }
454             model.setErrorMessageForUi(errorMessage);
455             util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "putModelAndProcessAction failed", Level.INFO,
456                 ONAPLogConstants.ResponseStatus.ERROR);
457             return new ResponseEntity<>(model, HttpStatus.INTERNAL_SERVER_ERROR);
458         } else {
459             // Need a refresh as new events have been inserted, could have been deleted so
460             // not blocking call
461             model = CldsModel.retrieve(cldsDao, modelName, true);
462             util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
463             return new ResponseEntity<>(model, HttpStatus.OK);
464         }
465     }
466
467     /**
468      * REST service that accepts events for a model.
469      *
470      * @param test      the test
471      * @param dcaeEvent the dcae event
472      * @return the string
473      */
474     public String postDcaeEvent(String test, DcaeEvent dcaeEvent) {
475         util.entering(request, "CldsService: Post dcae event");
476         final Date startTime = new Date();
477         String userid = null;
478         // TODO: allow auth checking to be turned off by removing the permission
479         // type property
480         if (cldsPermissionTypeClEvent != null && cldsPermissionTypeClEvent.length() > 0) {
481             SecureServicePermission permissionEvent = SecureServicePermission.create(cldsPermissionTypeClEvent,
482                 cldsPermissionInstance, dcaeEvent.getEvent());
483             isAuthorized(permissionEvent);
484             userid = getUserId();
485         }
486         // Flag indicates whether it is triggered by Validation Test button from
487         // UI
488         boolean isTest = Boolean.parseBoolean(test);
489         int instanceCount = 0;
490         if (dcaeEvent.getInstances() != null) {
491             instanceCount = dcaeEvent.getInstances().size();
492         }
493         String msgInfo = "event=" + dcaeEvent.getEvent() + " serviceUUID=" + dcaeEvent.getServiceUUID()
494             + " resourceUUID=" + dcaeEvent.getResourceUUID() + " artifactName=" + dcaeEvent.getArtifactName()
495             + " instance count=" + instanceCount + " isTest=" + isTest;
496         logger.info("POST dcae event {}", msgInfo);
497         if (isTest) {
498             logger.warn("Ignorning test event from DCAE");
499         } else {
500             if (DcaeEvent.EVENT_DEPLOYMENT.equalsIgnoreCase(dcaeEvent.getEvent())) {
501                 CldsModel.insertModelInstance(cldsDao, dcaeEvent, userid);
502             } else {
503                 CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(),
504                     CldsEvent.ACTION_STATE_RECEIVED, null);
505             }
506         }
507         // audit log
508         LoggingUtils.setTimeContext(startTime, new Date());
509         auditLogger.info("Post dcae event completed");
510         util.exiting("200", "Post dcae event success", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
511         return msgInfo;
512     }
513
514     /**
515      * REST service that retrieves total properties required by UI.
516      *
517      * @return the sdc properties
518      * @throws IOException In case of issues
519      */
520     public String getSdcProperties() throws IOException {
521         return refProp.getJsonTemplate(GLOBAL_PROPERTIES_KEY).toString();
522     }
523
524
525     /**
526      * Determine if the user is authorized for a particular VF by its invariant
527      * UUID.
528      *
529      * @param vfInvariantUuid the vf invariant uuid
530      * @return boolean or throws NotAuthorizedException
531      */
532     public boolean isAuthorizedForVf(String vfInvariantUuid) {
533         if (cldsPermissionTypeFilterVf != null && !cldsPermissionTypeFilterVf.isEmpty()) {
534             SecureServicePermission permission = SecureServicePermission.create(cldsPermissionTypeFilterVf,
535                 cldsPermissionInstance, vfInvariantUuid);
536             return isAuthorized(permission);
537         } else {
538             // if CLDS_PERMISSION_TYPE_FILTER_VF property is not provided, then
539             // VF filtering is turned off
540             logger.warn("VF filtering turned off");
541             return true;
542         }
543     }
544
545     /**
546      * Determine if the user is authorized for a particular VF by its invariant
547      * UUID. If not authorized, then NotAuthorizedException is thrown.
548      *
549      * @param model The clds model
550      * @return boolean or throws NotAuthorizedException
551      */
552     private boolean isAuthorizedForVf(CldsModel model) {
553         String vf = ModelProperties.getVf(model);
554         if (vf == null || vf.length() == 0) {
555             logger.info("VF not found in model");
556             return true;
557         } else {
558             return isAuthorizedForVf(vf);
559         }
560     }
561
562     /**
563      * Deploy model response entity.
564      *
565      * @param modelName the model name
566      * @param model     the model
567      * @return the response entity
568      */
569     public ResponseEntity<CldsModel> deployModel(String modelName, CldsModel model) {
570         util.entering(request, "CldsService: Deploy model");
571         Date startTime = new Date();
572         String errorMessage = "";
573         try {
574             fillInCldsModel(model);
575             String bpmnJson = cldsBpmnTransformer.doXslTransformToString(model.getBpmnText());
576             logger.info("PUT bpmnJson={}", bpmnJson);
577             SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage,
578                 cldsPermissionInstance, CldsEvent.ACTION_DEPLOY);
579             isAuthorized(permisionManage);
580             isAuthorizedForVf(model);
581             ModelProperties modelProp = new ModelProperties(modelName, model.getControlName(), CldsEvent.ACTION_DEPLOY,
582                 false, bpmnJson, model.getPropText());
583             checkForDuplicateServiceVf(modelName, model.getPropText());
584             String deploymentId = "";
585             // If model is already deployed then pass same deployment id
586             if (model.getDeploymentId() != null && !model.getDeploymentId().isEmpty()) {
587                 deploymentId = model.getDeploymentId();
588             } else {
589                 model.setDeploymentId(deploymentId = "closedLoop_" + UUID.randomUUID() + "_deploymentId");
590             }
591             model.setDeploymentStatusUrl(dcaeDispatcherServices.createNewDeployment(deploymentId, model.getTypeId(),
592                 modelProp.getGlobal().getDeployParameters()));
593             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), CldsEvent.ACTION_DEPLOY,
594                 CldsEvent.ACTION_STATE_INITIATED, null);
595             model.save(cldsDao, getUserId());
596             // This is a blocking call
597             checkDcaeDeploymentStatus(model, CldsEvent.ACTION_DEPLOY, true);
598             // Refresh the model object in any cases for new event
599             model = CldsModel.retrieve(cldsDao, model.getName(), false);
600             // audit log
601             LoggingUtils.setTimeContext(startTime, new Date());
602             auditLogger.info("Deploy model completed");
603         } catch (Exception e) {
604             errorMessage = e.getMessage();
605             logger.error("Exception occured during deployModel", e);
606         }
607         if (!errorMessage.isEmpty()) {
608             model.setErrorMessageForUi(errorMessage);
609             util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "DeployModel failed", Level.INFO,
610                 ONAPLogConstants.ResponseStatus.ERROR);
611             return new ResponseEntity<>(model, HttpStatus.INTERNAL_SERVER_ERROR);
612         } else {
613             util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
614             return new ResponseEntity<>(model, HttpStatus.OK);
615         }
616     }
617
618     /**
619      * Un deploy model response entity.
620      *
621      * @param modelName the model name
622      * @param model     the model
623      * @return the response entity
624      */
625     public ResponseEntity<CldsModel> unDeployModel(String modelName, CldsModel model) {
626         util.entering(request, "CldsService: Undeploy model");
627         Date startTime = new Date();
628         String errorMessage = "";
629         try {
630             SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage,
631                 cldsPermissionInstance, CldsEvent.ACTION_UNDEPLOY);
632             isAuthorized(permisionManage);
633             isAuthorizedForVf(model);
634             model.setDeploymentStatusUrl(
635                 dcaeDispatcherServices.deleteExistingDeployment(model.getDeploymentId(), model.getTypeId()));
636             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), CldsEvent.ACTION_UNDEPLOY,
637                 CldsEvent.ACTION_STATE_INITIATED, null);
638             // clean the deployment ID
639             model.setDeploymentId(null);
640             model.save(cldsDao, getUserId());
641             // This is a blocking call
642             checkDcaeDeploymentStatus(model, CldsEvent.ACTION_UNDEPLOY, true);
643             // Refresh the model object in any cases for new event
644             model = CldsModel.retrieve(cldsDao, model.getName(), false);
645             // audit log
646             LoggingUtils.setTimeContext(startTime, new Date());
647             auditLogger.info("Undeploy model completed");
648         } catch (Exception e) {
649             errorMessage = e.getMessage();
650             logger.error("Exception occured during unDeployModel", e);
651         }
652         if (!errorMessage.isEmpty()) {
653             model.setErrorMessageForUi(errorMessage);
654             util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "UndeployModel failed", Level.INFO,
655                 ONAPLogConstants.ResponseStatus.ERROR);
656             return new ResponseEntity<>(model, HttpStatus.INTERNAL_SERVER_ERROR);
657         } else {
658             util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
659             return new ResponseEntity<>(model, HttpStatus.OK);
660         }
661     }
662
663     private void checkDcaeDeploymentStatus(CldsModel model, String cldsEvent, boolean withRetry)
664         throws InterruptedException {
665         String operationStatus = withRetry
666             ? dcaeDispatcherServices.getOperationStatusWithRetry(model.getDeploymentStatusUrl())
667             : dcaeDispatcherServices.getOperationStatus(model.getDeploymentStatusUrl());
668         if ("succeeded".equalsIgnoreCase(operationStatus)) {
669             logger.info(cldsEvent + " model (" + model.getName() + ") succeeded...Deployment Id is - "
670                 + model.getDeploymentId());
671             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), cldsEvent,
672                 CldsEvent.ACTION_STATE_COMPLETED, null);
673         } else {
674             String info = "DCAE " + cldsEvent + " (" + model.getName() + ") failed...Operation Status is - "
675                 + operationStatus;
676             logger.info(info);
677             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), cldsEvent, CldsEvent.ACTION_STATE_ERROR,
678                 null);
679             util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "DCAE operation(" + cldsEvent + ") failed",
680                 Level.INFO, ONAPLogConstants.ResponseStatus.ERROR);
681             throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, info);
682         }
683     }
684
685     private void checkForDuplicateServiceVf(String modelName, String modelPropText) throws IOException {
686         JsonElement globalNode = JsonUtils.GSON.fromJson(modelPropText, JsonObject.class).get("global");
687         String service = JsonUtils.getStringValueByName(globalNode, "service");
688         List<String> resourceVf = JsonUtils.getStringValuesByName(globalNode, "vf");
689         if (service != null && resourceVf != null && !resourceVf.isEmpty()) {
690             List<CldsModelProp> cldsModelPropList = cldsDao.getDeployedModelProperties();
691             for (CldsModelProp cldsModelProp : cldsModelPropList) {
692                 JsonElement currentNode = JsonUtils.GSON
693                     .fromJson(cldsModelProp.getPropText(), JsonObject.class)
694                     .get("global");
695                 String currentService = JsonUtils.getStringValueByName(currentNode, "service");
696                 List<String> currentVf = JsonUtils.getStringValuesByName(currentNode, "vf");
697                 if (currentVf != null && !currentVf.isEmpty()) {
698                     if (!modelName.equalsIgnoreCase(cldsModelProp.getName()) && service.equalsIgnoreCase(currentService)
699                         && resourceVf.get(0).equalsIgnoreCase(currentVf.get(0))) {
700                         throw new BadRequestException("Same Service/VF already exists in " + cldsModelProp.getName()
701                             + " model, please select different Service/VF.");
702                     }
703                 }
704             }
705         }
706     }
707
708     /**
709      * Sets logging util.
710      *
711      * @param utilP the util p
712      */
713     // Created for the integration test
714     public void setLoggingUtil(LoggingUtils utilP) {
715         util = utilP;
716     }
717 }