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