19c8ca03ea61028111a818ede846c692967e0f81
[sdnc/apps.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SDNC
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.sdnc.apps.ms.gra.controllers;
22
23 import java.text.DateFormat;
24 import java.text.SimpleDateFormat;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.Properties;
29 import java.util.TimeZone;
30
31 import javax.servlet.http.HttpServletRequest;
32 import javax.validation.Valid;
33
34 import com.fasterxml.jackson.annotation.JsonInclude;
35 import com.fasterxml.jackson.core.JsonProcessingException;
36 import com.fasterxml.jackson.databind.JsonMappingException;
37 import com.fasterxml.jackson.databind.ObjectMapper;
38
39 import org.onap.ccsdk.apps.services.RestException;
40 import org.onap.ccsdk.apps.services.SvcLogicFactory;
41 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
42 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
43 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase;
44 import org.onap.sdnc.apps.ms.gra.data.ConfigContrailRouteAllottedResourcesRepository;
45 import org.onap.sdnc.apps.ms.gra.data.ConfigNetworksRepository;
46 import org.onap.sdnc.apps.ms.gra.data.ConfigPortMirrorConfigurations;
47 import org.onap.sdnc.apps.ms.gra.data.ConfigPortMirrorConfigurationsRepository;
48 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
49 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
50 import org.onap.sdnc.apps.ms.gra.data.ConfigServices;
51 import org.onap.sdnc.apps.ms.gra.data.ConfigServicesRepository;
52 import org.onap.sdnc.apps.ms.gra.data.ConfigVfModulesRepository;
53 import org.onap.sdnc.apps.ms.gra.data.ConfigVnfsRepository;
54 import org.onap.sdnc.apps.ms.gra.data.OperationalContrailRouteAllottedResourcesRepository;
55 import org.onap.sdnc.apps.ms.gra.data.OperationalPortMirrorConfigurationsRepository;
56 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadData;
57 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadDataRepository;
58 import org.onap.sdnc.apps.ms.gra.data.OperationalServices;
59 import org.onap.sdnc.apps.ms.gra.data.OperationalServicesRepository;
60 import org.onap.sdnc.apps.ms.gra.swagger.OperationsApi;
61 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiInstanceReference;
62 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiNetworkOperationInformation;
63 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiNetworkOperationInformationBodyparam;
64 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiNetworkTopologyOperation;
65 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiNetworktopologyoperationOutput;
66 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPolicyUpdateNotifyOperation;
67 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPolicyupdatenotifyoperationInput;
68 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPolicyupdatenotifyoperationInputBodyparam;
69 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPolicyupdatenotifyoperationOutput;
70 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPortMirrorTopologyOperation;
71 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPortMirrorTopologyOperationInformation;
72 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPortMirrorTopologyOperationInformationBodyparam;
73 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPortmirrortopologyoperationOutput;
74 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloadNetworkTopologyOperation;
75 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloadTopologyResponseBody;
76 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloadVfModuleTopologyOperation;
77 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloaddataPreloadData;
78 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloadnetworktopologyoperationInputBodyparam;
79 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam;
80 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiRequestStatusEnumeration;
81 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServiceOperationInformation;
82 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServiceOperationInformationBodyparam;
83 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServiceTopologyOperation;
84 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiServicetopologyoperationOutput;
85 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVfModuleOperationInformation;
86 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVfModuleOperationInformationBodyparam;
87 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVfModuleTopologyOperation;
88 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVfmoduletopologyoperationOutput;
89 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfGetResourceRequest;
90 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfOperationInformation;
91 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfOperationInformationBodyparam;
92 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfTopologyOperation;
93 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfgetresourcerequestInput;
94 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfgetresourcerequestInputBodyparam;
95 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnfgetresourcerequestOutput;
96 import org.onap.sdnc.apps.ms.gra.swagger.model.GenericResourceApiVnftopologyoperationOutput;
97 import org.springframework.beans.factory.annotation.Autowired;
98 import org.springframework.boot.autoconfigure.domain.EntityScan;
99 import org.springframework.context.annotation.ComponentScan;
100 import org.springframework.context.annotation.Import;
101 import org.springframework.http.HttpStatus;
102 import org.springframework.http.ResponseEntity;
103 import org.springframework.stereotype.Controller;
104
105 @Controller
106 @ComponentScan(basePackages = { "org.onap.sdnc.apps.ms.gra.*", "org.onap.ccsdk.apps.services" })
107 @EntityScan("org.onap.sdnc.apps.ms.gra.*")
108 @Import(value = SvcLogicFactory.class)
109 public class OperationsApiController implements OperationsApi {
110
111     private static final String CALLED_STR = "{} called.";
112     private static final String MODULE_NAME = "GENERIC-RESOURCE-API";
113     private static final String SERVICE_OBJECT_PATH_PARAM = "service-object-path";
114     private static final String NETWORK_OBJECT_PATH_PARAM = "network-object-path";
115     private static final String VNF_OBJECT_PATH_PARAM = "vnf-object-path";
116     private static final String PNF_OBJECT_PATH_PARAM = "pnf-object-path";
117     private static final String VF_MODULE_OBJECT_PATH_PARAM = "vf-module-object-path";
118     private static final String PORT_MIRROR_OBJECT_PATH_PARAM = "port-mirror-object-path";
119     private static final String BACKGROUND_THREAD_STARTED_MESSAGE = "Start background thread";
120     private static final String BACKGROUND_THREAD_INFO = "Background thread: input conf_id is {}";
121     private static final String SKIP_MDSAL_UPDATE_PROP = "skip-mdsal-update";
122     private static final String ADDING_INPUT_DATA_LOG = "Adding INPUT data for {} [{}] input: {}";
123     private static final String ADDING_OPERATIONAL_DATA_LOG = "Adding OPERATIONAL data for {} [{}] operational-data: {}";
124
125     private final ObjectMapper objectMapper;
126
127     private final HttpServletRequest request;
128
129     @Autowired
130     protected SvcLogicServiceBase svc;
131
132     @Autowired
133     private ConfigPreloadDataRepository configPreloadDataRepository;
134
135     @Autowired
136     private OperationalPreloadDataRepository operationalPreloadDataRepository;
137
138     @Autowired
139     private ConfigServicesRepository configServicesRepository;
140
141     @Autowired
142     private OperationalServicesRepository operationalServicesRepository;
143
144     @Autowired
145     private ConfigNetworksRepository configNetworksRepository;
146
147     @Autowired 
148     private ConfigVnfsRepository configVnfsRepository;
149
150     @Autowired
151     private ConfigVfModulesRepository configVfModulesRepository;
152
153     @Autowired
154     private ConfigContrailRouteAllottedResourcesRepository configContrailRouteAllottedResourcesRepository;
155
156     @Autowired
157     private OperationalContrailRouteAllottedResourcesRepository operationalContrailRouteAllottedResourcesRepository;
158
159     @Autowired
160     private ConfigPortMirrorConfigurationsRepository configPortMirrorConfigurationsRepository;
161
162     @Autowired
163     private OperationalPortMirrorConfigurationsRepository operationalPortMirrorConfigurationsRepository;
164
165     @Autowired
166     private ServiceDataHelper serviceDataHelper;
167
168     private static class Iso8601Util {
169
170         private static TimeZone timeZone = TimeZone.getTimeZone("UTC");
171         private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
172
173         private Iso8601Util() {
174         }
175
176         static {
177             dateFormat.setTimeZone(timeZone);
178         }
179
180         private static String now() {
181             return dateFormat.format(new Date());
182         }
183     }
184
185     @org.springframework.beans.factory.annotation.Autowired
186     public OperationsApiController(ObjectMapper objectMapper, HttpServletRequest request) {
187         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
188         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
189         this.objectMapper = objectMapper;
190         this.request = request;
191     }
192
193     @Override
194     public Optional<ObjectMapper> getObjectMapper() {
195         return Optional.ofNullable(objectMapper);
196     }
197
198     @Override
199     public Optional<HttpServletRequest> getRequest() {
200         return Optional.ofNullable(request);
201     }
202
203     @Override
204     public ResponseEntity<GenericResourceApiPreloadNetworkTopologyOperation> operationsGENERICRESOURCEAPIpreloadNetworkTopologyOperationPost(
205             @Valid GenericResourceApiPreloadnetworktopologyoperationInputBodyparam graInput) {
206         final String svcOperation = "preload-network-topology-operation";
207         GenericResourceApiPreloadNetworkTopologyOperation retval = new GenericResourceApiPreloadNetworkTopologyOperation();
208         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
209
210         log.info(CALLED_STR, svcOperation);
211         if (hasInvalidPreloadNetwork(graInput)) {
212             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
213
214             resp.setResponseCode("403");
215             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
216             resp.setAckFinalIndicator("Y");
217
218             retval.setOutput(resp);
219
220             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
221         }
222
223         String preloadId = graInput.getInput().getPreloadNetworkTopologyInformation()
224                 .getNetworkTopologyIdentifierStructure().getNetworkId();
225         String preloadType = "network";
226
227         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
228
229         SvcLogicContext ctxIn = new SvcLogicContext();
230
231         GenericResourceApiPreloaddataPreloadData preloadData = null;
232
233         // Add input to SvcLogicContext
234         try {
235             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
236         } catch (JsonProcessingException e) {
237             log.error("exiting {} due to parse error on input preload data", svcOperation);
238             resp.setResponseCode("500");
239             resp.setResponseMessage("internal error");
240             resp.setAckFinalIndicator("Y");
241             retval.setOutput(resp);
242             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
243         }
244
245         // Add config tree data to SvcLogicContext
246         try {
247             preloadData = getConfigPreloadData(preloadId, preloadType);
248             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
249         } catch (JsonProcessingException e) {
250             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
251             resp.setResponseCode("500");
252             resp.setResponseMessage("internal error");
253             resp.setAckFinalIndicator("Y");
254             retval.setOutput(resp);
255             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
256         }
257
258         // Add operational tree data to SvcLogicContext
259         try {
260             preloadData = getOperationalPreloadData(preloadId, preloadType);
261             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
262         } catch (JsonProcessingException e) {
263             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
264             resp.setResponseCode("500");
265             resp.setResponseMessage("internal error");
266             resp.setAckFinalIndicator("Y");
267             retval.setOutput(resp);
268             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
269         }
270
271         // Call DG
272         try {
273             // Any of these can throw a nullpointer exception
274             // execute should only throw a SvcLogicException
275             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
276             Properties respProps = ctxOut.toProperties();
277
278             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
279             resp.setResponseCode(respProps.getProperty("error-code", "200"));
280             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
281
282             if ("200".equals(resp.getResponseCode())) {
283                 // If DG returns success, update database
284                 String ctxJson = ctxOut.toJsonString("preload-data");
285                 log.info("DG preload-data is {}", ctxJson);
286                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
287                         GenericResourceApiPreloaddataPreloadData.class);
288                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
289                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
290             }
291
292         } catch (NullPointerException npe) {
293             log.error("Caught NPE", npe);
294             resp.setAckFinalIndicator("true");
295             resp.setResponseCode("500");
296             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
297         } catch (SvcLogicException e) {
298             log.error("Caught SvcLogicException", e);
299             resp.setAckFinalIndicator("true");
300             resp.setResponseCode("500");
301             resp.setResponseMessage(e.getMessage());
302         } catch (JsonMappingException e) {
303             log.error("Caught JsonMappingException", e);
304             resp.setAckFinalIndicator("true");
305             resp.setResponseCode("500");
306             resp.setResponseMessage(e.getMessage());
307         } catch (JsonProcessingException e) {
308             log.error("Caught JsonProcessingException", e);
309             resp.setAckFinalIndicator("true");
310             resp.setResponseCode("500");
311             resp.setResponseMessage(e.getMessage());
312         }
313
314         retval.setOutput(resp);
315         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
316     }
317
318     @Override
319     public ResponseEntity<GenericResourceApiPreloadVfModuleTopologyOperation> operationsGENERICRESOURCEAPIpreloadVfModuleTopologyOperationPost(
320             @Valid GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam graInput) {
321         final String svcOperation = "preload-vf-module-topology-operation";
322         GenericResourceApiPreloadVfModuleTopologyOperation retval = new GenericResourceApiPreloadVfModuleTopologyOperation();
323         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
324
325         log.info(CALLED_STR, svcOperation);
326         if (hasInvalidPreloadNetwork(graInput)) {
327             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
328
329             resp.setResponseCode("403");
330             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
331             resp.setAckFinalIndicator("Y");
332
333             retval.setOutput(resp);
334
335             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
336         }
337
338         String preloadId = graInput.getInput().getPreloadVfModuleTopologyInformation().getVfModuleTopology()
339                 .getVfModuleTopologyIdentifier().getVfModuleName();
340         String preloadType = "vf-module";
341
342         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
343
344         SvcLogicContext ctxIn = new SvcLogicContext();
345
346         GenericResourceApiPreloaddataPreloadData preloadData = null;
347
348         // Add input to SvcLogicContext
349         try {
350             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
351         } catch (JsonProcessingException e) {
352             log.error("exiting {} due to parse error on input preload data", svcOperation);
353             resp.setResponseCode("500");
354             resp.setResponseMessage("internal error");
355             resp.setAckFinalIndicator("Y");
356             retval.setOutput(resp);
357             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
358         }
359
360         // Add config tree data to SvcLogicContext
361         try {
362             preloadData = getConfigPreloadData(preloadId, preloadType);
363             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
364         } catch (JsonProcessingException e) {
365             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
366             resp.setResponseCode("500");
367             resp.setResponseMessage("internal error");
368             resp.setAckFinalIndicator("Y");
369             retval.setOutput(resp);
370             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
371         }
372
373         // Add operational tree data to SvcLogicContext
374         try {
375             preloadData = getOperationalPreloadData(preloadId, preloadType);
376             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
377         } catch (JsonProcessingException e) {
378             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
379             resp.setResponseCode("500");
380             resp.setResponseMessage("internal error");
381             resp.setAckFinalIndicator("Y");
382             retval.setOutput(resp);
383             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
384         }
385
386         // Call DG
387         try {
388             // Any of these can throw a nullpointer exception
389             // execute should only throw a SvcLogicException
390             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
391             Properties respProps = ctxOut.toProperties();
392
393             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
394             resp.setResponseCode(respProps.getProperty("error-code", "200"));
395             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
396
397             if ("200".equals(resp.getResponseCode())) {
398                 // If DG returns success, update database
399                 String ctxJson = ctxOut.toJsonString("preload-data");
400                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
401                         GenericResourceApiPreloaddataPreloadData.class);
402                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
403                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
404             }
405
406         } catch (NullPointerException npe) {
407             resp.setAckFinalIndicator("true");
408             resp.setResponseCode("500");
409             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
410         } catch (SvcLogicException e) {
411             resp.setAckFinalIndicator("true");
412             resp.setResponseCode("500");
413             resp.setResponseMessage(e.getMessage());
414         } catch (JsonMappingException e) {
415             resp.setAckFinalIndicator("true");
416             resp.setResponseCode("500");
417             resp.setResponseMessage(e.getMessage());
418         } catch (JsonProcessingException e) {
419             resp.setAckFinalIndicator("true");
420             resp.setResponseCode("500");
421             resp.setResponseMessage(e.getMessage());
422         }
423
424         retval.setOutput(resp);
425         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
426     }
427
428     private boolean hasInvalidPreloadNetwork(
429             GenericResourceApiPreloadnetworktopologyoperationInputBodyparam preloadData) {
430         return ((preloadData == null) || (preloadData.getInput() == null)
431                 || (preloadData.getInput().getPreloadNetworkTopologyInformation() == null));
432     }
433
434     private boolean hasInvalidPreloadNetwork(
435             GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam preloadData) {
436         return ((preloadData == null) || (preloadData.getInput() == null)
437                 || (preloadData.getInput().getPreloadVfModuleTopologyInformation() == null));
438     }
439
440     private boolean hasInvalidServiceId(GenericResourceApiServiceOperationInformation input) {
441
442         return input == null || input.getServiceInformation() == null
443                 || input.getServiceInformation().getServiceInstanceId() == null
444                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
445     }
446
447     private boolean hasInvalidServiceId(GenericResourceApiNetworkOperationInformation input) {
448
449         return input == null || input.getServiceInformation() == null
450                 || input.getServiceInformation().getServiceInstanceId() == null
451                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
452     }
453
454     private boolean hasInvalidServiceId(GenericResourceApiVnfOperationInformation input) {
455
456         return input == null || input.getServiceInformation() == null
457                 || input.getServiceInformation().getServiceInstanceId() == null
458                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
459     }
460
461     private boolean hasInvalidServiceId(GenericResourceApiVfModuleOperationInformation input) {
462
463         return input == null || input.getServiceInformation() == null
464                 || input.getServiceInformation().getServiceInstanceId() == null
465                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
466     }
467
468     private boolean hasInvalidServiceId(GenericResourceApiPortMirrorTopologyOperationInformation input) {
469
470         return input == null || input.getServiceInformation() == null
471                 || input.getServiceInformation().getServiceInstanceId() == null
472                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
473     }
474
475     private boolean hasInvalidServiceId(GenericResourceApiVnfgetresourcerequestInput input) {
476
477         return input == null || input.getServiceInformation() == null
478                 || input.getServiceInformation().getServiceInstanceId() == null
479                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
480     }
481
482     private boolean hasInvalidVnfId(GenericResourceApiVfModuleOperationInformation input) {
483
484         return input == null || input.getVnfInformation() == null
485                 || input.getVnfInformation().getVnfId() == null
486                 || input.getVnfInformation().getVnfId().length() == 0;
487     }
488
489     private boolean hasInvalidConfigurationId(GenericResourceApiPortMirrorTopologyOperationInformation input) {
490         return input.getConfigurationInformation() == null
491                 || input.getConfigurationInformation().getConfigurationId() == null
492                 || input.getConfigurationInformation().getConfigurationId().length() == 0;
493     }
494
495     private boolean hasInvalidPolicyUpdateInput(GenericResourceApiPolicyupdatenotifyoperationInput input) {
496         return (input.getPolicyName() == null) || (input.getUpdateType() == null) || (input.getVersionId() == null);
497     }
498
499     private GenericResourceApiPreloaddataPreloadData getConfigPreloadData(String preloadId, String preloadType)
500             throws JsonProcessingException {
501
502         List<ConfigPreloadData> configPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId,
503                 preloadType);
504
505         if (configPreloadData.isEmpty()) {
506             return (null);
507         } else {
508             return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
509                     GenericResourceApiPreloaddataPreloadData.class));
510         }
511     }
512
513     private GenericResourceApiPreloaddataPreloadData getOperationalPreloadData(String preloadId, String preloadType)
514             throws JsonProcessingException {
515
516         List<OperationalPreloadData> configPreloadData = operationalPreloadDataRepository
517                 .findByPreloadIdAndPreloadType(preloadId, preloadType);
518
519         if (configPreloadData.isEmpty()) {
520             return (null);
521         } else {
522             return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
523                     GenericResourceApiPreloaddataPreloadData.class));
524         }
525     }
526
527     private void saveConfigPreloadData(String preloadId, String preloadType,
528             GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
529
530         configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
531         configPreloadDataRepository
532                 .save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
533
534     }
535
536     private void saveOperationalPreloadData(String preloadId, String preloadType,
537             GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
538
539         operationalPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
540         operationalPreloadDataRepository
541                 .save(new OperationalPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
542
543     }
544
545
546     @Override
547     public ResponseEntity<GenericResourceApiNetworkTopologyOperation> operationsGENERICRESOURCEAPInetworkTopologyOperationPost(
548             @Valid GenericResourceApiNetworkOperationInformationBodyparam input) throws RestException {
549         final String svcOperation = "network-topology-operation";
550         GenericResourceApiNetworkTopologyOperation retval = new GenericResourceApiNetworkTopologyOperation();
551         GenericResourceApiNetworktopologyoperationOutput resp = new GenericResourceApiNetworktopologyoperationOutput();
552
553         log.info(CALLED_STR, svcOperation);
554         // Verify input contains service instance id
555         if (hasInvalidServiceId(input.getInput())) {
556             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
557
558             resp.setResponseCode("404");
559             resp.setResponseMessage("null or empty service-instance-id");
560             resp.setAckFinalIndicator("Y");
561
562             retval.setOutput(resp);
563
564             return new ResponseEntity<>(retval, HttpStatus.OK);
565         }
566
567         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
568
569         SvcLogicContext ctxIn = new SvcLogicContext();
570
571         // Add input to SvcLogicContext
572         try {
573             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
574         } catch (JsonProcessingException e) {
575             log.error("exiting {} due to parse error on input data", svcOperation);
576             resp.setResponseCode("500");
577             resp.setResponseMessage("internal error");
578             resp.setAckFinalIndicator("Y");
579             retval.setOutput(resp);
580             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
581         }
582
583         // Add config tree data to SvcLogicContext
584         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
585         ConfigServices configService = null;
586         String svcData = null;
587         if (configServices != null && !configServices.isEmpty()) {
588             configService = configServices.get(0);
589             try {
590                 svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
591             } catch (JsonProcessingException e) {
592                 log.error("exiting {} due to parse error on service data", svcOperation);
593                 resp.setResponseCode("500");
594                 resp.setResponseMessage("internal error");
595                 resp.setAckFinalIndicator("Y");
596                 retval.setOutput(resp);
597                 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
598             }
599         }
600         if (svcData != null) {
601             ctxIn.mergeJson("service-data", svcData);
602         } else {
603             log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
604
605             resp.setResponseCode("404");
606             resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
607             resp.setAckFinalIndicator("Y");
608
609             retval.setOutput(resp);
610
611             return new ResponseEntity<>(retval, HttpStatus.OK);
612         }
613
614         // Add operational tree data to SvcLogicContext
615         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
616         OperationalServices operService = null;
617         boolean saveOperationalData = false;
618
619         if (operServices != null && !operServices.isEmpty()) {
620             operService = operServices.get(0);
621             ctxIn.mergeJson("operational-data", operService.getSvcData());
622         } else {
623             operService = new OperationalServices(svcInstanceId, null, null);
624         }
625
626         // Update service status info in config entry from input
627         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
628         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
629         configService.setServiceStatusRpcName(svcOperation);
630
631         String ctxSvcDataJson = svcData;
632
633         // Call DG
634         try {
635             // Any of these can throw a nullpointer exception
636             // execute should only throw a SvcLogicException
637             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
638             Properties respProps = ctxOut.toProperties();
639
640             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
641             resp.setResponseCode(respProps.getProperty("error-code", "200"));
642             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
643
644
645
646             configService
647                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
648
649             if ("200".equals(resp.getResponseCode())) {
650
651                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
652                 serviceReference.setInstanceId(svcInstanceId);
653                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
654                 resp.setServiceResponseInformation(serviceReference);
655     
656                 GenericResourceApiInstanceReference networkReference = new GenericResourceApiInstanceReference();
657                 networkReference.setInstanceId(respProps.getProperty("networkId"));
658                 networkReference.setObjectPath(respProps.getProperty(NETWORK_OBJECT_PATH_PARAM));
659                 resp.setNetworkResponseInformation(networkReference);
660
661                 // If DG returns success, update svcData in config and operational trees
662                 // and remember to save operational data.
663                 ctxSvcDataJson = ctxOut.toJsonString("service-data");
664                 operService.setSvcData(ctxSvcDataJson);
665                 saveOperationalData = true;
666             }
667
668         } catch (NullPointerException npe) {
669             resp.setAckFinalIndicator("true");
670             resp.setResponseCode("500");
671             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
672         } catch (SvcLogicException e) {
673             resp.setAckFinalIndicator("true");
674             resp.setResponseCode("500");
675             resp.setResponseMessage(e.getMessage());
676         }
677
678         // Update status in config services entry
679
680         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
681         configService.setServiceStatusResponseCode(resp.getResponseCode());
682         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
683         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
684
685
686         // Save service data
687         try {
688             serviceDataHelper.saveService(configService, ctxSvcDataJson);
689         } catch (JsonProcessingException e) {
690             log.error("exiting {} due to  error saving service data", svcOperation);
691             resp.setResponseCode("500");
692             resp.setResponseMessage("internal error");
693             resp.setAckFinalIndicator("Y");
694             retval.setOutput(resp);
695             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
696         }
697
698         // If necessary, sync status to operation service entry and save
699         if (saveOperationalData) {
700             operService.setServiceStatus(configService.getServiceStatus());
701             operationalServicesRepository.save(operService);
702         }
703         retval.setOutput(resp);
704         
705         return (new ResponseEntity<>(retval, HttpStatus.OK));
706     }
707
708     @Override
709     public ResponseEntity<GenericResourceApiServiceTopologyOperation> operationsGENERICRESOURCEAPIserviceTopologyOperationPost(
710             @Valid GenericResourceApiServiceOperationInformationBodyparam input) throws RestException {
711         final String svcOperation = "service-topology-operation";
712         GenericResourceApiServiceTopologyOperation retval = new GenericResourceApiServiceTopologyOperation();
713         GenericResourceApiServicetopologyoperationOutput resp = new GenericResourceApiServicetopologyoperationOutput();
714
715         log.info(CALLED_STR, svcOperation);
716
717         // Verify input contains service instance id
718         if (hasInvalidServiceId(input.getInput())) {
719             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
720
721             resp.setResponseCode("404");
722             resp.setResponseMessage("null or empty service-instance-id");
723             resp.setAckFinalIndicator("Y");
724
725             retval.setOutput(resp);
726
727             return new ResponseEntity<>(retval, HttpStatus.OK);
728         }
729
730         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
731
732         SvcLogicContext ctxIn = new SvcLogicContext();
733
734         // Add input to SvcLogicContext
735         try {
736             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
737         } catch (JsonProcessingException e) {
738             log.error("exiting {} due to parse error on input data", svcOperation);
739             resp.setResponseCode("500");
740             resp.setResponseMessage("internal error");
741             resp.setAckFinalIndicator("Y");
742             retval.setOutput(resp);
743             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
744         }
745
746         // Add config tree data to SvcLogicContext
747         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
748         ConfigServices configService = null;
749         String svcData = null;
750         if (configServices != null && !configServices.isEmpty()) {
751             configService = configServices.get(0);
752             try {
753                 svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
754                 if (svcData != null) {
755                     ctxIn.mergeJson("service-data", svcData);
756                 }
757             } catch (JsonProcessingException e) {
758                 log.error("exiting {} due to parse error on service data", svcOperation, e);
759                 resp.setResponseCode("500");
760                 resp.setResponseMessage("internal error");
761                 resp.setAckFinalIndicator("Y");
762                 retval.setOutput(resp);
763                 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
764             }
765         } else {
766             configService = new ConfigServices(svcInstanceId);
767         }
768
769
770         // Add operational tree data to SvcLogicContext
771         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
772         OperationalServices operService = null;
773         boolean saveOperationalData = false;
774
775         if (operServices != null && !operServices.isEmpty()) {
776             operService = operServices.get(0);
777             ctxIn.mergeJson("operational-data", operService.getSvcData());
778         } else {
779             operService = new OperationalServices(svcInstanceId, null, null);
780         }
781
782         // Update service status info in config entry from input
783         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
784         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
785         configService.setServiceStatusRpcName(svcOperation);
786
787         String ctxSvcDataJson = svcData;
788         // Call DG
789         try {
790             // Any of these can throw a nullpointer exception
791             // execute should only throw a SvcLogicException
792             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
793             Properties respProps = ctxOut.toProperties();
794
795             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
796             resp.setResponseCode(respProps.getProperty("error-code", "200"));
797             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
798
799             configService
800                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
801
802             if ("200".equals(resp.getResponseCode())) {                 
803                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
804                 serviceReference.setInstanceId(svcInstanceId);
805                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
806                 resp.setServiceResponseInformation(serviceReference);
807
808                 // If DG returns success, update svcData in config and operational trees
809                 // and remember to save operational data.
810                 ctxSvcDataJson= ctxOut.toJsonString("service-data");
811
812                 operService.setSvcData(ctxSvcDataJson);
813                 saveOperationalData = true;
814             }
815
816         } catch (NullPointerException npe) {
817             resp.setAckFinalIndicator("true");
818             resp.setResponseCode("500");
819             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
820         } catch (SvcLogicException e) {
821             resp.setAckFinalIndicator("true");
822             resp.setResponseCode("500");
823             resp.setResponseMessage(e.getMessage());
824         }
825
826         // Update status in config services entry
827
828         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
829         configService.setServiceStatusResponseCode(resp.getResponseCode());
830         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
831         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
832
833         // Save service data
834         try {
835             serviceDataHelper.saveService(configService, ctxSvcDataJson);
836         } catch (JsonProcessingException e) {
837             log.error("exiting {} due to  error saving service data", svcOperation);
838             resp.setResponseCode("500");
839             resp.setResponseMessage("internal error");
840             resp.setAckFinalIndicator("Y");
841             retval.setOutput(resp);
842             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
843         }
844
845         // If necessary, sync status to operation service entry and save
846         if (saveOperationalData) {
847             operService.setServiceStatus(configService.getServiceStatus());
848             operationalServicesRepository.save(operService);
849         }
850         retval.setOutput(resp);
851         return (new ResponseEntity<>(retval, HttpStatus.OK));
852
853     }
854
855     @Override
856     public ResponseEntity<GenericResourceApiVnfTopologyOperation> operationsGENERICRESOURCEAPIvnfTopologyOperationPost(
857             @Valid GenericResourceApiVnfOperationInformationBodyparam input)
858             throws RestException {
859         final String svcOperation = "vnf-topology-operation";
860         GenericResourceApiVnfTopologyOperation retval = new GenericResourceApiVnfTopologyOperation();
861         GenericResourceApiVnftopologyoperationOutput resp = new GenericResourceApiVnftopologyoperationOutput();
862
863         log.info(CALLED_STR, svcOperation);
864         // Verify input contains service instance id
865         if(hasInvalidServiceId(input.getInput())) {
866             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
867
868             resp.setResponseCode("404");
869             resp.setResponseMessage("null or empty service-instance-id");
870             resp.setAckFinalIndicator("Y");
871
872             retval.setOutput(resp);
873
874             return new ResponseEntity<>(retval, HttpStatus.OK);
875         }
876
877         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
878         String vnfId = null;
879
880         if((input.getInput() != null) && (input.getInput().getVnfInformation() != null)) {
881             vnfId = input.getInput().getVnfInformation().getVnfId();
882         }
883
884         SvcLogicContext ctxIn = new SvcLogicContext();
885
886         // Add input to SvcLogicContext
887         try {
888             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
889         }
890         catch(JsonProcessingException e) {
891             log.error("exiting {} due to parse error on input data", svcOperation);
892             resp.setResponseCode("500");
893             resp.setResponseMessage("internal error");
894             resp.setAckFinalIndicator("Y");
895             retval.setOutput(resp);
896             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
897         }
898
899        // Add config tree data to SvcLogicContext
900        List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
901        ConfigServices configService = null;
902        String svcData = null;
903        if (configServices != null && !configServices.isEmpty()) {
904            configService = configServices.get(0);
905            try {
906                svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
907            } catch (JsonProcessingException e) {
908                log.error("exiting {} due to parse error on service data", svcOperation);
909                resp.setResponseCode("500");
910                resp.setResponseMessage("internal error");
911                resp.setAckFinalIndicator("Y");
912                retval.setOutput(resp);
913                return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
914            }
915        }
916        if (svcData != null) {
917            ctxIn.mergeJson("service-data", svcData);
918        } else {
919            log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
920
921            resp.setResponseCode("404");
922            resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
923            resp.setAckFinalIndicator("Y");
924
925            retval.setOutput(resp);
926
927            return new ResponseEntity<>(retval, HttpStatus.OK);
928        }
929
930         // Add operational tree data to SvcLogicContext
931         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
932         OperationalServices operService = null;
933         boolean saveOperationalData = false;
934
935         if(operServices != null && !operServices.isEmpty()) {
936             operService = operServices.get(0);
937             ctxIn.mergeJson("operational-data", operService.getSvcData());
938         }
939         else {
940             operService = new OperationalServices(svcInstanceId, null, null);
941         }
942
943         // Update service status info in config entry from input
944         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
945         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
946         configService.setServiceStatusRpcName(svcOperation);
947
948         String ctxSvcDataJson = svcData;
949
950         // Call DG
951         try {
952             // Any of these can throw a nullpointer exception
953             // execute should only throw a SvcLogicException
954             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
955             Properties respProps = ctxOut.toProperties();
956
957             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
958             resp.setResponseCode(respProps.getProperty("error-code", "200"));
959             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
960
961             configService
962                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
963
964             if("200".equals(resp.getResponseCode())) {
965
966                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
967                 serviceReference.setInstanceId(svcInstanceId);
968                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
969                 resp.setServiceResponseInformation(serviceReference);
970
971                 if(vnfId == null) {
972                     vnfId = respProps.getProperty("vnfId");
973                 }
974                 GenericResourceApiInstanceReference vnfReference = new GenericResourceApiInstanceReference();
975                 vnfReference.setInstanceId(vnfId);
976                 vnfReference.setObjectPath(respProps.getProperty(VNF_OBJECT_PATH_PARAM));
977                 resp.setVnfResponseInformation(vnfReference);
978
979                 // If DG returns success, update svcData in config and operational trees
980                 // and remember to save operational data.
981                 ctxSvcDataJson = ctxOut.toJsonString("service-data");
982                 operService.setSvcData(ctxSvcDataJson);
983                 saveOperationalData = true;
984             }
985
986         }
987         catch(NullPointerException npe) {
988             resp.setAckFinalIndicator("Y");
989             resp.setResponseCode("500");
990             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
991         }
992         catch(SvcLogicException e) {
993             resp.setAckFinalIndicator("Y");
994             resp.setResponseCode("500");
995             resp.setResponseMessage(e.getMessage());
996         }
997
998         // Update status in config services entry
999
1000         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
1001         configService.setServiceStatusResponseCode(resp.getResponseCode());
1002         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
1003         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
1004
1005         // Save service data
1006         try {
1007             serviceDataHelper.saveService(configService, ctxSvcDataJson);
1008         } catch (JsonProcessingException e) {
1009             log.error("exiting {} due to  error saving service data", svcOperation);
1010             resp.setResponseCode("500");
1011             resp.setResponseMessage("internal error");
1012             resp.setAckFinalIndicator("Y");
1013             retval.setOutput(resp);
1014             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1015         }
1016
1017
1018         // If necessary, sync status to operation service entry and save
1019         if(saveOperationalData) {
1020             operService.setServiceStatus(configService.getServiceStatus());
1021             operationalServicesRepository.save(operService);
1022         }
1023
1024         if(resp.getAckFinalIndicator().equals("N")) {
1025             // Spawn background thread to invoke the Async DG
1026             Runnable backgroundThread = () -> {
1027                 log.info(BACKGROUND_THREAD_STARTED_MESSAGE);
1028                 processAsyncVnfTopologyOperation(svcOperation, input);
1029             };
1030             new Thread(backgroundThread).start();
1031         }
1032
1033         log.info("Returned {} for {} [{}] {}.", resp.getResponseCode(), svcOperation, vnfId, resp.getResponseMessage());
1034         retval.setOutput(resp);
1035         return (new ResponseEntity<>(retval, HttpStatus.OK));
1036     }
1037
1038     public void processAsyncVnfTopologyOperation(String parentOperation, @Valid GenericResourceApiVnfOperationInformationBodyparam input) {
1039         final String svcOperation = "vnf-topology-operation-async";
1040         GenericResourceApiVnftopologyoperationOutput resp = new GenericResourceApiVnftopologyoperationOutput();
1041
1042         log.info(CALLED_STR, svcOperation);
1043         // Verify input contains service instance id
1044         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1045         String vnfId = input.getInput().getVnfInformation().getVnfId();
1046
1047         SvcLogicContext ctxIn = new SvcLogicContext();
1048
1049         // Add input to SvcLogicContext
1050         try {
1051             ctxIn.mergeJson(parentOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1052         } catch (JsonProcessingException e) {
1053             log.error("exiting {} due to parse error on input data", svcOperation);
1054             return;
1055         }
1056
1057         // Add config tree data to SvcLogicContext
1058         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1059         ConfigServices configService = null;
1060         String svcData = null;
1061         if (configServices != null && !configServices.isEmpty()) {
1062             configService = configServices.get(0);
1063             try {
1064                 svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
1065             } catch (JsonProcessingException e) {
1066                 log.error("exiting {} due to parse error on service data", svcOperation);
1067                 return;
1068             }
1069         }
1070         if (svcData != null) {
1071             ctxIn.mergeJson("service-data", svcData);
1072         } else {
1073             log.error("exiting {} because there is no service data with id [{}] in SDN", svcOperation, svcInstanceId);
1074             return;
1075         }
1076
1077
1078         // Add operational tree data to SvcLogicContext
1079         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
1080         OperationalServices operService = null;
1081
1082         if(operServices != null && !operServices.isEmpty()) {
1083             operService = operServices.get(0);
1084             ctxIn.mergeJson("operational-data", operService.getSvcData());
1085         }
1086         else {
1087             operService = new OperationalServices(svcInstanceId, null, null);
1088         }
1089
1090         // Update service status info in config entry from input
1091         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
1092         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
1093         configService.setServiceStatusRpcName(svcOperation);
1094
1095         String ctxSvcDataJson = svcData;
1096
1097         // Call DG
1098         try {
1099             // Any of these can throw a nullpointer exception
1100             // execute should only throw a SvcLogicException
1101             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1102             Properties respProps = ctxOut.toProperties();
1103
1104             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
1105             resp.setResponseCode(respProps.getProperty("error-code", "200"));
1106             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
1107
1108             configService
1109                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
1110
1111             if("200".equals(resp.getResponseCode())) {
1112                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
1113                 serviceReference.setInstanceId(svcInstanceId);
1114                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
1115                 resp.setServiceResponseInformation(serviceReference);
1116
1117                 if(vnfId == null) {
1118                     vnfId = respProps.getProperty("vnfId");
1119                 }
1120                 GenericResourceApiInstanceReference vnfReference = new GenericResourceApiInstanceReference();
1121                 vnfReference.setInstanceId(vnfId);
1122                 vnfReference.setObjectPath(respProps.getProperty(VNF_OBJECT_PATH_PARAM));
1123                 resp.setVnfResponseInformation(vnfReference);
1124
1125                 // If DG returns success, update svcData in config and operational trees
1126                 // and remember to save operational data.
1127                 ctxSvcDataJson  = ctxOut.toJsonString("service-data");
1128                 operService.setSvcData(ctxSvcDataJson);
1129
1130                 // Update status in config services entry
1131
1132                 configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
1133                 configService.setServiceStatusResponseCode(resp.getResponseCode());
1134                 configService.setServiceStatusResponseMessage(resp.getResponseMessage());
1135                 configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
1136
1137                 // Save service data
1138                 try {
1139                     serviceDataHelper.saveService(configService, ctxSvcDataJson);
1140                 } catch (JsonProcessingException e) {
1141                     log.error("exiting {} due to  error saving service data", svcOperation);
1142                     return;
1143                 }
1144
1145                 // Update operational tree
1146                 operService.setServiceStatus(configService.getServiceStatus());
1147                 operationalServicesRepository.save(operService);
1148                 log.info("Returned SUCCESS for {} [{}]", svcOperation, vnfId);
1149             }
1150         }
1151         catch(Exception e) {
1152             log.error("Caught Exception updating configuration status in SDN for {} [{}] \n", svcOperation, vnfId);
1153         }
1154     }
1155
1156     @Override
1157     public ResponseEntity<GenericResourceApiVfModuleTopologyOperation> operationsGENERICRESOURCEAPIvfModuleTopologyOperationPost(
1158             @Valid GenericResourceApiVfModuleOperationInformationBodyparam input)
1159             throws RestException {
1160         final String svcOperation = "vf-module-topology-operation";
1161         GenericResourceApiVfModuleTopologyOperation retval = new GenericResourceApiVfModuleTopologyOperation();
1162         GenericResourceApiVfmoduletopologyoperationOutput resp = new GenericResourceApiVfmoduletopologyoperationOutput();
1163
1164         log.info(CALLED_STR, svcOperation);
1165
1166         log.info("MYSQL_DATABASE = {}", System.getenv("MYSQL_DATABASE"));
1167         // Verify input contains service instance id
1168         if (hasInvalidServiceId(input.getInput())) {
1169             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
1170
1171             resp.setResponseCode("404");
1172             resp.setResponseMessage("null or empty service-instance-id");
1173             resp.setAckFinalIndicator("Y");
1174             retval.setOutput(resp);
1175             return new ResponseEntity<>(retval, HttpStatus.OK);
1176         }
1177
1178         // Verify input contains vnf-id
1179         if (hasInvalidVnfId(input.getInput())) {
1180             log.debug("exiting {} because of null or empty vnf-id", svcOperation);
1181
1182             resp.setResponseCode("404");
1183             resp.setResponseMessage("null or empty vnf-id");
1184             resp.setAckFinalIndicator("Y");
1185             retval.setOutput(resp);
1186             return new ResponseEntity<>(retval, HttpStatus.OK);
1187         }
1188
1189         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1190         String vnfId = input.getInput().getVnfInformation().getVnfId();
1191         String vfModuleId = input.getInput().getVfModuleInformation().getVfModuleId();
1192
1193         SvcLogicContext ctxIn = new SvcLogicContext();
1194
1195         // Add input to SvcLogicContext
1196         try {
1197             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1198         } catch (JsonProcessingException e) {
1199             log.error("exiting {} due to parse error on input data", svcOperation);
1200             resp.setResponseCode("500");
1201             resp.setResponseMessage("internal error");
1202             resp.setAckFinalIndicator("Y");
1203             retval.setOutput(resp);
1204             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1205         }
1206
1207         // Add config tree data to SvcLogicContext
1208         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1209         ConfigServices configService = null;
1210         String svcData = null;
1211         if (configServices != null && !configServices.isEmpty()) {
1212             configService = configServices.get(0);
1213             try {
1214                 svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
1215             } catch (JsonProcessingException e) {
1216                 log.error("exiting {} due to parse error on service data", svcOperation);
1217                 resp.setResponseCode("500");
1218                 resp.setResponseMessage("internal error");
1219                 resp.setAckFinalIndicator("Y");
1220                 retval.setOutput(resp);
1221                 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1222             }
1223         }
1224         if (svcData != null) {
1225             ctxIn.mergeJson("service-data", svcData);
1226         } else {
1227             log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
1228  
1229             resp.setResponseCode("404");
1230             resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
1231             resp.setAckFinalIndicator("Y");
1232  
1233             retval.setOutput(resp);
1234  
1235             return new ResponseEntity<>(retval, HttpStatus.OK);
1236         }
1237
1238         // Add operational tree data to SvcLogicContext
1239         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
1240         OperationalServices operService = null;
1241
1242         if (operServices != null && !operServices.isEmpty()) {
1243             operService = operServices.get(0);
1244             log.info("Read ({}) data for [{}] operational-data: {}",
1245                     "OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS", svcInstanceId, operService.getSvcData().toString());
1246             //ctxIn.mergeJson("operational-data", operService.getSvcData());
1247         } else {
1248             log.info("No operational-data found in OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS for [{}]", svcInstanceId);
1249             operService = new OperationalServices(svcInstanceId, null, null);
1250         }
1251
1252         // Update service status info in config entry from input
1253         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
1254         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
1255         configService.setServiceStatusRpcName(svcOperation);
1256
1257         String ackFinal = "Y";
1258         String skipMdsalUpdate;
1259         
1260
1261         // Call DG
1262         try {
1263             // Any of these can throw a nullpointer exception
1264             // execute should only throw a SvcLogicException
1265             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1266             Properties respProps = ctxOut.toProperties();
1267
1268             ackFinal = respProps.getProperty("ack-final", "Y");
1269             skipMdsalUpdate = respProps.getProperty("skip-mdsal-update", "N");
1270             log.info("ackFinal [{}], skipMdsalUpdate [{}]", ackFinal, skipMdsalUpdate);
1271
1272             resp.setAckFinalIndicator(ackFinal);
1273             resp.setResponseCode(respProps.getProperty("error-code", "200"));
1274             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
1275
1276             // Update status in config services entry
1277             configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
1278             configService.setServiceStatusResponseCode(resp.getResponseCode());
1279             configService.setServiceStatusResponseMessage(resp.getResponseMessage());
1280             configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
1281             configService
1282                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
1283
1284             if ("200".equals(resp.getResponseCode())) {
1285
1286                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
1287                 serviceReference.setInstanceId(svcInstanceId);
1288                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
1289                 resp.setServiceResponseInformation(serviceReference);
1290
1291                 GenericResourceApiInstanceReference vnfReference = new GenericResourceApiInstanceReference();
1292                 vnfReference.setInstanceId(vnfId);
1293                 vnfReference.setObjectPath(respProps.getProperty(VNF_OBJECT_PATH_PARAM));
1294                 resp.setVnfResponseInformation(vnfReference);
1295
1296                 GenericResourceApiInstanceReference vfModuleReference = new GenericResourceApiInstanceReference();
1297                 vnfReference.setInstanceId(vfModuleId);
1298                 vnfReference.setObjectPath(respProps.getProperty(VF_MODULE_OBJECT_PATH_PARAM));
1299                 resp.setVnfResponseInformation(vfModuleReference);
1300
1301                 if (skipMdsalUpdate.equals("N")) {
1302                     // If DG returns success,
1303                     // ONLY update svcData in config and operational trees
1304                     // and remember to save operational data when skip-mdsal-update is Y in ctx.
1305                     String ctxJson = ctxOut.toJsonString("service-data");
1306                     log.info("Saving service-data in SDN because skipMdsalUpdate is {}", skipMdsalUpdate);
1307                     log.info("Service data : {}", ctxJson);
1308                     serviceDataHelper.saveService(configService, ctxJson);
1309
1310                     log.info("Copying service-data to operational-data");
1311                     operService.setSvcData(ctxJson);
1312                     operService.setServiceStatus(configService.getServiceStatus());
1313                     operationalServicesRepository.save(operService);
1314                 }
1315             }
1316         } catch (NullPointerException npe) {
1317             resp.setAckFinalIndicator("Y");
1318             resp.setResponseCode("500");
1319             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
1320         } catch (SvcLogicException e) {
1321             resp.setAckFinalIndicator("Y");
1322         } catch (JsonProcessingException e) {
1323             resp.setAckFinalIndicator("Y");
1324             resp.setResponseCode("500");
1325             resp.setResponseMessage("Internal error");
1326             log.error("exiting {} due to error updating service data", svcOperation, e);
1327         }
1328
1329         if (ackFinal.equals("N")) {
1330             // Spawn background thread to invoke the Async DG
1331             Runnable backgroundThread = new Runnable() {
1332                 public void run() {
1333                     log.info(BACKGROUND_THREAD_STARTED_MESSAGE);
1334                     processAsyncVfModuleTopologyOperation(svcOperation, input);
1335                 }
1336             };
1337             new Thread(backgroundThread).start();
1338         }
1339         retval.setOutput(resp);
1340         return (new ResponseEntity<>(retval, HttpStatus.OK));
1341     }
1342
1343     public void processAsyncVfModuleTopologyOperation( String parentOperation,
1344             @Valid GenericResourceApiVfModuleOperationInformationBodyparam input) {
1345         log.info(BACKGROUND_THREAD_INFO, input.getInput().getVfModuleInformation().getVfModuleId());
1346         final String svcOperation = "vf-module-topology-operation-async";
1347
1348         log.info(CALLED_STR, svcOperation);
1349         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1350         SvcLogicContext ctxIn = new SvcLogicContext();
1351
1352         // Add input to SvcLogicContext
1353         try {
1354             ctxIn.mergeJson(parentOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1355         } catch (JsonProcessingException e) {
1356             log.error("exiting {} due to parse error on input data", svcOperation);
1357             return;
1358         }
1359
1360         // Add config tree data to SvcLogicContext
1361         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1362         ConfigServices configService = null;
1363         String svcData = null;
1364         if (configServices != null && !configServices.isEmpty()) {
1365             configService = configServices.get(0);
1366             try {
1367                 svcData = serviceDataHelper.getServiceDataAsString(svcInstanceId);
1368             } catch (JsonProcessingException e) {
1369                 log.error("exiting {} due to parse error on service data", svcOperation);
1370                 return;
1371             }
1372         }
1373         if (svcData != null) {
1374             ctxIn.mergeJson("service-data", svcData);
1375         } else {
1376             log.error("exiting {} because there is no service data with id [{}] in SDN", svcOperation, svcInstanceId);
1377             return;
1378         }
1379
1380
1381         // Add operational tree data to SvcLogicContext
1382         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
1383         OperationalServices operService = null;
1384
1385         if (operServices != null && !operServices.isEmpty()) {
1386             operService = operServices.get(0);
1387             log.info("Read ({}) data for [{}] operational-data: {}",
1388                     "OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS", svcInstanceId, operService.getSvcData().toString());
1389             //ctxIn.mergeJson("operational-data", operService.getSvcData());
1390         } else {
1391             log.info("No operational-data found in OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS for [{}]", svcInstanceId);
1392             operService = new OperationalServices(svcInstanceId, null, null);
1393         }
1394
1395         // Update service status info in config entry from input
1396         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
1397         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
1398         configService.setServiceStatusRpcName(svcOperation);
1399
1400         String respStatus = "SUCCESS";
1401         String errorMessage = null;
1402
1403         String ctxSvcDataJson = svcData;
1404
1405         log.info ("Adding INPUT data for {} [{}] input: {}", svcOperation, svcInstanceId, input.getInput().toString());
1406
1407         // Call DG
1408         try {
1409             // Any of these can throw a nullpointer exception
1410             // execute should only throw a SvcLogicException
1411             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1412             Properties respProps = ctxOut.toProperties();
1413
1414             String ackFinal = respProps.getProperty("ack-final-indicator", "Y");
1415             String errorCode = respProps.getProperty("error-code", "200");
1416             errorMessage = respProps.getProperty("error-message", "SUCCESS");
1417
1418             if (! "200".equals(errorCode)) {
1419                 respStatus = "FAILED";
1420             }
1421
1422             // Update status in config services entry
1423             configService.setServiceStatusFinalIndicator(ackFinal);
1424             configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
1425             configService.setServiceStatusResponseCode(errorCode);
1426             configService.setServiceStatusResponseMessage(errorMessage);
1427             configService
1428                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
1429
1430             ctxSvcDataJson = ctxOut.toJsonString("service-data");
1431             configServicesRepository.save(configService);
1432
1433             // Save service data
1434             try {
1435                 serviceDataHelper.saveService(configService, ctxSvcDataJson);
1436             } catch (JsonProcessingException e) {
1437                 log.error("exiting {} due to  error saving service data", svcOperation);
1438                 return;
1439             }
1440
1441             operService.setSvcData(ctxSvcDataJson);
1442             operService.setServiceStatus(configService.getServiceStatus());
1443             operationalServicesRepository.save(operService);
1444
1445         } catch (Exception ex) {
1446             log.error("Caught Exception updating service status in SDN for {} [{}] \n", svcOperation, svcInstanceId);
1447         }
1448         log.info("Returned {} for {} [{}] {}.", respStatus, svcOperation, svcInstanceId, errorMessage);
1449     }
1450
1451     @Override
1452     public ResponseEntity<GenericResourceApiPortMirrorTopologyOperation> operationsGENERICRESOURCEAPIportMirrorTopologyOperationPost(
1453             @Valid GenericResourceApiPortMirrorTopologyOperationInformationBodyparam input)
1454             throws RestException {
1455         final String svcOperation = "port-mirror-topology-operation";
1456         GenericResourceApiPortMirrorTopologyOperation retval = new GenericResourceApiPortMirrorTopologyOperation();
1457         GenericResourceApiPortmirrortopologyoperationOutput resp = new GenericResourceApiPortmirrortopologyoperationOutput();
1458
1459         log.info(CALLED_STR, svcOperation);
1460
1461         // Verify input contains configuration-id
1462         if (hasInvalidConfigurationId(input.getInput())) {
1463             log.debug("exiting {} because of null or empty configuration-id", svcOperation);
1464
1465             resp.setResponseCode("404");
1466             resp.setResponseMessage("null or empty configuration-id");
1467             resp.setAckFinalIndicator("Y");
1468             retval.setOutput(resp);
1469             return new ResponseEntity<>(retval, HttpStatus.OK);
1470         }
1471
1472         // Verify input contains service instance id
1473         if (hasInvalidServiceId(input.getInput())) {
1474             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
1475
1476             resp.setResponseCode("404");
1477             resp.setResponseMessage("null or empty service-instance-id");
1478             resp.setAckFinalIndicator("Y");
1479             retval.setOutput(resp);
1480             return new ResponseEntity<>(retval, HttpStatus.OK);
1481         }
1482
1483         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1484         String configurationId = input.getInput().getConfigurationInformation().getConfigurationId();
1485
1486         SvcLogicContext ctxIn = new SvcLogicContext();
1487
1488         // Add input to SvcLogicContext
1489         try {
1490             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1491         } catch (JsonProcessingException e) {
1492             log.error("exiting {} due to parse error on input data", svcOperation);
1493             resp.setResponseCode("500");
1494             resp.setResponseMessage("internal error");
1495             resp.setAckFinalIndicator("Y");
1496             retval.setOutput(resp);
1497             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1498         }
1499
1500         // Add service instance config data to SvcLogicContext
1501         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1502         ConfigServices configService = null;
1503         if (configServices != null && !configServices.isEmpty()) {
1504             configService = configServices.get(0);
1505             log.info("Read ({}) data for [{}] service-data: {}", "CONFIG_GRA_SERVICES", svcInstanceId, configService.getSvcData());
1506             ctxIn.mergeJson("service-data", configService.getSvcData());
1507
1508         } else {
1509             log.debug("exiting {} because there is no service data with id [{}] in SDN", svcOperation, svcInstanceId);
1510             resp.setResponseCode("404");
1511             resp.setResponseMessage("invalid input: there is no service-instance with id [{}] in SDNC");
1512             resp.setAckFinalIndicator("Y");
1513
1514             retval.setOutput(resp);
1515             return new ResponseEntity<>(retval, HttpStatus.OK);
1516         }
1517
1518         // Add configuration config data to SvcLogicContext
1519         List<ConfigPortMirrorConfigurations> configPortMirrorConfigurations =
1520                 configPortMirrorConfigurationsRepository.findByConfigurationId(configurationId);
1521         ConfigPortMirrorConfigurations configPortMirrorConfiguration;
1522         if (configPortMirrorConfigurations != null && !configPortMirrorConfigurations.isEmpty()) {
1523             configPortMirrorConfiguration = configPortMirrorConfigurations.get(0);
1524             log.info("Read ({}) data for [{}] configuration-data: {}",
1525                     "CONFIG_GRA_PORT_MIRROR_CONFIGURATIONS", configurationId, configPortMirrorConfiguration.getPmcData());
1526             ctxIn.mergeJson("configuration-data", configPortMirrorConfiguration.getPmcData());
1527
1528         } else {
1529             log.info("No configuration-data found ({}) for [{}]", "CONFIG_GRA_PORT_MIRROR_CONFIGURATIONS", configurationId);
1530             configPortMirrorConfiguration = new ConfigPortMirrorConfigurations(configurationId, null);
1531         }
1532
1533         /*
1534         // Add configuration operational data to SvcLogicContext
1535         List<OperationalPortMirrorConfigurations> operPortMirrorConfigurations =
1536                 operationalPortMirrorConfigurationsRepository.findByConfigurationId(configurationId);
1537         OperationalPortMirrorConfigurations operPortMirrorConfiguration;
1538
1539         if (operPortMirrorConfigurations != null && !operPortMirrorConfigurations.isEmpty()) {
1540             operPortMirrorConfiguration = operPortMirrorConfigurations.get(0);
1541             log.info("Read ({}) data for [{}] operational-data: {}",
1542                     "OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS", configurationId, operPortMirrorConfiguration.getPmcData());
1543             ctxIn.mergeJson("operational-data", operPortMirrorConfiguration.getPmcData());
1544
1545         } else {
1546             log.info("No operational-data found ({}) for [{}]", "OPERATIONAL_GRA_PORT_MIRROR_CONFIGURATIONS", configurationId);
1547             operPortMirrorConfiguration = new OperationalPortMirrorConfigurations(configurationId, null, null);
1548         }
1549
1550         */
1551
1552         String ackFinal = "Y";
1553         String errorCode = "200";
1554         String errorMessage = "SUCCESS";
1555         String respStatus = "SUCCESS";
1556
1557         log.info(ADDING_INPUT_DATA_LOG, svcOperation, svcInstanceId, input.getInput().toString());
1558         //log.info(ADDING_INPUT_DATA_LOG, svcOperation, svcInstanceId, input.toString());
1559
1560         // Update service status info in config entry from input
1561         configPortMirrorConfiguration.setPortMirrorConfigurationStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
1562         configPortMirrorConfiguration.setPortMirrorConfigurationStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
1563         configPortMirrorConfiguration.setPortMirrorConfigurationStatusRpcName(svcOperation);
1564
1565         // Call DG
1566         try {
1567             // Any of these can throw a nullpointer exception
1568             // execute should only throw a SvcLogicException
1569             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1570             Properties respProps = ctxOut.toProperties();
1571
1572             ackFinal = respProps.getProperty("ack-final", "Y");
1573             errorCode = respProps.getProperty("error-code", "200");
1574             errorMessage = respProps.getProperty("error-message", "SUCCESS");
1575             log.info("ackFinal [{}], error-code [{}], error-message [{}]", ackFinal, errorCode, errorMessage);
1576
1577             resp.setAckFinalIndicator(ackFinal);
1578             resp.setResponseCode(errorCode);
1579             resp.setResponseMessage(errorMessage);
1580
1581             // Update status in config services entry
1582             configPortMirrorConfiguration
1583                     .setPortMirrorConfigurationStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
1584             configPortMirrorConfiguration.setPortMirrorConfigurationStatusFinalIndicator(resp.getAckFinalIndicator());
1585             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseCode(resp.getResponseCode());
1586             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseMessage(resp.getResponseMessage());
1587             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseTimestamp(Iso8601Util.now());
1588
1589             GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
1590             serviceReference.setInstanceId(svcInstanceId);
1591             serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
1592             resp.setServiceResponseInformation(serviceReference);
1593
1594             GenericResourceApiInstanceReference pmcReference = new GenericResourceApiInstanceReference();
1595             serviceReference.setInstanceId(configurationId);
1596             serviceReference.setObjectPath(respProps.getProperty(PORT_MIRROR_OBJECT_PATH_PARAM));
1597             resp.setServiceResponseInformation(pmcReference);
1598
1599             retval.setOutput(resp);
1600
1601             // ONLY update pmcData in config and operational trees
1602             //String ctxJson = ctxOut.toJsonString("configuration-data");
1603             //configPortMirrorConfiguration.setPmcData(ctxJson);
1604             //operPortMirrorConfiguration.setPmcData(ctxJson);
1605             //configPortMirrorConfigurationsRepository.save(configPortMirrorConfiguration);
1606
1607             // If necessary, sync status to operation service entry and save
1608             //operPortMirrorConfiguration.setPortMirrorConfigurationStatus(configPortMirrorConfiguration.getPortMirrorConfigurationStatus());
1609             //operationalPortMirrorConfigurationsRepository.save(operPortMirrorConfiguration);
1610
1611             if (! "200".equals(errorCode)) {
1612                 respStatus = "FAILED";
1613             }
1614
1615         } catch (NullPointerException npe) {
1616             resp.setAckFinalIndicator("Y");
1617             resp.setResponseCode("500");
1618             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
1619         } catch (SvcLogicException e) {
1620             resp.setAckFinalIndicator("Y");
1621         }
1622
1623         if (ackFinal.equals("N")) {
1624             // Spawn background thread to invoke the Async DG
1625             Runnable backgroundThread = new Runnable() {
1626                 public void run() {
1627                     log.info(BACKGROUND_THREAD_STARTED_MESSAGE);
1628                     processAsyncPortMirrorTopologyOperation(svcOperation, input);
1629                  }
1630             };
1631             new Thread(backgroundThread).start();
1632         }
1633         log.info("Returned {} for {} [{}] {}.", respStatus, svcOperation, configurationId, errorMessage);
1634         return (new ResponseEntity<>(retval, HttpStatus.OK));
1635     }
1636
1637     public void processAsyncPortMirrorTopologyOperation( String parentOperation,
1638              @Valid GenericResourceApiPortMirrorTopologyOperationInformationBodyparam input) {
1639         log.info(BACKGROUND_THREAD_INFO, input.getInput().getConfigurationInformation().getConfigurationId());
1640         final String svcOperation = "port-mirror-topology-operation-async";
1641
1642         log.info(CALLED_STR, svcOperation);
1643         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1644         String configurationId = input.getInput().getConfigurationInformation().getConfigurationId();
1645         SvcLogicContext ctxIn = new SvcLogicContext();
1646
1647         String errorMessage;
1648
1649         // Add input to SvcLogicContext
1650         try {
1651             ctxIn.mergeJson(parentOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1652         } catch (JsonProcessingException e) {
1653             log.error("exiting {} due to parse error on input data", svcOperation);
1654             return;
1655         }
1656
1657         // Add service instance config data to SvcLogicContext
1658         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1659         ConfigServices configService = null;
1660         if (configServices != null && !configServices.isEmpty()) {
1661             configService = configServices.get(0);
1662             ctxIn.mergeJson("service-data", configService.getSvcData());
1663         } else {
1664             log.error("exiting {} because there is no service data with id [{}] in SDN", svcOperation, svcInstanceId);
1665             return;
1666         }
1667
1668         // Add config tree data to SvcLogicContext
1669         List<ConfigPortMirrorConfigurations> configPortMirrorConfigurations = configPortMirrorConfigurationsRepository.findByConfigurationId(configurationId);
1670         ConfigPortMirrorConfigurations configPortMirrorConfiguration;
1671         if (configPortMirrorConfigurations != null && !configPortMirrorConfigurations.isEmpty()) {
1672             configPortMirrorConfiguration = configPortMirrorConfigurations.get(0);
1673             ctxIn.mergeJson("configuration-data", configPortMirrorConfiguration.getPmcData());
1674         } else {
1675             configPortMirrorConfiguration = new ConfigPortMirrorConfigurations(configurationId, null);
1676         }
1677
1678         /*
1679         // Add operational tree data to SvcLogicContext
1680         List<OperationalPortMirrorConfigurations> operPortMirrorConfigurations = operationalPortMirrorConfigurationsRepository.findByConfigurationId(configurationId);
1681         OperationalPortMirrorConfigurations operPortMirrorConfiguration = null;
1682
1683         if (operPortMirrorConfigurations != null && !operPortMirrorConfigurations.isEmpty()) {
1684             operPortMirrorConfiguration = operPortMirrorConfigurations.get(0);
1685             ctxIn.mergeJson("operational-data", operPortMirrorConfiguration.getPmcData());
1686         } else {
1687             operPortMirrorConfiguration = new OperationalPortMirrorConfigurations(configurationId, null, null);
1688         }
1689
1690         */
1691
1692         // Update service status info in config entry from input
1693         configPortMirrorConfiguration.setPortMirrorConfigurationStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
1694         configPortMirrorConfiguration.setPortMirrorConfigurationStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
1695         configPortMirrorConfiguration.setPortMirrorConfigurationStatusRpcName(parentOperation);
1696
1697         log.info("Adding INPUT data for {} [{}] input: {}", svcOperation, svcInstanceId, input.toString());
1698
1699         // Call DG
1700         try {
1701             // Any of these can throw a nullpointer exception
1702             // execute should only throw a SvcLogicException
1703             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1704             Properties respProps = ctxOut.toProperties();
1705
1706             String ackFinalIndicator = respProps.getProperty("ack-final-indicator", "Y");
1707             String errorCode = respProps.getProperty("error-code", "200");
1708             errorMessage = respProps.getProperty("error-message", "SUCCESS");
1709
1710             // Update status in config services entry
1711             configPortMirrorConfiguration.setPortMirrorConfigurationStatusFinalIndicator(ackFinalIndicator);
1712             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseTimestamp(Iso8601Util.now());
1713             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseCode(errorCode);
1714             configPortMirrorConfiguration.setPortMirrorConfigurationStatusResponseMessage(errorMessage);
1715             configPortMirrorConfiguration
1716                     .setPortMirrorConfigurationStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
1717
1718             // ONLY update status
1719             //String ctxJson = ctxOut.toJsonString("configuration-data");
1720             //configPortMirrorConfiguration.setPmcData(ctxJson);
1721             //configPortMirrorConfiguration.setPmcData(ctxJson);
1722
1723             // Update config tree
1724             configPortMirrorConfigurationsRepository.save(configPortMirrorConfiguration);
1725
1726             //update operational tree
1727             //operPortMirrorConfiguration.setPortMirrorConfigurationStatus(configPortMirrorConfiguration.getPortMirrorConfigurationStatus());
1728             //operationalPortMirrorConfigurationsRepository.save(operPortMirrorConfiguration);
1729
1730         } catch (Exception e) {
1731             log.error("Caught Exception updating configuration status in SDN for {} [{}] \n", svcOperation, configurationId);
1732         }
1733         log.info("Returned SUCCESS for {} [{}]", svcOperation, configurationId);
1734     }
1735
1736     @Override
1737     public ResponseEntity<GenericResourceApiVnfGetResourceRequest> operationsGENERICRESOURCEAPIvnfGetResourceRequestPost(
1738             @Valid GenericResourceApiVnfgetresourcerequestInputBodyparam input)
1739             throws RestException {
1740         final String svcOperation = "vnf-get-resource-request";
1741         GenericResourceApiVnfGetResourceRequest retval = new GenericResourceApiVnfGetResourceRequest();
1742
1743         log.info(CALLED_STR, svcOperation);
1744         // Verify input contains service instance id
1745         if (hasInvalidServiceId(input.getInput())) {
1746             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
1747             //return new ResponseEntity<>(retval, HttpStatus.OK);
1748         }
1749
1750         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
1751         SvcLogicContext ctxIn = new SvcLogicContext();
1752
1753         // Add input to SvcLogicContext
1754         try {
1755             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1756         } catch (JsonProcessingException e) {
1757             log.error("exiting {} due to parse error on input data", svcOperation);
1758             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1759         }
1760
1761         // Add config tree data to SvcLogicContext
1762         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
1763         ConfigServices configService = null;
1764         if (configServices != null && !configServices.isEmpty()) {
1765             configService = configServices.get(0);
1766             try {
1767                 ctxIn.mergeJson("service-data", serviceDataHelper.getServiceDataAsString(svcInstanceId));
1768             } catch (JsonProcessingException e) {
1769                 log.error("exiting {} due to parse error on service data", svcOperation);
1770                 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1771             }
1772         } else {
1773             log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
1774             return new ResponseEntity<>(retval, HttpStatus.OK);
1775         }
1776
1777         // Call DG
1778         try {
1779             // Any of these can throw a nullpointer exception
1780             // execute should only throw a SvcLogicException
1781             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1782
1783
1784             String ctxJson = ctxOut.toJsonString("vnf-get-resource-request-output");
1785             GenericResourceApiVnfgetresourcerequestOutput vnfgetresourcerequestOutput =
1786                     objectMapper.readValue(ctxJson, GenericResourceApiVnfgetresourcerequestOutput.class);
1787
1788             retval.setOutput(vnfgetresourcerequestOutput);
1789
1790         } catch (Exception e) {
1791             return (new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR));
1792         }
1793         return (new ResponseEntity<>(retval, HttpStatus.OK));
1794     }
1795
1796     @Override
1797     public ResponseEntity<GenericResourceApiPolicyUpdateNotifyOperation> operationsGENERICRESOURCEAPIpolicyUpdateNotifyOperationPost(
1798             @Valid GenericResourceApiPolicyupdatenotifyoperationInputBodyparam input)
1799             throws RestException {
1800         final String svcOperation = "policy-update-notify-operation";
1801         GenericResourceApiPolicyUpdateNotifyOperation retval = new GenericResourceApiPolicyUpdateNotifyOperation();
1802         GenericResourceApiPolicyupdatenotifyoperationOutput resp = new GenericResourceApiPolicyupdatenotifyoperationOutput();
1803
1804         log.info(CALLED_STR, svcOperation);
1805         // Verify required input elements
1806         if (hasInvalidPolicyUpdateInput(input.getInput())) {
1807             log.debug("exiting {} because policy name, update type, or version id was not provided", svcOperation);
1808             resp.setErrorCode("404");
1809             resp.setErrorMsg("policy-name, update-type, and/or version-id is null or empty");
1810             retval.setOutput(resp);
1811             return new ResponseEntity<>(retval, HttpStatus.OK);
1812         }
1813
1814         SvcLogicContext ctxIn = new SvcLogicContext();
1815
1816         // Add input to SvcLogicContext
1817         try {
1818             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
1819         } catch (JsonProcessingException e) {
1820             log.error("exiting {} due to parse error on input data", svcOperation);
1821             resp.setErrorCode("500");
1822             resp.setErrorMsg("internal error");
1823             retval.setOutput(resp);
1824             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
1825         }
1826
1827         // Call DG
1828         try {
1829             // Any of these can throw a nullpointer exception
1830             // execute should only throw a SvcLogicException
1831             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
1832             Properties respProps = ctxOut.toProperties();
1833             resp.setErrorCode(respProps.getProperty("error-code", "200"));
1834             resp.setErrorMsg(respProps.getProperty("error-message", "SUCCESS"));
1835
1836             /* For debugging Only
1837             respProps.forEach((k,v) -> {
1838                 log.debug("prop: {} -> {}",k,v);
1839             });
1840              */
1841
1842         } catch (NullPointerException npe) {
1843             resp.setErrorCode("500");
1844             resp.setErrorMsg("Check that you populated module, rpc and or mode correctly.");
1845         } catch (SvcLogicException e) {
1846             resp.setErrorCode("500");
1847             resp.setErrorMsg(e.getMessage());
1848         }
1849
1850         retval.setOutput(resp);
1851         return (new ResponseEntity<>(retval, HttpStatus.OK));
1852     }
1853
1854 }