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