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