6a4e5613c14dabc76a4d105c63469dbb993e0dd3
[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         String svcData = null;
488         if (configServices != null && !configServices.isEmpty()) {
489             configService = configServices.get(0);
490             svcData = configService.getSvcData();
491         }
492         if (svcData != null) {
493             ctxIn.mergeJson("service-data", configService.getSvcData());
494         } else {
495             log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
496
497             resp.setResponseCode("404");
498             resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
499             resp.setAckFinalIndicator("Y");
500
501             retval.setOutput(resp);
502
503             return new ResponseEntity<>(retval, HttpStatus.OK);
504         }
505
506         // Add operational tree data to SvcLogicContext
507         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
508         OperationalServices operService = null;
509         boolean saveOperationalData = false;
510
511         if (operServices != null && !operServices.isEmpty()) {
512             operService = operServices.get(0);
513             ctxIn.mergeJson("operational-data", operService.getSvcData());
514         } else {
515             operService = new OperationalServices(svcInstanceId, null, null);
516         }
517
518         // Update service status info in config entry from input
519         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
520         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
521         configService.setServiceStatusRpcName(svcOperation);
522
523         // Call DG
524         try {
525             // Any of these can throw a nullpointer exception
526             // execute should only throw a SvcLogicException
527             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
528             Properties respProps = ctxOut.toProperties();
529
530             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
531             resp.setResponseCode(respProps.getProperty("error-code", "200"));
532             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
533
534
535
536             configService
537                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
538
539             if ("200".equals(resp.getResponseCode())) {
540
541                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
542                 serviceReference.setInstanceId(svcInstanceId);
543                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
544                 resp.setServiceResponseInformation(serviceReference);
545     
546                 GenericResourceApiInstanceReference networkReference = new GenericResourceApiInstanceReference();
547                 networkReference.setInstanceId(respProps.getProperty("networkId"));
548                 networkReference.setObjectPath(respProps.getProperty(NETWORK_OBJECT_PATH_PARAM));
549                 resp.setNetworkResponseInformation(networkReference);
550
551                 // If DG returns success, update svcData in config and operational trees
552                 // and remember to save operational data.
553                 String ctxJson = ctxOut.toJsonString("service-data");
554                 configService.setSvcData(ctxJson);
555                 operService.setSvcData(ctxJson);
556                 saveOperationalData = true;
557             }
558
559         } catch (NullPointerException npe) {
560             resp.setAckFinalIndicator("true");
561             resp.setResponseCode("500");
562             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
563         } catch (SvcLogicException e) {
564             resp.setAckFinalIndicator("true");
565             resp.setResponseCode("500");
566             resp.setResponseMessage(e.getMessage());
567         }
568
569         // Update status in config services entry
570
571         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
572         configService.setServiceStatusResponseCode(resp.getResponseCode());
573         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
574         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
575
576         // Update config tree
577         configServicesRepository.save(configService);
578
579         // If necessary, sync status to operation service entry and save
580         if (saveOperationalData) {
581             operService.setServiceStatus(configService.getServiceStatus());
582             operationalServicesRepository.save(operService);
583         }
584         retval.setOutput(resp);
585         
586         return (new ResponseEntity<>(retval, HttpStatus.OK));
587     }
588
589     @Override
590     public ResponseEntity<GenericResourceApiServiceTopologyOperation> operationsGENERICRESOURCEAPIserviceTopologyOperationPost(
591             @Valid GenericResourceApiServiceOperationInformationBodyparam input) throws RestException {
592         final String svcOperation = "service-topology-operation";
593         GenericResourceApiServiceTopologyOperation retval = new GenericResourceApiServiceTopologyOperation();
594         GenericResourceApiServicetopologyoperationOutput resp = new GenericResourceApiServicetopologyoperationOutput();
595
596         log.info(CALLED_STR, svcOperation);
597
598         // Verify input contains service instance id
599         if (hasInvalidServiceId(input.getInput())) {
600             log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
601
602             resp.setResponseCode("404");
603             resp.setResponseMessage("null or empty service-instance-id");
604             resp.setAckFinalIndicator("Y");
605
606             retval.setOutput(resp);
607
608             return new ResponseEntity<>(retval, HttpStatus.OK);
609         }
610
611         String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
612
613         SvcLogicContext ctxIn = new SvcLogicContext();
614
615         // Add input to SvcLogicContext
616         try {
617             ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
618         } catch (JsonProcessingException e) {
619             log.error("exiting {} due to parse error on input data", svcOperation);
620             resp.setResponseCode("500");
621             resp.setResponseMessage("internal error");
622             resp.setAckFinalIndicator("Y");
623             retval.setOutput(resp);
624             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
625         }
626
627         // Add config tree data to SvcLogicContext
628         List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
629         ConfigServices configService = null;
630         if (configServices != null && !configServices.isEmpty()) {
631             configService = configServices.get(0);
632             if (configService.getSvcData() != null) {
633                 ctxIn.mergeJson("service-data", configService.getSvcData());
634             }
635         } else {
636             configService = new ConfigServices(svcInstanceId, null);
637         }
638
639         // Add operational tree data to SvcLogicContext
640         List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
641         OperationalServices operService = null;
642         boolean saveOperationalData = false;
643
644         if (operServices != null && !operServices.isEmpty()) {
645             operService = operServices.get(0);
646             ctxIn.mergeJson("operational-data", operService.getSvcData());
647         } else {
648             operService = new OperationalServices(svcInstanceId, null, null);
649         }
650
651         // Update service status info in config entry from input
652         configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
653         configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
654         configService.setServiceStatusRpcName(svcOperation);
655
656         // Call DG
657         try {
658             // Any of these can throw a nullpointer exception
659             // execute should only throw a SvcLogicException
660             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
661             Properties respProps = ctxOut.toProperties();
662
663             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
664             resp.setResponseCode(respProps.getProperty("error-code", "200"));
665             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
666
667             configService
668                     .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
669
670             if ("200".equals(resp.getResponseCode())) {                 
671                 GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
672                 serviceReference.setInstanceId(svcInstanceId);
673                 serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
674                 resp.setServiceResponseInformation(serviceReference);
675
676                 // If DG returns success, update svcData in config and operational trees
677                 // and remember to save operational data.
678                 String ctxJson = ctxOut.toJsonString("service-data");
679                 configService.setSvcData(ctxJson);
680                 operService.setSvcData(ctxJson);
681                 saveOperationalData = true;
682             }
683
684         } catch (NullPointerException npe) {
685             resp.setAckFinalIndicator("true");
686             resp.setResponseCode("500");
687             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
688         } catch (SvcLogicException e) {
689             resp.setAckFinalIndicator("true");
690             resp.setResponseCode("500");
691             resp.setResponseMessage(e.getMessage());
692         }
693
694         // Update status in config services entry
695
696         configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
697         configService.setServiceStatusResponseCode(resp.getResponseCode());
698         configService.setServiceStatusResponseMessage(resp.getResponseMessage());
699         configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
700
701         // Update config tree
702         configServicesRepository.save(configService);
703
704         // If necessary, sync status to operation service entry and save
705         if (saveOperationalData) {
706             operService.setServiceStatus(configService.getServiceStatus());
707             operationalServicesRepository.save(operService);
708         }
709         retval.setOutput(resp);
710         return (new ResponseEntity<>(retval, HttpStatus.OK));
711
712     }
713
714     @Override
715     public ResponseEntity<GenericResourceApiVnfTopologyOperation> operationsGENERICRESOURCEAPIvnfTopologyOperationPost(
716             @Valid GenericResourceApiVnfOperationInformationBodyparam input)
717             throws RestException {
718                 final String svcOperation = "vnf-topology-operation";
719                 GenericResourceApiVnfTopologyOperation retval = new GenericResourceApiVnfTopologyOperation();
720                 GenericResourceApiVnftopologyoperationOutput resp = new GenericResourceApiVnftopologyoperationOutput();
721         
722                 log.info(CALLED_STR, svcOperation);
723                 // Verify input contains service instance id
724                 if (hasInvalidServiceId(input.getInput())) {
725                     log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
726         
727                     resp.setResponseCode("404");
728                     resp.setResponseMessage("null or empty service-instance-id");
729                     resp.setAckFinalIndicator("Y");
730         
731                     retval.setOutput(resp);
732         
733                     return new ResponseEntity<>(retval, HttpStatus.OK);
734                 }
735         
736                 String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
737                 String vnfId = null;
738                 
739                 if ((input.getInput() != null) && (input.getInput().getVnfInformation() != null)) {
740                     vnfId = input.getInput().getVnfInformation().getVnfId();
741                 }
742         
743                 SvcLogicContext ctxIn = new SvcLogicContext();
744         
745                 // Add input to SvcLogicContext
746                 try {
747                     ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
748                 } catch (JsonProcessingException e) {
749                     log.error("exiting {} due to parse error on input data", svcOperation);
750                     resp.setResponseCode("500");
751                     resp.setResponseMessage("internal error");
752                     resp.setAckFinalIndicator("Y");
753                     retval.setOutput(resp);
754                     return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
755                 }
756         
757                 // Add config tree data to SvcLogicContext
758                 List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
759                 ConfigServices configService = null;
760                 if (configServices != null && !configServices.isEmpty()) {
761                     configService = configServices.get(0);
762                     ctxIn.mergeJson("service-data", configService.getSvcData());
763                 } else {
764                     log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
765         
766                     resp.setResponseCode("404");
767                     resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
768                     resp.setAckFinalIndicator("Y");
769         
770                     retval.setOutput(resp);
771         
772                     return new ResponseEntity<>(retval, HttpStatus.OK);
773                 }
774         
775                 // Add operational tree data to SvcLogicContext
776                 List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
777                 OperationalServices operService = null;
778                 boolean saveOperationalData = false;
779         
780                 if (operServices != null && !operServices.isEmpty()) {
781                     operService = operServices.get(0);
782                     ctxIn.mergeJson("operational-data", operService.getSvcData());
783                 } else {
784                     operService = new OperationalServices(svcInstanceId, null, null);
785                 }
786         
787                 // Update service status info in config entry from input
788                 configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
789                 configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
790                 configService.setServiceStatusRpcName(svcOperation);
791
792
793         
794                 // Call DG
795                 try {
796                     // Any of these can throw a nullpointer exception
797                     // execute should only throw a SvcLogicException
798                     SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
799                     Properties respProps = ctxOut.toProperties();
800         
801                     resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
802                     resp.setResponseCode(respProps.getProperty("error-code", "200"));
803                     resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
804
805                     configService
806                             .setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
807         
808                     if ("200".equals(resp.getResponseCode())) {
809
810                         GenericResourceApiInstanceReference serviceReference = new GenericResourceApiInstanceReference();
811                         serviceReference.setInstanceId(svcInstanceId);
812                         serviceReference.setObjectPath(respProps.getProperty(SERVICE_OBJECT_PATH_PARAM));
813                         resp.setServiceResponseInformation(serviceReference);
814                         
815                         if (vnfId == null) {
816                             vnfId = respProps.getProperty("vnfId");
817                         }
818                         GenericResourceApiInstanceReference vnfReference = new GenericResourceApiInstanceReference();
819                         vnfReference.setInstanceId(vnfId);
820                         vnfReference.setObjectPath(respProps.getProperty(VNF_OBJECT_PATH_PARAM));
821                         resp.setVnfResponseInformation(vnfReference);
822                         
823                         // If DG returns success, update svcData in config and operational trees
824                         // and remember to save operational data.
825                         String ctxJson = ctxOut.toJsonString("service-data");
826                         configService.setSvcData(ctxJson);
827                         operService.setSvcData(ctxJson);
828                         saveOperationalData = true;
829                     }
830         
831                 } catch (NullPointerException npe) {
832                     resp.setAckFinalIndicator("true");
833                     resp.setResponseCode("500");
834                     resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
835                 } catch (SvcLogicException e) {
836                     resp.setAckFinalIndicator("true");
837                     resp.setResponseCode("500");
838                     resp.setResponseMessage(e.getMessage());
839                 }
840         
841                 // Update status in config services entry
842         
843                 configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
844                 configService.setServiceStatusResponseCode(resp.getResponseCode());
845                 configService.setServiceStatusResponseMessage(resp.getResponseMessage());
846                 configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
847         
848                 // Update config tree
849                 configServicesRepository.save(configService);
850         
851                 // If necessary, sync status to operation service entry and save
852                 if (saveOperationalData) {
853                     operService.setServiceStatus(configService.getServiceStatus());
854                     operationalServicesRepository.save(operService);
855                 }
856                 retval.setOutput(resp);
857                 return (new ResponseEntity<>(retval, HttpStatus.OK));
858     }
859
860     
861 }