ac9a8b183d72d8002fc63dc5cd63fbd087013bbc
[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 com.fasterxml.jackson.annotation.JsonInclude;
24 import com.fasterxml.jackson.core.JsonProcessingException;
25 import com.fasterxml.jackson.databind.JsonMappingException;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.google.gson.JsonParser;
28
29 import org.onap.ccsdk.apps.services.RestException;
30 import org.onap.ccsdk.apps.services.SvcLogicFactory;
31 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
33 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase;
34 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
35 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
36 import org.onap.sdnc.apps.ms.gra.data.ConfigServices;
37 import org.onap.sdnc.apps.ms.gra.data.ConfigServicesRepository;
38 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadData;
39 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadDataRepository;
40 import org.onap.sdnc.apps.ms.gra.data.OperationalServices;
41 import org.onap.sdnc.apps.ms.gra.data.OperationalServicesRepository;
42 import org.onap.sdnc.apps.ms.gra.swagger.OperationsApi;
43 import org.onap.sdnc.apps.ms.gra.swagger.model.*;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.boot.autoconfigure.domain.EntityScan;
46 import org.springframework.context.annotation.ComponentScan;
47 import org.springframework.context.annotation.Import;
48 import org.springframework.http.HttpStatus;
49 import org.springframework.http.ResponseEntity;
50 import org.springframework.stereotype.Controller;
51
52 import javax.servlet.http.HttpServletRequest;
53 import javax.validation.Valid;
54
55 import java.text.DateFormat;
56 import java.text.SimpleDateFormat;
57 import java.util.*;
58 import java.util.concurrent.atomic.AtomicBoolean;
59
60 @Controller
61 @ComponentScan(basePackages = { "org.onap.sdnc.apps.ms.gra.*", "org.onap.ccsdk.apps.services" })
62 @EntityScan("org.onap.sdnc.apps.ms.gra.*")
63 @Import(value = SvcLogicFactory.class)
64 public class OperationsApiController implements OperationsApi {
65
66     private static final String CALLED_STR = "{} called.";
67     private static final String MODULE_NAME = "GENERIC-RESOURCE-API";
68     private static final String SERVICE_OBJECT_PATH_PARAM = "service-object-path";
69     private static final String NETWORK_OBJECT_PATH_PARAM = "network-object-path";
70     private static final String VNF_OBJECT_PATH_PARAM = "vnf-object-path";
71     private static final String PNF_OBJECT_PATH_PARAM = "pnf-object-path";
72     private static final String VF_MODULE_OBJECT_PATH_PARAM = "vf-module-object-path";
73     private static final String VF_MODULE_ID_PARAM = "vf-module-id";
74
75
76     private final ObjectMapper objectMapper;
77
78     private final HttpServletRequest request;
79
80     @Autowired
81     protected SvcLogicServiceBase svc;
82
83     @Autowired
84     private ConfigPreloadDataRepository configPreloadDataRepository;
85
86     @Autowired
87     private OperationalPreloadDataRepository operationalPreloadDataRepository;
88
89     @Autowired
90     private ConfigServicesRepository configServicesRepository;
91
92     @Autowired
93     private OperationalServicesRepository operationalServicesRepository;
94
95     private static class Iso8601Util {
96
97         private static TimeZone timeZone = TimeZone.getTimeZone("UTC");
98         private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
99
100         private Iso8601Util() {
101         }
102
103         static {
104             dateFormat.setTimeZone(timeZone);
105         }
106
107         private static String now() {
108             return dateFormat.format(new Date());
109         }
110     }
111
112     @org.springframework.beans.factory.annotation.Autowired
113     public OperationsApiController(ObjectMapper objectMapper, HttpServletRequest request) {
114         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
115         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
116         this.objectMapper = objectMapper;
117         this.request = request;
118     }
119
120     @Override
121     public Optional<ObjectMapper> getObjectMapper() {
122         return Optional.ofNullable(objectMapper);
123     }
124
125     @Override
126     public Optional<HttpServletRequest> getRequest() {
127         return Optional.ofNullable(request);
128     }
129
130     @Override
131     public ResponseEntity<GenericResourceApiPreloadNetworkTopologyOperation> operationsGENERICRESOURCEAPIpreloadNetworkTopologyOperationPost(
132             @Valid GenericResourceApiPreloadnetworktopologyoperationInputBodyparam graInput) {
133         final String svcOperation = "preload-network-topology-operation";
134         GenericResourceApiPreloadNetworkTopologyOperation retval = new GenericResourceApiPreloadNetworkTopologyOperation();
135         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
136
137         log.info(CALLED_STR, svcOperation);
138         if (hasInvalidPreloadNetwork(graInput)) {
139             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
140
141             resp.setResponseCode("403");
142             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
143             resp.setAckFinalIndicator("Y");
144
145             retval.setOutput(resp);
146
147             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
148         }
149
150         String preloadId = graInput.getInput().getPreloadNetworkTopologyInformation()
151                 .getNetworkTopologyIdentifierStructure().getNetworkId();
152         String preloadType = "network";
153
154         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
155
156         SvcLogicContext ctxIn = new SvcLogicContext();
157
158         GenericResourceApiPreloaddataPreloadData preloadData = null;
159
160         // Add input to SvcLogicContext
161         try {
162             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
163         } catch (JsonProcessingException e) {
164             log.error("exiting {} due to parse error on input preload data", svcOperation);
165             resp.setResponseCode("500");
166             resp.setResponseMessage("internal error");
167             resp.setAckFinalIndicator("Y");
168             retval.setOutput(resp);
169             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
170         }
171
172         // Add config tree data to SvcLogicContext
173         try {
174             preloadData = getConfigPreloadData(preloadId, preloadType);
175             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
176         } catch (JsonProcessingException e) {
177             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
178             resp.setResponseCode("500");
179             resp.setResponseMessage("internal error");
180             resp.setAckFinalIndicator("Y");
181             retval.setOutput(resp);
182             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
183         }
184
185         // Add operational tree data to SvcLogicContext
186         try {
187             preloadData = getOperationalPreloadData(preloadId, preloadType);
188             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
189         } catch (JsonProcessingException e) {
190             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
191             resp.setResponseCode("500");
192             resp.setResponseMessage("internal error");
193             resp.setAckFinalIndicator("Y");
194             retval.setOutput(resp);
195             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
196         }
197
198         // Call DG
199         try {
200             // Any of these can throw a nullpointer exception
201             // execute should only throw a SvcLogicException
202             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
203             Properties respProps = ctxOut.toProperties();
204
205             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
206             resp.setResponseCode(respProps.getProperty("error-code", "200"));
207             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
208
209             if ("200".equals(resp.getResponseCode())) {
210                 // If DG returns success, update database
211                 String ctxJson = ctxOut.toJsonString("preload-data");
212                 log.info("DG preload-data is {}", ctxJson);
213                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
214                         GenericResourceApiPreloaddataPreloadData.class);
215                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
216                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
217             }
218
219         } catch (NullPointerException npe) {
220             log.error("Caught NPE", npe);
221             resp.setAckFinalIndicator("true");
222             resp.setResponseCode("500");
223             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
224         } catch (SvcLogicException e) {
225             log.error("Caught SvcLogicException", e);
226             resp.setAckFinalIndicator("true");
227             resp.setResponseCode("500");
228             resp.setResponseMessage(e.getMessage());
229         } catch (JsonMappingException e) {
230             log.error("Caught JsonMappingException", e);
231             resp.setAckFinalIndicator("true");
232             resp.setResponseCode("500");
233             resp.setResponseMessage(e.getMessage());
234         } catch (JsonProcessingException e) {
235             log.error("Caught JsonProcessingException", e);
236             resp.setAckFinalIndicator("true");
237             resp.setResponseCode("500");
238             resp.setResponseMessage(e.getMessage());
239         }
240
241         retval.setOutput(resp);
242         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
243     }
244
245     @Override
246     public ResponseEntity<GenericResourceApiPreloadVfModuleTopologyOperation> operationsGENERICRESOURCEAPIpreloadVfModuleTopologyOperationPost(
247             @Valid GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam graInput) {
248         final String svcOperation = "preload-vf-module-topology-operation";
249         GenericResourceApiPreloadVfModuleTopologyOperation retval = new GenericResourceApiPreloadVfModuleTopologyOperation();
250         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
251
252         log.info(CALLED_STR, svcOperation);
253         if (hasInvalidPreloadNetwork(graInput)) {
254             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
255
256             resp.setResponseCode("403");
257             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
258             resp.setAckFinalIndicator("Y");
259
260             retval.setOutput(resp);
261
262             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
263         }
264
265         String preloadId = graInput.getInput().getPreloadVfModuleTopologyInformation().getVfModuleTopology()
266                 .getVfModuleTopologyIdentifier().getVfModuleName();
267         String preloadType = "vf-module";
268
269         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
270
271         SvcLogicContext ctxIn = new SvcLogicContext();
272
273         GenericResourceApiPreloaddataPreloadData preloadData = null;
274
275         // Add input to SvcLogicContext
276         try {
277             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
278         } catch (JsonProcessingException e) {
279             log.error("exiting {} due to parse error on input preload data", svcOperation);
280             resp.setResponseCode("500");
281             resp.setResponseMessage("internal error");
282             resp.setAckFinalIndicator("Y");
283             retval.setOutput(resp);
284             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
285         }
286
287         // Add config tree data to SvcLogicContext
288         try {
289             preloadData = getConfigPreloadData(preloadId, preloadType);
290             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
291         } catch (JsonProcessingException e) {
292             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
293             resp.setResponseCode("500");
294             resp.setResponseMessage("internal error");
295             resp.setAckFinalIndicator("Y");
296             retval.setOutput(resp);
297             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
298         }
299
300         // Add operational tree data to SvcLogicContext
301         try {
302             preloadData = getOperationalPreloadData(preloadId, preloadType);
303             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
304         } catch (JsonProcessingException e) {
305             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
306             resp.setResponseCode("500");
307             resp.setResponseMessage("internal error");
308             resp.setAckFinalIndicator("Y");
309             retval.setOutput(resp);
310             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
311         }
312
313         // Call DG
314         try {
315             // Any of these can throw a nullpointer exception
316             // execute should only throw a SvcLogicException
317             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
318             Properties respProps = ctxOut.toProperties();
319
320             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
321             resp.setResponseCode(respProps.getProperty("error-code", "200"));
322             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
323
324             if ("200".equals(resp.getResponseCode())) {
325                 // If DG returns success, update database
326                 String ctxJson = ctxOut.toJsonString("preload-data");
327                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
328                         GenericResourceApiPreloaddataPreloadData.class);
329                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
330                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
331             }
332
333         } catch (NullPointerException npe) {
334             resp.setAckFinalIndicator("true");
335             resp.setResponseCode("500");
336             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
337         } catch (SvcLogicException e) {
338             resp.setAckFinalIndicator("true");
339             resp.setResponseCode("500");
340             resp.setResponseMessage(e.getMessage());
341         } catch (JsonMappingException e) {
342             resp.setAckFinalIndicator("true");
343             resp.setResponseCode("500");
344             resp.setResponseMessage(e.getMessage());
345         } catch (JsonProcessingException e) {
346             resp.setAckFinalIndicator("true");
347             resp.setResponseCode("500");
348             resp.setResponseMessage(e.getMessage());
349         }
350
351         retval.setOutput(resp);
352         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
353     }
354
355     private boolean hasInvalidPreloadNetwork(
356             GenericResourceApiPreloadnetworktopologyoperationInputBodyparam preloadData) {
357         return ((preloadData == null) || (preloadData.getInput() == null)
358                 || (preloadData.getInput().getPreloadNetworkTopologyInformation() == null));
359     }
360
361     private boolean hasInvalidPreloadNetwork(
362             GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam preloadData) {
363         return ((preloadData == null) || (preloadData.getInput() == null)
364                 || (preloadData.getInput().getPreloadVfModuleTopologyInformation() == null));
365     }
366
367     private boolean hasInvalidServiceId(GenericResourceApiServiceOperationInformation input) {
368
369         return input == null || input.getServiceInformation() == null
370                 || input.getServiceInformation().getServiceInstanceId() == null
371                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
372     }
373
374     private boolean hasInvalidServiceId(GenericResourceApiNetworkOperationInformation input) {
375
376         return input == null || input.getServiceInformation() == null
377                 || input.getServiceInformation().getServiceInstanceId() == null
378                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
379     }
380
381     private boolean hasInvalidServiceId(GenericResourceApiVnfOperationInformation input) {
382
383         return input == null || input.getServiceInformation() == null
384                 || input.getServiceInformation().getServiceInstanceId() == null
385                 || input.getServiceInformation().getServiceInstanceId().length() == 0;
386     }
387
388     private GenericResourceApiPreloaddataPreloadData getConfigPreloadData(String preloadId, String preloadType)
389             throws JsonProcessingException {
390
391         List<ConfigPreloadData> configPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId,
392                 preloadType);
393
394         if (configPreloadData.isEmpty()) {
395             return (null);
396         } else {
397             return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
398                     GenericResourceApiPreloaddataPreloadData.class));
399         }
400     }
401
402     private GenericResourceApiPreloaddataPreloadData getOperationalPreloadData(String preloadId, String preloadType)
403             throws JsonProcessingException {
404
405         List<OperationalPreloadData> configPreloadData = operationalPreloadDataRepository
406                 .findByPreloadIdAndPreloadType(preloadId, preloadType);
407
408         if (configPreloadData.isEmpty()) {
409             return (null);
410         } else {
411             return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
412                     GenericResourceApiPreloaddataPreloadData.class));
413         }
414     }
415
416     private void saveConfigPreloadData(String preloadId, String preloadType,
417             GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
418
419         configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
420         configPreloadDataRepository
421                 .save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
422
423     }
424
425     private void saveOperationalPreloadData(String preloadId, String preloadType,
426             GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
427
428         operationalPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
429         operationalPreloadDataRepository
430                 .save(new OperationalPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
431
432     }
433
434     private GenericResourceApiServicedataServiceData getConfigServiceData(String svcInstanceId)
435             throws JsonProcessingException {
436
437         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
438
439         if (configServices.isEmpty()) {
440             return (null);
441         } else {
442             return (objectMapper.readValue(configServices.get(0).getSvcData(),
443                     GenericResourceApiServicedataServiceData.class));
444         }
445     }
446
447     @Override
448     public ResponseEntity<GenericResourceApiNetworkTopologyOperation> operationsGENERICRESOURCEAPInetworkTopologyOperationPost(
449             @Valid GenericResourceApiNetworkOperationInformationBodyparam input) throws RestException {
450         final String svcOperation = "network-topology-operation";
451         GenericResourceApiNetworkTopologyOperation retval = new GenericResourceApiNetworkTopologyOperation();
452         GenericResourceApiNetworktopologyoperationOutput resp = new GenericResourceApiNetworktopologyoperationOutput();
453
454         log.info(CALLED_STR, svcOperation);
455         // Verify input contains service instance id
456         if (hasInvalidServiceId(input.getInput())) {
457             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
458
459             resp.setResponseCode("404");
460             resp.setResponseMessage("null or empty service-instance-id");
461             resp.setAckFinalIndicator("Y");
462
463             retval.setOutput(resp);
464
465             return new ResponseEntity<>(retval, HttpStatus.OK);
466         }
467
468         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
469
470         SvcLogicContext ctxIn = new SvcLogicContext();
471
472         // Add input to SvcLogicContext
473         try {
474             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
475         } catch (JsonProcessingException e) {
476             log.error("exiting {} due to parse error on input data", svcOperation);
477             resp.setResponseCode("500");
478             resp.setResponseMessage("internal error");
479             resp.setAckFinalIndicator("Y");
480             retval.setOutput(resp);
481             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
482         }
483
484         // Add config tree data to SvcLogicContext
485         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
486         ConfigServices configService = null;
487         if (configServices != null && !configServices.isEmpty()) {
488             configService = configServices.get(0);
489             ctxIn.mergeJson("service-data", configService.getSvcData());
490         } else {
491             log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
492
493             resp.setResponseCode("404");
494             resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
495             resp.setAckFinalIndicator("Y");
496
497             retval.setOutput(resp);
498
499             return new ResponseEntity<>(retval, HttpStatus.OK);
500         }
501
502         // Add operational tree data to SvcLogicContext
503         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
504         OperationalServices operService = null;
505         boolean saveOperationalData = false;
506
507         if (operServices != null && !operServices.isEmpty()) {
508             operService = operServices.get(0);
509             ctxIn.mergeJson("operational-data", operService.getSvcData());
510         } else {
511             operService = new OperationalServices(svcInstanceId, null, null);
512         }
513
514         // Update service status info in config entry from input
515         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
516         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
517         configService.setServiceStatusRpcName(svcOperation);
518
519         // Call DG
520         try {
521             // Any of these can throw a nullpointer exception
522             // execute should only throw a SvcLogicException
523             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
524             Properties respProps = ctxOut.toProperties();
525
526             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
527             resp.setResponseCode(respProps.getProperty("error-code", "200"));
528             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
529
530
531
532             configService
533                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
534
535             if ("200".equals(resp.getResponseCode())) {
536
537                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
538                 serviceReference.setInstanceId(svcInstanceId);
539                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
540                 resp.setServiceResponseInformation(serviceReference);
541     
542                 GenericResourceApiInstanceReference networkReference = new GenericResourceApiInstanceReference();
543                 networkReference.setInstanceId(respProps.getProperty("networkId"));
544                 networkReference.setObjectPath(respProps.getProperty(NETWORK_OBJECT_PATH_PARAM));
545                 resp.setNetworkResponseInformation(networkReference);
546
547                 // If DG returns success, update svcData in config and operational trees
548                 // and remember to save operational data.
549                 String ctxJson = ctxOut.toJsonString("service-data");
550                 configService.setSvcData(ctxJson);
551                 operService.setSvcData(ctxJson);
552                 saveOperationalData = true;
553             }
554
555         } catch (NullPointerException npe) {
556             resp.setAckFinalIndicator("true");
557             resp.setResponseCode("500");
558             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
559         } catch (SvcLogicException e) {
560             resp.setAckFinalIndicator("true");
561             resp.setResponseCode("500");
562             resp.setResponseMessage(e.getMessage());
563         }
564
565         // Update status in config services entry
566
567         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
568         configService.setServiceStatusResponseCode(resp.getResponseCode());
569         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
570         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
571
572         // Update config tree
573         configServicesRepository.save(configService);
574
575         // If necessary, sync status to operation service entry and save
576         if (saveOperationalData) {
577             operService.setServiceStatus(configService.getServiceStatus());
578             operationalServicesRepository.save(operService);
579         }
580         retval.setOutput(resp);
581         
582         return (new ResponseEntity<>(retval, HttpStatus.OK));
583     }
584
585     @Override
586     public ResponseEntity<GenericResourceApiServiceTopologyOperation> operationsGENERICRESOURCEAPIserviceTopologyOperationPost(
587             @Valid GenericResourceApiServiceOperationInformationBodyparam input) throws RestException {
588         final String svcOperation = "service-topology-operation";
589         GenericResourceApiServiceTopologyOperation retval = new GenericResourceApiServiceTopologyOperation();
590         GenericResourceApiServicetopologyoperationOutput resp = new GenericResourceApiServicetopologyoperationOutput();
591
592         log.info(CALLED_STR, svcOperation);
593
594         // Verify input contains service instance id
595         if (hasInvalidServiceId(input.getInput())) {
596             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
597
598             resp.setResponseCode("404");
599             resp.setResponseMessage("null or empty service-instance-id");
600             resp.setAckFinalIndicator("Y");
601
602             retval.setOutput(resp);
603
604             return new ResponseEntity<>(retval, HttpStatus.OK);
605         }
606
607         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
608
609         SvcLogicContext ctxIn = new SvcLogicContext();
610
611         // Add input to SvcLogicContext
612         try {
613             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
614         } catch (JsonProcessingException e) {
615             log.error("exiting {} due to parse error on input data", svcOperation);
616             resp.setResponseCode("500");
617             resp.setResponseMessage("internal error");
618             resp.setAckFinalIndicator("Y");
619             retval.setOutput(resp);
620             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
621         }
622
623         // Add config tree data to SvcLogicContext
624         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
625         ConfigServices configService = null;
626         if (configServices != null && !configServices.isEmpty()) {
627             configService = configServices.get(0);
628             if (configService.getSvcData() != null) {
629                 ctxIn.mergeJson("service-data", configService.getSvcData());
630             }
631         } else {
632             configService = new ConfigServices(svcInstanceId, null);
633         }
634
635         // Add operational tree data to SvcLogicContext
636         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
637         OperationalServices operService = null;
638         boolean saveOperationalData = false;
639
640         if (operServices != null && !operServices.isEmpty()) {
641             operService = operServices.get(0);
642             ctxIn.mergeJson("operational-data", operService.getSvcData());
643         } else {
644             operService = new OperationalServices(svcInstanceId, null, null);
645         }
646
647         // Update service status info in config entry from input
648         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
649         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
650         configService.setServiceStatusRpcName(svcOperation);
651
652         // Call DG
653         try {
654             // Any of these can throw a nullpointer exception
655             // execute should only throw a SvcLogicException
656             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
657             Properties respProps = ctxOut.toProperties();
658
659             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
660             resp.setResponseCode(respProps.getProperty("error-code", "200"));
661             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
662
663             configService
664                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
665
666             if ("200".equals(resp.getResponseCode())) {                 
667                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
668                 serviceReference.setInstanceId(svcInstanceId);
669                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
670                 resp.setServiceResponseInformation(serviceReference);
671
672                 // If DG returns success, update svcData in config and operational trees
673                 // and remember to save operational data.
674                 String ctxJson = ctxOut.toJsonString("service-data");
675                 configService.setSvcData(ctxJson);
676                 operService.setSvcData(ctxJson);
677                 saveOperationalData = true;
678             }
679
680         } catch (NullPointerException npe) {
681             resp.setAckFinalIndicator("true");
682             resp.setResponseCode("500");
683             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
684         } catch (SvcLogicException e) {
685             resp.setAckFinalIndicator("true");
686             resp.setResponseCode("500");
687             resp.setResponseMessage(e.getMessage());
688         }
689
690         // Update status in config services entry
691
692         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
693         configService.setServiceStatusResponseCode(resp.getResponseCode());
694         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
695         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
696
697         // Update config tree
698         configServicesRepository.save(configService);
699
700         // If necessary, sync status to operation service entry and save
701         if (saveOperationalData) {
702             operService.setServiceStatus(configService.getServiceStatus());
703             operationalServicesRepository.save(operService);
704         }
705         retval.setOutput(resp);
706         return (new ResponseEntity<>(retval, HttpStatus.OK));
707
708     }
709
710     @Override
711     public ResponseEntity<GenericResourceApiVnfTopologyOperation> operationsGENERICRESOURCEAPIvnfTopologyOperationPost(
712             @Valid GenericResourceApiVnfOperationInformationBodyparam input)
713             throws RestException {
714                 final String svcOperation = "vnf-topology-operation";
715                 GenericResourceApiVnfTopologyOperation retval = new GenericResourceApiVnfTopologyOperation();
716                 GenericResourceApiVnftopologyoperationOutput resp = new GenericResourceApiVnftopologyoperationOutput();
717         
718                 log.info(CALLED_STR, svcOperation);
719                 // Verify input contains service instance id
720                 if (hasInvalidServiceId(input.getInput())) {
721                     log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
722         
723                     resp.setResponseCode("404");
724                     resp.setResponseMessage("null or empty service-instance-id");
725                     resp.setAckFinalIndicator("Y");
726         
727                     retval.setOutput(resp);
728         
729                     return new ResponseEntity<>(retval, HttpStatus.OK);
730                 }
731         
732                 String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
733                 String vnfId = null;
734                 
735                 if ((input.getInput() != null) && (input.getInput().getVnfInformation() != null)) {
736                     vnfId = input.getInput().getVnfInformation().getVnfId();
737                 }
738         
739                 SvcLogicContext ctxIn = new SvcLogicContext();
740         
741                 // Add input to SvcLogicContext
742                 try {
743                     ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
744                 } catch (JsonProcessingException e) {
745                     log.error("exiting {} due to parse error on input data", svcOperation);
746                     resp.setResponseCode("500");
747                     resp.setResponseMessage("internal error");
748                     resp.setAckFinalIndicator("Y");
749                     retval.setOutput(resp);
750                     return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
751                 }
752         
753                 // Add config tree data to SvcLogicContext
754                 List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
755                 ConfigServices configService = null;
756                 if (configServices != null && !configServices.isEmpty()) {
757                     configService = configServices.get(0);
758                     ctxIn.mergeJson("service-data", configService.getSvcData());
759                 } else {
760                     log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
761         
762                     resp.setResponseCode("404");
763                     resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
764                     resp.setAckFinalIndicator("Y");
765         
766                     retval.setOutput(resp);
767         
768                     return new ResponseEntity<>(retval, HttpStatus.OK);
769                 }
770         
771                 // Add operational tree data to SvcLogicContext
772                 List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
773                 OperationalServices operService = null;
774                 boolean saveOperationalData = false;
775         
776                 if (operServices != null && !operServices.isEmpty()) {
777                     operService = operServices.get(0);
778                     ctxIn.mergeJson("operational-data", operService.getSvcData());
779                 } else {
780                     operService = new OperationalServices(svcInstanceId, null, null);
781                 }
782         
783                 // Update service status info in config entry from input
784                 configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
785                 configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
786                 configService.setServiceStatusRpcName(svcOperation);
787
788
789         
790                 // Call DG
791                 try {
792                     // Any of these can throw a nullpointer exception
793                     // execute should only throw a SvcLogicException
794                     SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
795                     Properties respProps = ctxOut.toProperties();
796         
797                     resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
798                     resp.setResponseCode(respProps.getProperty("error-code", "200"));
799                     resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
800
801                     configService
802                             .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
803         
804                     if ("200".equals(resp.getResponseCode())) {
805
806                         GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
807                         serviceReference.setInstanceId(svcInstanceId);
808                         serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
809                         resp.setServiceResponseInformation(serviceReference);
810                         
811                         if (vnfId == null) {
812                             vnfId = respProps.getProperty("vnfId");
813                         }
814                         GenericResourceApiInstanceReference vnfReference = new GenericResourceApiInstanceReference();
815                         vnfReference.setInstanceId(vnfId);
816                         vnfReference.setObjectPath(respProps.getProperty(VNF_OBJECT_PATH_PARAM));
817                         resp.setVnfResponseInformation(vnfReference);
818                         
819                         // If DG returns success, update svcData in config and operational trees
820                         // and remember to save operational data.
821                         String ctxJson = ctxOut.toJsonString("service-data");
822                         configService.setSvcData(ctxJson);
823                         operService.setSvcData(ctxJson);
824                         saveOperationalData = true;
825                     }
826         
827                 } catch (NullPointerException npe) {
828                     resp.setAckFinalIndicator("true");
829                     resp.setResponseCode("500");
830                     resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
831                 } catch (SvcLogicException e) {
832                     resp.setAckFinalIndicator("true");
833                     resp.setResponseCode("500");
834                     resp.setResponseMessage(e.getMessage());
835                 }
836         
837                 // Update status in config services entry
838         
839                 configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
840                 configService.setServiceStatusResponseCode(resp.getResponseCode());
841                 configService.setServiceStatusResponseMessage(resp.getResponseMessage());
842                 configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
843         
844                 // Update config tree
845                 configServicesRepository.save(configService);
846         
847                 // If necessary, sync status to operation service entry and save
848                 if (saveOperationalData) {
849                     operService.setServiceStatus(configService.getServiceStatus());
850                     operationalServicesRepository.save(operService);
851                 }
852                 retval.setOutput(resp);
853                 return (new ResponseEntity<>(retval, HttpStatus.OK));
854     }
855
856     
857 }