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