Fix Sonar bugs
[clamp.git] / src / main / java / org / onap / clamp / clds / service / CldsService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017 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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 package org.onap.clamp.clds.service;
25
26 import com.att.ajsc.common.AjscService;
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.JsonNode;
31 import com.fasterxml.jackson.databind.ObjectMapper;
32 import com.fasterxml.jackson.databind.node.ObjectNode;
33
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.sql.SQLException;
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Properties;
42 import java.util.UUID;
43 import java.util.concurrent.TimeUnit;
44
45 import javax.annotation.PostConstruct;
46 import javax.ws.rs.Consumes;
47 import javax.ws.rs.DefaultValue;
48 import javax.ws.rs.GET;
49 import javax.ws.rs.NotAuthorizedException;
50 import javax.ws.rs.POST;
51 import javax.ws.rs.PUT;
52 import javax.ws.rs.Path;
53 import javax.ws.rs.PathParam;
54 import javax.ws.rs.Produces;
55 import javax.ws.rs.QueryParam;
56 import javax.ws.rs.core.MediaType;
57 import javax.xml.transform.TransformerConfigurationException;
58 import javax.xml.transform.TransformerException;
59
60 import org.apache.commons.lang3.StringUtils;
61 import org.camunda.bpm.engine.RuntimeService;
62 import org.camunda.bpm.engine.runtime.ProcessInstance;
63 import org.onap.clamp.clds.client.DcaeDispatcherServices;
64 import org.onap.clamp.clds.client.DcaeInventoryServices;
65 import org.onap.clamp.clds.client.SdcCatalogServices;
66 import org.onap.clamp.clds.dao.CldsDao;
67 import org.onap.clamp.clds.model.CldsDBServiceCache;
68 import org.onap.clamp.clds.model.CldsEvent;
69 import org.onap.clamp.clds.model.CldsHealthCheck;
70 import org.onap.clamp.clds.model.CldsInfo;
71 import org.onap.clamp.clds.model.CldsModel;
72 import org.onap.clamp.clds.model.CldsSdcResource;
73 import org.onap.clamp.clds.model.CldsSdcServiceDetail;
74 import org.onap.clamp.clds.model.CldsSdcServiceInfo;
75 import org.onap.clamp.clds.model.CldsServiceData;
76 import org.onap.clamp.clds.model.CldsTemplate;
77 import org.onap.clamp.clds.model.DcaeEvent;
78 import org.onap.clamp.clds.model.ValueItem;
79 import org.onap.clamp.clds.model.prop.ModelProperties;
80 import org.onap.clamp.clds.model.refprop.RefProp;
81 import org.onap.clamp.clds.transform.XslTransformer;
82 import org.onap.clamp.clds.util.LoggingUtils;
83 import org.springframework.beans.factory.annotation.Autowired;
84 import org.springframework.beans.factory.annotation.Value;
85 import org.springframework.context.ApplicationContext;
86 import org.springframework.http.HttpStatus;
87 import org.springframework.web.client.HttpClientErrorException;
88
89 import io.swagger.annotations.Api;
90 import io.swagger.annotations.ApiOperation;
91
92 /**
93  * Service to save and retrieve the CLDS model attributes.
94  */
95 @AjscService
96 @Api(value = "/clds", description = "Clds operations")
97 @Path("/clds")
98 public class CldsService extends SecureServiceBase {
99
100     @Autowired
101     private ApplicationContext        appContext;
102
103     private static final String       RESOURCE_NAME = "clds-version.properties";
104
105     protected static final EELFLogger logger        = EELFManager.getInstance().getLogger(CldsService.class);
106     protected static final EELFLogger auditLogger   = EELFManager.getInstance().getAuditLogger();
107
108     @Value("${CLDS_PERMISSION_TYPE_CL:permission-type-cl}")
109     private String                    cldsPersmissionTypeCl;
110
111     @Value("${CLDS_PERMISSION_TYPE_CL_MANAGE:permission-type-cl-manage}")
112     private String                    cldsPermissionTypeClManage;
113
114     @Value("${CLDS_PERMISSION_TYPE_CL_EVENT:permission-type-cl-event}")
115     private String                    cldsPermissionTypeClEvent;
116
117     @Value("${CLDS_PERMISSION_TYPE_FILTER_VF:permission-type-filter-vf}")
118     private String                    cldsPermissionTypeFilterVf;
119
120     @Value("${CLDS_PERMISSION_TYPE_TEMPLATE:permission-type-template}")
121     private String                    cldsPermissionTypeTemplate;
122
123     @Value("${CLDS_PERMISSION_INSTANCE:dev}")
124     private String                    cldsPermissionInstance;
125
126     private SecureServicePermission   permissionReadCl;
127
128     private SecureServicePermission   permissionUpdateCl;
129
130     private SecureServicePermission   permissionReadTemplate;
131
132     private SecureServicePermission   permissionUpdateTemplate;
133
134     @PostConstruct
135     private final void afterConstruction() {
136         permissionReadCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "read");
137         permissionUpdateCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "update");
138         permissionReadTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
139                 "read");
140         permissionUpdateTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
141                 "update");
142     }
143
144     @Value("${org.onap.clamp.config.files.globalClds:'classpath:/clds/globalClds.properties'}")
145     private String                 globalClds;
146
147     private Properties             globalCldsProperties;
148
149     @Autowired
150     private CldsDao                cldsDao;
151     @Autowired
152     private RuntimeService         runtimeService;
153     @Autowired
154     private XslTransformer         cldsBpmnTransformer;
155
156     @Autowired
157     private RefProp                refProp;
158
159     @Autowired
160     private SdcCatalogServices     sdcCatalogServices;
161
162     @Autowired
163     private DcaeDispatcherServices dcaeDispatcherServices;
164
165     @Autowired
166     private DcaeInventoryServices  dcaeInventoryServices;
167
168     public CldsService() {
169     }
170
171     public CldsService(RefProp refProp) {
172         this.refProp = refProp;
173     }
174
175     /*
176      *
177      * CLDS IFO service will return 3 things 1. User Name 2. CLDS code version
178      * that is currently installed from pom.xml file 3. User permissions
179      *
180      */
181
182     @GET
183     @Path("/cldsInfo")
184     @Produces(MediaType.APPLICATION_JSON)
185     public CldsInfo getCldsInfo() {
186
187         CldsInfo cldsInfo = new CldsInfo();
188
189         // Get the user info
190         cldsInfo.setUserName(getUserName());
191
192         // Get CLDS application version
193         String cldsVersion = "";
194         Properties props = new Properties();
195         InputStream resourceStream = null;
196
197         try {
198             ClassLoader loader = Thread.currentThread().getContextClassLoader();
199             resourceStream = loader.getResourceAsStream(RESOURCE_NAME);
200             props.load(resourceStream);
201             cldsVersion = props.getProperty("clds.version");
202         } catch (Exception ex) {
203             ex.printStackTrace();
204         } finally {
205             if (resourceStream != null) {
206                 try {
207                     resourceStream.close();
208                 } catch (IOException e) {
209                     e.printStackTrace();
210                 }
211             }
212         }
213         cldsInfo.setCldsVersion(cldsVersion);
214
215         // Get the user list of permissions
216         cldsInfo.setPermissionReadCl(isAuthorizedNoException(permissionReadCl));
217         cldsInfo.setPermissionUpdateCl(isAuthorizedNoException(permissionUpdateCl));
218         cldsInfo.setPermissionReadTemplate(isAuthorizedNoException(permissionReadTemplate));
219         cldsInfo.setPermissionUpdateTemplate(isAuthorizedNoException(permissionUpdateTemplate));
220         return cldsInfo;
221     }
222
223     @GET
224     @Path("/healthcheck")
225     @Produces(MediaType.APPLICATION_JSON)
226     public CldsHealthCheck gethealthcheck() {
227
228         CldsHealthCheck cldsHealthCheck = new CldsHealthCheck();
229
230         try {
231             cldsDao.doHealthCheck();
232             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
233             cldsHealthCheck.setHealthCheckStatus("UP");
234             cldsHealthCheck.setDescription("OK");
235         } catch (SQLException e) {
236             logger.error("CLAMP application DB Error" + e);
237             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
238             cldsHealthCheck.setHealthCheckStatus("DOWN");
239             cldsHealthCheck.setDescription("NOT-OK");
240             // return Response.status(500).entity("Database down for CLDS
241             // application").build();
242         } catch (Exception e) {
243             logger.error("CLAMP application DB Error" + e);
244             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
245             cldsHealthCheck.setHealthCheckStatus("DOWN");
246             cldsHealthCheck.setDescription("NOT-OK");
247             // return Response.status(500).entity("Database down for CLDS
248             // application").build();
249         }
250
251         return cldsHealthCheck;
252
253     }
254
255     /**
256      * REST service that retrieves BPMN for a CLDS model name from the database.
257      * This is subset of the json getModel. This is only expected to be used for
258      * testing purposes, not by the UI.
259      *
260      * @param modelName
261      * @return bpmn xml text - content of bpmn given name
262      */
263     @ApiOperation(value = "Retrieves BPMN for a CLDS model name from the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
264     @GET
265     @Path("/model/bpmn/{modelName}")
266     @Produces(MediaType.TEXT_XML)
267     public String getBpmnXml(@PathParam("modelName") String modelName) {
268         Date startTime = new Date();
269         LoggingUtils.setRequestContext("CldsService: GET model bpmn", getPrincipalName());
270         isAuthorized(permissionReadCl);
271         logger.info("GET bpmnText for modelName={}", modelName);
272         CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
273         // audit log
274         LoggingUtils.setTimeContext(startTime, new Date());
275         LoggingUtils.setResponseContext("0", "Get model bpmn success", this.getClass().getName());
276         auditLogger.info("GET model bpmn completed");
277         return model.getBpmnText();
278     }
279
280     /**
281      * REST service that saves BPMN for a CLDS model by name in the database.
282      * This is subset of the json putModel. This is only expected to be used for
283      * testing purposes, not by the UI.
284      *
285      * @param modelName
286      */
287     @ApiOperation(value = "Saves BPMN for a CLDS model by name in the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
288     @PUT
289     @Path("/model/bpmn/{modelName}")
290     @Consumes(MediaType.TEXT_XML)
291     public String putBpmnXml(@PathParam("modelName") String modelName, String bpmnText) {
292         LoggingUtils.setRequestContext("CldsService: PUT model bpmn", getPrincipalName());
293         isAuthorized(permissionUpdateCl);
294         logger.info("PUT bpmnText for modelName={}", modelName);
295         logger.info("PUT bpmnText={}", bpmnText);
296         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
297         cldsModel.setBpmnText(bpmnText);
298         cldsModel.save(cldsDao, getUserId());
299         // audit log
300         LoggingUtils.setTimeContext(new Date(), new Date());
301         LoggingUtils.setResponseContext("0", "Put model bpmn success", this.getClass().getName());
302         auditLogger.info("PUT model bpmn completed");
303         return "wrote bpmnText for modelName=" + modelName;
304     }
305
306     /**
307      * REST service that retrieves image for a CLDS model name from the
308      * database. This is subset of the json getModel. This is only expected to
309      * be used for testing purposes, not by the UI.
310      *
311      * @param modelName
312      * @return image xml text - content of image given name
313      */
314     @ApiOperation(value = "Retrieves image for a CLDS model name from the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
315     @GET
316     @Path("/model/image/{modelName}")
317     @Produces(MediaType.TEXT_XML)
318     public String getImageXml(@PathParam("modelName") String modelName) {
319         Date startTime = new Date();
320         LoggingUtils.setRequestContext("CldsService: GET model image", getPrincipalName());
321         isAuthorized(permissionReadCl);
322         logger.info("GET imageText for modelName={}", modelName);
323         CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
324         // audit log
325         LoggingUtils.setTimeContext(startTime, new Date());
326         LoggingUtils.setResponseContext("0", "Get model image success", this.getClass().getName());
327         auditLogger.info("GET model image completed");
328         return model.getImageText();
329     }
330
331     /**
332      * REST service that saves image for a CLDS model by name in the database.
333      * This is subset of the json putModel. This is only expected to be used for
334      * testing purposes, not by the UI.
335      *
336      * @param modelName
337      */
338     @ApiOperation(value = "Saves image for a CLDS model by name in the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
339     @PUT
340     @Path("/model/image/{modelName}")
341     @Consumes(MediaType.TEXT_XML)
342     public String putImageXml(@PathParam("modelName") String modelName, String imageText) {
343         Date startTime = new Date();
344         LoggingUtils.setRequestContext("CldsService: PUT model image", getPrincipalName());
345         isAuthorized(permissionUpdateCl);
346         logger.info("PUT iamgeText for modelName={}", modelName);
347         logger.info("PUT imageText={}", imageText);
348         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
349         cldsModel.setImageText(imageText);
350         cldsModel.save(cldsDao, getUserId());
351         // audit log
352         LoggingUtils.setTimeContext(startTime, new Date());
353         LoggingUtils.setResponseContext("0", "Put model image success", this.getClass().getName());
354         auditLogger.info("PUT model image completed");
355         return "wrote imageText for modelName=" + modelName;
356     }
357
358     /**
359      * REST service that retrieves a CLDS model by name from the database.
360      *
361      * @param modelName
362      * @return clds model - clds model for the given model name
363      * @throws NotAuthorizedException
364      */
365     @ApiOperation(value = "Retrieves a CLDS model by name from the database", notes = "", response = String.class)
366     @GET
367     @Path("/model/{modelName}")
368     @Produces(MediaType.APPLICATION_JSON)
369     public CldsModel getModel(@PathParam("modelName") String modelName) throws NotAuthorizedException {
370         Date startTime = new Date();
371         LoggingUtils.setRequestContext("CldsService: GET model", getPrincipalName());
372         isAuthorized(permissionReadCl);
373         logger.debug("GET model for  modelName={}", modelName);
374         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, false);
375         isAuthorizedForVf(cldsModel);
376         cldsModel.setUserAuthorizedToUpdate(isAuthorizedNoException(permissionUpdateCl));
377
378         /**
379          * Checking condtion whether our CLDS model can call INventory Method
380          */
381         if (cldsModel.canInventoryCall()) {
382             try {
383                 /*
384                  * Below is the method to for inventory call and DB insert for
385                  * event methods
386                  */
387                 dcaeInventoryServices.setEventInventory(cldsModel, getUserId());
388             } catch (Exception e) {
389                 LoggingUtils.setErrorContext("900", "Set event inventory error");
390                 logger.error("getModel set event Inventory error:" + e);
391             }
392         }
393         // audit log
394         LoggingUtils.setTimeContext(startTime, new Date());
395         LoggingUtils.setResponseContext("0", "Get model success", this.getClass().getName());
396         auditLogger.info("GET model completed");
397         return cldsModel;
398     }
399
400     /**
401      * REST service that saves a CLDS model by name in the database.
402      *
403      * @param modelName
404      * @throws TransformerException
405      * @throws TransformerConfigurationException
406      */
407     @ApiOperation(value = "Saves a CLDS model by name in the database", notes = "", response = String.class)
408     @PUT
409     @Path("/model/{modelName}")
410     @Consumes(MediaType.APPLICATION_JSON)
411     @Produces(MediaType.APPLICATION_JSON)
412     public CldsModel putModel(@PathParam("modelName") String modelName, CldsModel cldsModel)
413             throws TransformerException {
414         Date startTime = new Date();
415         LoggingUtils.setRequestContext("CldsService: PUT model", getPrincipalName());
416         isAuthorized(permissionUpdateCl);
417         isAuthorizedForVf(cldsModel);
418         logger.info("PUT model for  modelName={}", modelName);
419         logger.info("PUT bpmnText={}", cldsModel.getBpmnText());
420         logger.info("PUT propText={}", cldsModel.getPropText());
421         logger.info("PUT imageText={}", cldsModel.getImageText());
422         cldsModel.setName(modelName);
423
424         if (cldsModel.getTemplateName() != null) {
425             CldsTemplate template = cldsDao.getTemplate(cldsModel.getTemplateName());
426             if (template != null) {
427                 cldsModel.setTemplateId(template.getId());
428                 cldsModel.setDocText(template.getPropText());
429                 cldsModel.setDocId(template.getPropId());
430             }
431         }
432         cldsModel.save(cldsDao, getUserId());
433         cldsModel.save(cldsDao, getUserId());
434         // audit log
435         LoggingUtils.setTimeContext(startTime, new Date());
436         LoggingUtils.setResponseContext("0", "Put model success", this.getClass().getName());
437         auditLogger.info("PUT model completed");
438         return cldsModel;
439     }
440
441     /**
442      * REST service that retrieves a list of CLDS model names.
443      *
444      * @return model names in JSON
445      */
446     @ApiOperation(value = "Retrieves a list of CLDS model names", notes = "", response = String.class)
447     @GET
448     @Path("/model-names")
449     @Produces(MediaType.APPLICATION_JSON)
450     public List<ValueItem> getModelNames() {
451         Date startTime = new Date();
452         LoggingUtils.setRequestContext("CldsService: GET model names", getPrincipalName());
453         isAuthorized(permissionReadCl);
454         logger.info("GET list of model names");
455         List<ValueItem> names = cldsDao.getBpmnNames();
456         // audit log
457         LoggingUtils.setTimeContext(startTime, new Date());
458         LoggingUtils.setResponseContext("0", "Get model names success", this.getClass().getName());
459         auditLogger.info("GET model names completed");
460         return names;
461     }
462
463     /**
464      * REST service that saves and processes an action for a CLDS model by name.
465      *
466      * @param action
467      * @param modelName
468      * @param test
469      * @param model
470      * @return
471      * @throws Exception
472      * @throws JsonProcessingException
473      * @throws NotAuthorizedException
474      */
475     @ApiOperation(value = "Saves and processes an action for a CLDS model by name", notes = "", response = String.class)
476     @PUT
477     @Path("/action/{action}/{modelName}")
478     @Consumes(MediaType.APPLICATION_JSON)
479     @Produces(MediaType.APPLICATION_JSON)
480     public CldsModel putModelAndProcessAction(@PathParam("action") String action,
481             @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model)
482             throws Exception {
483         Date startTime = new Date();
484         LoggingUtils.setRequestContext("CldsService: Process model action", getPrincipalName());
485         String actionCd = action.toUpperCase();
486         SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage,
487                 cldsPermissionInstance, actionCd);
488         isAuthorized(permisionManage);
489         isAuthorizedForVf(model);
490         String userid = getUserId();
491         String actionStateCd = CldsEvent.ACTION_STATE_INITIATED;
492         String processDefinitionKey = "clds-process-action-wf";
493
494         logger.info("PUT actionCd={}", actionCd);
495         logger.info("PUT actionStateCd={}", actionStateCd);
496         logger.info("PUT processDefinitionKey={}", processDefinitionKey);
497         logger.info("PUT modelName={}", modelName);
498         logger.info("PUT test={}", test);
499         logger.info("PUT bpmnText={}", model.getBpmnText());
500         logger.info("PUT propText={}", model.getPropText());
501         logger.info("PUT userid={}", userid);
502         logger.info("PUT getTypeId={}", model.getTypeId());
503         logger.info("PUT deploymentId={}", model.getDeploymentId());
504
505         if (model.getTemplateName() != null) {
506             CldsTemplate template = cldsDao.getTemplate(model.getTemplateName());
507             if (template != null) {
508                 model.setTemplateId(template.getId());
509                 model.setDocText(template.getPropText());
510                 model.setDocId(template.getPropId());
511             }
512         }
513         // save model to db
514         model.setName(modelName);
515         model.save(cldsDao, getUserId());
516
517         // get vars and format if necessary
518         String prop = model.getPropText();
519         String bpmn = model.getBpmnText();
520         String docText = model.getDocText();
521         String controlName = model.getControlName();
522
523         String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn);
524         logger.info("PUT bpmnJson={}", bpmnJson);
525
526         // Flag indicates whether it is triggered by Validation Test button from
527         // UI
528         boolean isTest = false;
529         if (test != null && test.equalsIgnoreCase("true")) {
530             isTest = true;
531         } else {
532             // if action.test.override is true, then any action will be marked
533             // as test=true (even if incoming action request had test=false);
534             // otherwise, test flag will be unchanged on the action request
535             String actionTestOverride = refProp.getStringValue("action.test.override");
536             if (actionTestOverride != null && actionTestOverride.equalsIgnoreCase("true")) {
537                 logger.info("PUT actionTestOverride={}", actionTestOverride);
538                 logger.info("PUT override test indicator and setting it to true");
539                 isTest = true;
540             }
541         }
542         logger.info("PUT isTest={}", isTest);
543
544         boolean isInsertTestEvent = false;
545         String insertTestEvent = refProp.getStringValue("action.insert.test.event");
546         if (insertTestEvent != null && insertTestEvent.equalsIgnoreCase("true")) {
547             isInsertTestEvent = true;
548         }
549         logger.info("PUT isInsertTestEvent={}", isInsertTestEvent);
550
551         // determine if requested action is permitted
552         model.validateAction(actionCd);
553
554         // input variables to camunda process
555         Map<String, Object> variables = new HashMap<>();
556         variables.put("actionCd", actionCd);
557         variables.put("modelProp", prop.getBytes());
558         variables.put("modelBpmnProp", bpmnJson);
559         variables.put("modelName", modelName);
560         variables.put("controlName", controlName);
561         variables.put("docText", docText.getBytes());
562         variables.put("isTest", isTest);
563         variables.put("userid", userid);
564         variables.put("isInsertTestEvent", isInsertTestEvent);
565         logger.info("modelProp - " + prop);
566         logger.info("docText - " + docText);
567
568         // start camunda process
569         ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
570
571         // log process info
572         logger.info("Started processDefinitionId={}, processInstanceId={}", pi.getProcessDefinitionId(),
573                 pi.getProcessInstanceId());
574
575         // refresh model info from db (get fresh event info)
576         CldsModel retreivedModel = CldsModel.retrieve(cldsDao, modelName, false);
577
578         if (actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMIT)
579                 || actionCd.equalsIgnoreCase(CldsEvent.ACTION_RESUBMIT)) {
580             // To verify inventory status and modify model status to distribute
581             dcaeInventoryServices.setEventInventory(retreivedModel, getUserId());
582             retreivedModel.save(cldsDao, getUserId());
583         }
584         // audit log
585         LoggingUtils.setTimeContext(startTime, new Date());
586         LoggingUtils.setResponseContext("0", "Process model action success", this.getClass().getName());
587         auditLogger.info("Process model action completed");
588
589         return retreivedModel;
590     }
591
592     /**
593      * REST service that accepts events for a model.
594      *
595      * @param test
596      * @param dcaeEvent
597      */
598     @ApiOperation(value = "Accepts events for a model", notes = "", response = String.class)
599     @POST
600     @Path("/dcae/event")
601     @Consumes(MediaType.APPLICATION_JSON)
602     @Produces(MediaType.APPLICATION_JSON)
603     public String postDcaeEvent(@QueryParam("test") String test, DcaeEvent dcaeEvent) {
604         Date startTime = new Date();
605         LoggingUtils.setRequestContext("CldsService: Post dcae event", getPrincipalName());
606         String userid = null;
607         // TODO: allow auth checking to be turned off by removing the permission
608         // type property
609         if (cldsPermissionTypeClEvent != null && cldsPermissionTypeClEvent.length() > 0) {
610             SecureServicePermission permissionEvent = SecureServicePermission.create(cldsPermissionTypeClEvent,
611                     cldsPermissionInstance, dcaeEvent.getEvent());
612             isAuthorized(permissionEvent);
613             userid = getUserId();
614         }
615
616         // Flag indicates whether it is triggered by Validation Test button from
617         // UI
618         boolean isTest = false;
619         if (test != null && test.equalsIgnoreCase("true")) {
620             isTest = true;
621         }
622
623         int instanceCount = 0;
624         if (dcaeEvent.getInstances() != null) {
625             instanceCount = dcaeEvent.getInstances().size();
626         }
627         String msgInfo = "event=" + dcaeEvent.getEvent() + " serviceUUID=" + dcaeEvent.getServiceUUID()
628                 + " resourceUUID=" + dcaeEvent.getResourceUUID() + " artifactName=" + dcaeEvent.getArtifactName()
629                 + " instance count=" + instanceCount + " isTest=" + isTest;
630         logger.info("POST dcae event {}", msgInfo);
631
632         if (isTest) {
633             logger.warn("Ignorning test event from DCAE");
634         } else {
635             if (DcaeEvent.EVENT_DEPLOYMENT.equalsIgnoreCase(dcaeEvent.getEvent())) {
636                 CldsModel.insertModelInstance(cldsDao, dcaeEvent, userid);
637             } else {
638                 CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(),
639                         CldsEvent.ACTION_STATE_RECEIVED, null);
640             }
641         }
642         // audit log
643         LoggingUtils.setTimeContext(startTime, new Date());
644         LoggingUtils.setResponseContext("0", "Post dcae event success", this.getClass().getName());
645         auditLogger.info("Post dcae event completed");
646
647         return msgInfo;
648     }
649
650     /**
651      * REST service that retrieves sdc services
652      *
653      * @throws Exception
654      */
655     @ApiOperation(value = "Retrieves sdc services", notes = "", response = String.class)
656     @GET
657     @Path("/sdc/services")
658     @Produces(MediaType.APPLICATION_JSON)
659     public String getSdcServices() throws Exception {
660         Date startTime = new Date();
661         LoggingUtils.setRequestContext("CldsService: GET sdc services", getPrincipalName());
662         String retStr;
663         try {
664             String responseStr = sdcCatalogServices.getSdcServicesInformation(null);
665             retStr = createUiServiceFormatJson(responseStr);
666         } catch (Exception e) {
667             logger.info("{} {}", e.getClass().getName(), e.getMessage());
668             throw e;
669         }
670         logger.info("value of sdcServices : {}", retStr);
671         // audit log
672         LoggingUtils.setTimeContext(startTime, new Date());
673         LoggingUtils.setResponseContext("0", "Get sdc services success", this.getClass().getName());
674         auditLogger.info("GET sdc services completed");
675         return retStr;
676     }
677
678     /**
679      * REST service that retrieves total properties required by UI
680      *
681      * @throws Exception
682      */
683     @ApiOperation(value = "Retrieves total properties required by UI", notes = "", response = String.class)
684     @GET
685     @Path("/properties")
686     @Produces(MediaType.APPLICATION_JSON)
687     public String getSdcProperties() throws Exception {
688         return createPropertiesObjectByUUID(getGlobalCldsString(), "{}");
689     }
690
691     /**
692      * REST service that retrieves total properties by using invariantUUID based
693      * on refresh and non refresh
694      *
695      * @throws Exception
696      */
697     @ApiOperation(value = "Retrieves total properties by using invariantUUID based on refresh and non refresh", notes = "", response = String.class)
698     @GET
699     @Path("/properties/{serviceInvariantUUID}")
700     @Produces(MediaType.APPLICATION_JSON)
701     public String getSdcPropertiesByServiceUUIDForRefresh(
702             @PathParam("serviceInvariantUUID") String serviceInvariantUUID,
703             @DefaultValue("false") @QueryParam("refresh") String refresh) throws Exception {
704         Date startTime = new Date();
705         LoggingUtils.setRequestContext("CldsService: GET sdc properties by uuid", getPrincipalName());
706         CldsServiceData cldsServiceData = new CldsServiceData();
707         cldsServiceData.setServiceInvariantUUID(serviceInvariantUUID);
708
709         boolean isCldsSdcDataExpired = true;
710         // To getcldsService information from database cache using invariantUUID
711         // only when refresh = false
712         if (refresh != null && refresh.equalsIgnoreCase("false")) {
713             cldsServiceData = cldsServiceData.getCldsServiceCache(cldsDao, serviceInvariantUUID);
714             // If cldsService is available in database Cache , verify is data
715             // expired or not
716             if (cldsServiceData != null) {
717                 isCldsSdcDataExpired = sdcCatalogServices.isCldsSdcCacheDataExpired(cldsServiceData);
718             }
719         }
720         // If user Requested for refresh or database cache expired , get all
721         // data from sdc api.
722         if ((refresh != null && refresh.equalsIgnoreCase("true")) || isCldsSdcDataExpired) {
723             cldsServiceData = sdcCatalogServices.getCldsServiceDataWithAlarmConditions(serviceInvariantUUID);
724             CldsDBServiceCache cldsDBServiceCache = sdcCatalogServices
725                     .getCldsDbServiceCacheUsingCldsServiceData(cldsServiceData);
726             if (cldsDBServiceCache != null && cldsDBServiceCache.getInvariantId() != null
727                     && cldsDBServiceCache.getServiceId() != null) {
728                 cldsServiceData.setCldsServiceCache(cldsDao, cldsDBServiceCache);
729             }
730         }
731
732         // filter out VFs the user is not authorized for
733         cldsServiceData.filterVfs(this);
734
735         // audit log
736         LoggingUtils.setTimeContext(startTime, new Date());
737         LoggingUtils.setResponseContext("0", "Get sdc properties by uuid success", this.getClass().getName());
738         auditLogger.info("GET sdc properties by uuid completed");
739
740         // format retrieved data into properties json
741         return sdcCatalogServices.createPropertiesObjectByUUID(getGlobalCldsString(), cldsServiceData);
742     }
743
744     /**
745      * Determine if the user is authorized for a particular VF by its invariant
746      * UUID.
747      *
748      * @param vfInvariantUuid
749      * @throws NotAuthorizedException
750      * @return
751      */
752     public boolean isAuthorizedForVf(String vfInvariantUuid) throws NotAuthorizedException {
753         if (cldsPermissionTypeFilterVf != null && cldsPermissionTypeFilterVf.length() > 0) {
754             SecureServicePermission permission = SecureServicePermission.create(cldsPermissionTypeFilterVf,
755                     cldsPermissionInstance, vfInvariantUuid);
756             return isAuthorized(permission);
757         } else {
758             // if CLDS_PERMISSION_TYPE_FILTER_VF property is not provided, then
759             // VF filtering is turned off
760             logger.warn("VF filtering turned off");
761             return true;
762         }
763     }
764
765     /**
766      * Determine if the user is authorized for a particular VF by its invariant
767      * UUID. If not authorized, then NotAuthorizedException is thrown.
768      *
769      * @param model
770      * @return
771      */
772     private boolean isAuthorizedForVf(CldsModel model) throws NotAuthorizedException {
773         String vf = ModelProperties.getVf(model);
774         if (vf == null || vf.length() == 0) {
775             logger.info("VF not found in model");
776             return true;
777         } else {
778             return isAuthorizedForVf(vf);
779         }
780     }
781
782     private String createUiServiceFormatJson(String responseStr) throws IOException {
783         if (StringUtils.isBlank(responseStr)) {
784             return "";
785         }
786         ObjectMapper objectMapper = new ObjectMapper();
787         List<CldsSdcServiceInfo> rawList = objectMapper.readValue(responseStr,
788                 objectMapper.getTypeFactory().constructCollectionType(List.class, CldsSdcServiceInfo.class));
789         ObjectNode invariantIdServiceNode = objectMapper.createObjectNode();
790         ObjectNode serviceNode = objectMapper.createObjectNode();
791         logger.info("value of cldsserviceiNfolist: {}", rawList);
792         if (rawList != null && rawList.size() > 0) {
793             List<CldsSdcServiceInfo> cldsSdcServiceInfoList = sdcCatalogServices.removeDuplicateServices(rawList);
794
795             for (CldsSdcServiceInfo currCldsSdcServiceInfo : cldsSdcServiceInfoList) {
796                 if (currCldsSdcServiceInfo != null) {
797                     invariantIdServiceNode.put(currCldsSdcServiceInfo.getInvariantUUID(),
798                             currCldsSdcServiceInfo.getName());
799                 }
800             }
801             serviceNode.putPOJO("service", invariantIdServiceNode);
802         }
803         return serviceNode.toString();
804     }
805
806     private String createPropertiesObjectByUUID(String globalProps, String cldsResponseStr) throws IOException {
807         ObjectMapper mapper = new ObjectMapper();
808         CldsSdcServiceDetail cldsSdcServiceDetail = mapper.readValue(cldsResponseStr, CldsSdcServiceDetail.class);
809         ObjectNode globalPropsJson = null;
810         if (cldsSdcServiceDetail != null && cldsSdcServiceDetail.getUuid() != null) {
811             /**
812              * to create json with vf, alarm and locations
813              */
814             ObjectNode serviceObjectNode = createEmptyVfAlarmObject(mapper);
815             ObjectNode vfObjectNode = mapper.createObjectNode();
816
817             /**
818              * to create json with vf and vfresourceId
819              */
820             createVfObjectNode(vfObjectNode, mapper, cldsSdcServiceDetail.getResources());
821             serviceObjectNode.putPOJO(cldsSdcServiceDetail.getInvariantUUID(), vfObjectNode);
822             ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
823             byServiceBasicObjetNode.putPOJO("byService", serviceObjectNode);
824
825             /**
826              * to create json with VFC Node
827              */
828             ObjectNode emptyvfcobjectNode = createByVFCObjectNode(mapper, cldsSdcServiceDetail.getResources());
829             byServiceBasicObjetNode.putPOJO("byVf", emptyvfcobjectNode);
830             globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
831             globalPropsJson.putPOJO("shared", byServiceBasicObjetNode);
832             logger.info("valuie of objNode: {}", globalPropsJson);
833         } else {
834             /**
835              * to create json with total properties when no serviceUUID passed
836              */
837             globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
838         }
839         return globalPropsJson.toString();
840     }
841
842     private ObjectNode createEmptyVfAlarmObject(ObjectMapper mapper) {
843         ObjectNode emptyObjectNode = mapper.createObjectNode();
844         emptyObjectNode.put("", "");
845         ObjectNode vfObjectNode = mapper.createObjectNode();
846         vfObjectNode.putPOJO("vf", emptyObjectNode);
847         vfObjectNode.putPOJO("location", emptyObjectNode);
848         vfObjectNode.putPOJO("alarmCondition", emptyObjectNode);
849         ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
850         emptyServiceObjectNode.putPOJO("", vfObjectNode);
851         return emptyServiceObjectNode;
852     }
853
854     private void createVfObjectNode(ObjectNode vfObjectNode2, ObjectMapper mapper,
855             List<CldsSdcResource> rawCldsSdcResourceList) throws IOException {
856         ObjectNode vfNode = mapper.createObjectNode();
857         vfNode.put("", "");
858
859         // To remove repeated resource instance name from resourceInstanceList
860         List<CldsSdcResource> cldsSdcResourceList = sdcCatalogServices
861                 .removeDuplicateSdcResourceInstances(rawCldsSdcResourceList);
862         /**
863          * Creating vf resource node using cldsSdcResource Object
864          */
865         if (cldsSdcResourceList != null && cldsSdcResourceList.size() > 0) {
866             for (CldsSdcResource cldsSdcResource : cldsSdcResourceList) {
867                 if (cldsSdcResource != null && cldsSdcResource.getResoucreType() != null
868                         && cldsSdcResource.getResoucreType().equalsIgnoreCase("VF")) {
869                     vfNode.put(cldsSdcResource.getResourceUUID(), cldsSdcResource.getResourceName());
870                 }
871             }
872         }
873         vfObjectNode2.putPOJO("vf", vfNode);
874         String locationStringValue = refProp.getStringValue("ui.location.default");
875         String alarmStringValue = refProp.getStringValue("ui.alarm.default");
876
877         /**
878          * creating location json object using properties file value
879          */
880         ObjectNode locationJsonNode = (ObjectNode) mapper.readValue(locationStringValue, JsonNode.class);
881         vfObjectNode2.putPOJO("location", locationJsonNode);
882
883         /**
884          * creating alarm json object using properties file value
885          */
886         logger.info("value of alarm: {}", alarmStringValue);
887         ObjectNode alarmStringJsonNode = (ObjectNode) mapper.readValue(alarmStringValue, JsonNode.class);
888         vfObjectNode2.putPOJO("alarmCondition", alarmStringJsonNode);
889     }
890
891     private ObjectNode createByVFCObjectNode(ObjectMapper mapper, List<CldsSdcResource> cldsSdcResourceList) {
892         ObjectNode emptyObjectNode = mapper.createObjectNode();
893         ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
894         ObjectNode vfCObjectNode = mapper.createObjectNode();
895         vfCObjectNode.putPOJO("vfC", emptyObjectNode);
896         ObjectNode subVfCObjectNode = mapper.createObjectNode();
897         subVfCObjectNode.putPOJO("vfc", emptyObjectNode);
898         if (cldsSdcResourceList != null && cldsSdcResourceList.size() > 0) {
899             for (CldsSdcResource cldsSdcResource : cldsSdcResourceList) {
900                 if (cldsSdcResource != null && cldsSdcResource.getResoucreType() != null
901                         && cldsSdcResource.getResoucreType().equalsIgnoreCase("VF")) {
902                     vfCObjectNode.putPOJO(cldsSdcResource.getResourceUUID(), subVfCObjectNode);
903                 }
904             }
905         }
906         emptyvfcobjectNode.putPOJO("", vfCObjectNode);
907         return emptyvfcobjectNode;
908     }
909
910     @PUT
911     @Path("/deploy/{modelName}")
912     @Consumes(MediaType.APPLICATION_JSON)
913     @Produces(MediaType.APPLICATION_JSON)
914     public CldsModel deployModel(@PathParam("action") String action, @PathParam("modelName") String modelName,
915             @QueryParam("test") String test, CldsModel model) throws Exception {
916         Date startTime = new Date();
917         LoggingUtils.setRequestContext("CldsService: Deploy model", getPrincipalName());
918         String deploymentId = "closedLoop_" + UUID.randomUUID() + "_deploymentId";
919         String createNewDeploymentStatusUrl = dcaeDispatcherServices.createNewDeployment(deploymentId,
920                 model.getTypeId());
921         String operationStatus = "processing";
922         long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10);
923         while (operationStatus.equalsIgnoreCase("processing")) {
924             // Break the loop if waiting for more than 10 mins
925             if (waitingTime < System.nanoTime()) {
926                 break;
927             }
928             operationStatus = dcaeDispatcherServices.getOperationStatus(createNewDeploymentStatusUrl);
929         }
930         if (operationStatus.equalsIgnoreCase("succeeded")) {
931             String artifactName = model.getControlName();
932             if (artifactName != null) {
933                 artifactName = artifactName + ".yml";
934             }
935             DcaeEvent dcaeEvent = new DcaeEvent();
936             /* set dcae events */
937             dcaeEvent.setArtifactName(artifactName);
938             dcaeEvent.setEvent(DcaeEvent.EVENT_DEPLOYMENT);
939             CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(),
940                     CldsEvent.ACTION_STATE_RECEIVED, null);
941             model.setDeploymentId(deploymentId);
942             model.save(cldsDao, getUserId());
943         } else {
944             logger.info("Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
945             throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR,
946                     "Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
947         }
948         logger.info("Deploy model (" + modelName + ") succeeded...Deployment Id is - " + deploymentId);
949         // audit log
950         LoggingUtils.setTimeContext(startTime, new Date());
951         LoggingUtils.setResponseContext("0", "Deploy model success", this.getClass().getName());
952         auditLogger.info("Deploy model completed");
953         return model;
954     }
955
956     @PUT
957     @Path("/undeploy/{modelName}")
958     @Consumes(MediaType.APPLICATION_JSON)
959     @Produces(MediaType.APPLICATION_JSON)
960     public CldsModel unDeployModel(@PathParam("action") String action, @PathParam("modelName") String modelName,
961             @QueryParam("test") String test, CldsModel model) throws Exception {
962         Date startTime = new Date();
963         LoggingUtils.setRequestContext("CldsService: Undeploy model", getPrincipalName());
964         String operationStatusUndeployUrl = dcaeDispatcherServices.deleteExistingDeployment(model.getDeploymentId(),
965                 model.getTypeId());
966         String operationStatus = "processing";
967         long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10);
968         while (operationStatus.equalsIgnoreCase("processing")) {
969             if (waitingTime < System.nanoTime()) {
970                 break;
971             }
972             operationStatus = dcaeDispatcherServices.getOperationStatus(operationStatusUndeployUrl);
973         }
974         if (operationStatus.equalsIgnoreCase("succeeded")) {
975             String artifactName = model.getControlName();
976             if (artifactName != null) {
977                 artifactName = artifactName + ".yml";
978             }
979             DcaeEvent dcaeEvent = new DcaeEvent();
980             // set dcae events
981             dcaeEvent.setArtifactName(artifactName);
982             dcaeEvent.setEvent(DcaeEvent.EVENT_UNDEPLOYMENT);
983             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(),
984                     CldsEvent.ACTION_STATE_RECEIVED, null);
985             model.setDeploymentId(null);
986             model.save(cldsDao, getUserId());
987         } else {
988             logger.info("Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
989             throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR,
990                     "Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
991         }
992         logger.info("Undeploy model (" + modelName + ") succeeded.");
993         // audit log
994         LoggingUtils.setTimeContext(startTime, new Date());
995         LoggingUtils.setResponseContext("0", "Undeploy model success", this.getClass().getName());
996         auditLogger.info("Undeploy model completed");
997         return model;
998     }
999
1000     private String getGlobalCldsString() throws Exception {
1001         if (null == globalCldsProperties) {
1002             globalCldsProperties = new Properties();
1003             globalCldsProperties.load(appContext.getResource(globalClds).getInputStream());
1004         }
1005         return (String) globalCldsProperties.get("globalCldsProps");
1006     }
1007 }