2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.sdnc.apps.ms.gra.controllers;
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;
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;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.validation.Valid;
55 import java.text.DateFormat;
56 import java.text.SimpleDateFormat;
58 import java.util.concurrent.atomic.AtomicBoolean;
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 {
66 private static final String CALLED_STR = "{} called.";
67 private static final String MODULE_NAME = "GENERIC-RESOURCE-API";
69 private final ObjectMapper objectMapper;
71 private final HttpServletRequest request;
74 protected SvcLogicServiceBase svc;
77 private ConfigPreloadDataRepository configPreloadDataRepository;
80 private OperationalPreloadDataRepository operationalPreloadDataRepository;
83 private ConfigServicesRepository configServicesRepository;
86 private OperationalServicesRepository operationalServicesRepository;
88 private static class Iso8601Util {
90 private static TimeZone timeZone = TimeZone.getTimeZone("UTC");
91 private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
93 private Iso8601Util() {
97 dateFormat.setTimeZone(timeZone);
100 private static String now() {
101 return dateFormat.format(new Date());
105 @org.springframework.beans.factory.annotation.Autowired
106 public OperationsApiController(ObjectMapper objectMapper, HttpServletRequest request) {
107 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
108 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
109 this.objectMapper = objectMapper;
110 this.request = request;
114 public Optional<ObjectMapper> getObjectMapper() {
115 return Optional.ofNullable(objectMapper);
119 public Optional<HttpServletRequest> getRequest() {
120 return Optional.ofNullable(request);
124 public ResponseEntity<GenericResourceApiPreloadNetworkTopologyOperation> operationsGENERICRESOURCEAPIpreloadNetworkTopologyOperationPost(
125 @Valid GenericResourceApiPreloadnetworktopologyoperationInputBodyparam graInput) {
126 final String svcOperation = "preload-network-topology-operation";
127 GenericResourceApiPreloadNetworkTopologyOperation retval = new GenericResourceApiPreloadNetworkTopologyOperation();
128 GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
130 log.info(CALLED_STR, svcOperation);
131 if (hasInvalidPreloadNetwork(graInput)) {
132 log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
134 resp.setResponseCode("403");
135 resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
136 resp.setAckFinalIndicator("Y");
138 retval.setOutput(resp);
140 return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
143 String preloadId = graInput.getInput().getPreloadNetworkTopologyInformation()
144 .getNetworkTopologyIdentifierStructure().getNetworkId();
145 String preloadType = "network";
147 resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
149 SvcLogicContext ctxIn = new SvcLogicContext();
151 GenericResourceApiPreloaddataPreloadData preloadData = null;
153 // Add input to SvcLogicContext
155 ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
156 } catch (JsonProcessingException e) {
157 log.error("exiting {} due to parse error on input preload data", svcOperation);
158 resp.setResponseCode("500");
159 resp.setResponseMessage("internal error");
160 resp.setAckFinalIndicator("Y");
161 retval.setOutput(resp);
162 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
165 // Add config tree data to SvcLogicContext
167 preloadData = getConfigPreloadData(preloadId, preloadType);
168 ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
169 } catch (JsonProcessingException e) {
170 log.error("exiting {} due to parse error on saved config preload data", svcOperation);
171 resp.setResponseCode("500");
172 resp.setResponseMessage("internal error");
173 resp.setAckFinalIndicator("Y");
174 retval.setOutput(resp);
175 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
178 // Add operational tree data to SvcLogicContext
180 preloadData = getOperationalPreloadData(preloadId, preloadType);
181 ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
182 } catch (JsonProcessingException e) {
183 log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
184 resp.setResponseCode("500");
185 resp.setResponseMessage("internal error");
186 resp.setAckFinalIndicator("Y");
187 retval.setOutput(resp);
188 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
193 // Any of these can throw a nullpointer exception
194 // execute should only throw a SvcLogicException
195 SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
196 Properties respProps = ctxOut.toProperties();
198 resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
199 resp.setResponseCode(respProps.getProperty("error-code", "200"));
200 resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
202 if ("200".equals(resp.getResponseCode())) {
203 // If DG returns success, update database
204 String ctxJson = ctxOut.toJsonString("preload-data");
205 log.info("DG preload-data is {}", ctxJson);
206 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
207 GenericResourceApiPreloaddataPreloadData.class);
208 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
209 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
212 } catch (NullPointerException npe) {
213 log.error("Caught NPE", npe);
214 resp.setAckFinalIndicator("true");
215 resp.setResponseCode("500");
216 resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
217 } catch (SvcLogicException e) {
218 log.error("Caught SvcLogicException", e);
219 resp.setAckFinalIndicator("true");
220 resp.setResponseCode("500");
221 resp.setResponseMessage(e.getMessage());
222 } catch (JsonMappingException e) {
223 log.error("Caught JsonMappingException", e);
224 resp.setAckFinalIndicator("true");
225 resp.setResponseCode("500");
226 resp.setResponseMessage(e.getMessage());
227 } catch (JsonProcessingException e) {
228 log.error("Caught JsonProcessingException", e);
229 resp.setAckFinalIndicator("true");
230 resp.setResponseCode("500");
231 resp.setResponseMessage(e.getMessage());
234 retval.setOutput(resp);
235 return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
239 public ResponseEntity<GenericResourceApiPreloadVfModuleTopologyOperation> operationsGENERICRESOURCEAPIpreloadVfModuleTopologyOperationPost(
240 @Valid GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam graInput) {
241 final String svcOperation = "preload-vf-module-topology-operation";
242 GenericResourceApiPreloadVfModuleTopologyOperation retval = new GenericResourceApiPreloadVfModuleTopologyOperation();
243 GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
245 log.info(CALLED_STR, svcOperation);
246 if (hasInvalidPreloadNetwork(graInput)) {
247 log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
249 resp.setResponseCode("403");
250 resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
251 resp.setAckFinalIndicator("Y");
253 retval.setOutput(resp);
255 return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
258 String preloadId = graInput.getInput().getPreloadVfModuleTopologyInformation().getVfModuleTopology()
259 .getVfModuleTopologyIdentifier().getVfModuleName();
260 String preloadType = "vf-module";
262 resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
264 SvcLogicContext ctxIn = new SvcLogicContext();
266 GenericResourceApiPreloaddataPreloadData preloadData = null;
268 // Add input to SvcLogicContext
270 ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(graInput.getInput()));
271 } catch (JsonProcessingException e) {
272 log.error("exiting {} due to parse error on input preload data", svcOperation);
273 resp.setResponseCode("500");
274 resp.setResponseMessage("internal error");
275 resp.setAckFinalIndicator("Y");
276 retval.setOutput(resp);
277 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
280 // Add config tree data to SvcLogicContext
282 preloadData = getConfigPreloadData(preloadId, preloadType);
283 ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
284 } catch (JsonProcessingException e) {
285 log.error("exiting {} due to parse error on saved config preload data", svcOperation);
286 resp.setResponseCode("500");
287 resp.setResponseMessage("internal error");
288 resp.setAckFinalIndicator("Y");
289 retval.setOutput(resp);
290 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
293 // Add operational tree data to SvcLogicContext
295 preloadData = getOperationalPreloadData(preloadId, preloadType);
296 ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
297 } catch (JsonProcessingException e) {
298 log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
299 resp.setResponseCode("500");
300 resp.setResponseMessage("internal error");
301 resp.setAckFinalIndicator("Y");
302 retval.setOutput(resp);
303 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
308 // Any of these can throw a nullpointer exception
309 // execute should only throw a SvcLogicException
310 SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
311 Properties respProps = ctxOut.toProperties();
313 resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
314 resp.setResponseCode(respProps.getProperty("error-code", "200"));
315 resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
317 if ("200".equals(resp.getResponseCode())) {
318 // If DG returns success, update database
319 String ctxJson = ctxOut.toJsonString("preload-data");
320 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson,
321 GenericResourceApiPreloaddataPreloadData.class);
322 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
323 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
326 } catch (NullPointerException npe) {
327 resp.setAckFinalIndicator("true");
328 resp.setResponseCode("500");
329 resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
330 } catch (SvcLogicException e) {
331 resp.setAckFinalIndicator("true");
332 resp.setResponseCode("500");
333 resp.setResponseMessage(e.getMessage());
334 } catch (JsonMappingException e) {
335 resp.setAckFinalIndicator("true");
336 resp.setResponseCode("500");
337 resp.setResponseMessage(e.getMessage());
338 } catch (JsonProcessingException e) {
339 resp.setAckFinalIndicator("true");
340 resp.setResponseCode("500");
341 resp.setResponseMessage(e.getMessage());
344 retval.setOutput(resp);
345 return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
348 private boolean hasInvalidPreloadNetwork(
349 GenericResourceApiPreloadnetworktopologyoperationInputBodyparam preloadData) {
350 return ((preloadData == null) || (preloadData.getInput() == null)
351 || (preloadData.getInput().getPreloadNetworkTopologyInformation() == null));
354 private boolean hasInvalidPreloadNetwork(
355 GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam preloadData) {
356 return ((preloadData == null) || (preloadData.getInput() == null)
357 || (preloadData.getInput().getPreloadVfModuleTopologyInformation() == null));
360 private boolean hasInvalidServiceId(GenericResourceApiServiceOperationInformation input) {
362 return input == null || input.getServiceInformation() == null
363 || input.getServiceInformation().getServiceInstanceId() == null
364 || input.getServiceInformation().getServiceInstanceId().length() == 0;
367 private boolean hasInvalidServiceId(GenericResourceApiNetworkOperationInformation input) {
369 return input == null || input.getServiceInformation() == null
370 || input.getServiceInformation().getServiceInstanceId() == null
371 || input.getServiceInformation().getServiceInstanceId().length() == 0;
374 private GenericResourceApiPreloaddataPreloadData getConfigPreloadData(String preloadId, String preloadType)
375 throws JsonProcessingException {
377 List<ConfigPreloadData> configPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId,
380 if (configPreloadData.isEmpty()) {
383 return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
384 GenericResourceApiPreloaddataPreloadData.class));
388 private GenericResourceApiPreloaddataPreloadData getOperationalPreloadData(String preloadId, String preloadType)
389 throws JsonProcessingException {
391 List<OperationalPreloadData> configPreloadData = operationalPreloadDataRepository
392 .findByPreloadIdAndPreloadType(preloadId, preloadType);
394 if (configPreloadData.isEmpty()) {
397 return (objectMapper.readValue(configPreloadData.get(0).getPreloadData(),
398 GenericResourceApiPreloaddataPreloadData.class));
402 private void saveConfigPreloadData(String preloadId, String preloadType,
403 GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
405 configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
406 configPreloadDataRepository
407 .save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
411 private void saveOperationalPreloadData(String preloadId, String preloadType,
412 GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
414 operationalPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
415 operationalPreloadDataRepository
416 .save(new OperationalPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
420 private GenericResourceApiServicedataServiceData getConfigServiceData(String svcInstanceId) throws JsonProcessingException {
422 List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
424 if (configServices.isEmpty()) {
427 return (objectMapper.readValue(configServices.get(0).getSvcData(),
428 GenericResourceApiServicedataServiceData.class));
434 public ResponseEntity<GenericResourceApiNetworkTopologyOperation> operationsGENERICRESOURCEAPInetworkTopologyOperationPost(
435 @Valid GenericResourceApiNetworkOperationInformationBodyparam input)
436 throws RestException {
437 final String svcOperation = "network-topology-operation";
438 GenericResourceApiNetworkTopologyOperation retval = new GenericResourceApiNetworkTopologyOperation();
439 GenericResourceApiNetworktopologyoperationOutput resp = new GenericResourceApiNetworktopologyoperationOutput();
441 log.info(CALLED_STR, svcOperation);
442 // Verify input contains service instance id
443 if (hasInvalidServiceId(input.getInput())) {
444 log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
446 resp.setResponseCode("404");
447 resp.setResponseMessage("null or empty service-instance-id");
448 resp.setAckFinalIndicator("Y");
450 retval.setOutput(resp);
452 return new ResponseEntity<>(retval, HttpStatus.OK);
455 String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
457 SvcLogicContext ctxIn = new SvcLogicContext();
459 // Add input to SvcLogicContext
461 ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
462 } catch (JsonProcessingException e) {
463 log.error("exiting {} due to parse error on input data", svcOperation);
464 resp.setResponseCode("500");
465 resp.setResponseMessage("internal error");
466 resp.setAckFinalIndicator("Y");
467 retval.setOutput(resp);
468 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
471 // Add config tree data to SvcLogicContext
472 List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
473 ConfigServices configService = null;
474 if (configServices != null && !configServices.isEmpty()) {
475 configService = configServices.get(0);
476 ctxIn.mergeJson("service-data", configService.getSvcData());
478 log.debug("exiting {} because the service-instance does not have any service data in SDN", svcOperation);
480 resp.setResponseCode("404");
481 resp.setResponseMessage("invalid input: the service-instance does not have any service data in SDNC");
482 resp.setAckFinalIndicator("Y");
484 retval.setOutput(resp);
486 return new ResponseEntity<>(retval, HttpStatus.OK);
489 // Add operational tree data to SvcLogicContext
490 List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
491 OperationalServices operService = null;
492 boolean saveOperationalData = false;
494 if (operServices != null && !operServices.isEmpty()) {
495 operService = operServices.get(0);
496 ctxIn.mergeJson("operational-data", operService.getSvcData());
498 operService = new OperationalServices(svcInstanceId, null, null);
501 // Update service status info in config entry from input
502 configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
503 configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
504 configService.setServiceStatusRpcName(svcOperation);
508 // Any of these can throw a nullpointer exception
509 // execute should only throw a SvcLogicException
510 SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
511 Properties respProps = ctxOut.toProperties();
513 resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
514 resp.setResponseCode(respProps.getProperty("error-code", "200"));
515 resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
516 configService.setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
518 if ("200".equals(resp.getResponseCode())) {
519 // If DG returns success, update svcData in config and operational trees
520 // and remember to save operational data.
521 String ctxJson = ctxOut.toJsonString("service-data");
522 configService.setSvcData(ctxJson);
523 operService.setSvcData(ctxJson);
524 saveOperationalData = true;
527 } catch (NullPointerException npe) {
528 resp.setAckFinalIndicator("true");
529 resp.setResponseCode("500");
530 resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
531 } catch (SvcLogicException e) {
532 resp.setAckFinalIndicator("true");
533 resp.setResponseCode("500");
534 resp.setResponseMessage(e.getMessage());
537 // Update status in config services entry
539 configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
540 configService.setServiceStatusResponseCode(resp.getResponseCode());
541 configService.setServiceStatusResponseMessage(resp.getResponseMessage());
542 configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
544 // Update config tree
545 configServicesRepository.save(configService);
547 // If necessary, sync status to operation service entry and save
548 if (saveOperationalData) {
549 operService.setServiceStatus(configService.getServiceStatus());
550 operationalServicesRepository.save(operService);
552 retval.setOutput(resp);
553 return (new ResponseEntity<>(retval, HttpStatus.OK));
557 public ResponseEntity<GenericResourceApiServiceTopologyOperation> operationsGENERICRESOURCEAPIserviceTopologyOperationPost(
558 @Valid GenericResourceApiServiceOperationInformationBodyparam input) throws RestException {
559 final String svcOperation = "service-topology-operation";
560 GenericResourceApiServiceTopologyOperation retval = new GenericResourceApiServiceTopologyOperation();
561 GenericResourceApiServicetopologyoperationOutput resp = new GenericResourceApiServicetopologyoperationOutput();
563 log.info(CALLED_STR, svcOperation);
565 // Verify input contains service instance id
566 if (hasInvalidServiceId(input.getInput())) {
567 log.debug("exiting {} because of null or empty service-instance-id", svcOperation);
569 resp.setResponseCode("404");
570 resp.setResponseMessage("null or empty service-instance-id");
571 resp.setAckFinalIndicator("Y");
573 retval.setOutput(resp);
575 return new ResponseEntity<>(retval, HttpStatus.OK);
578 String svcInstanceId = input.getInput().getServiceInformation().getServiceInstanceId();
580 SvcLogicContext ctxIn = new SvcLogicContext();
582 // Add input to SvcLogicContext
584 ctxIn.mergeJson(svcOperation + "-input", objectMapper.writeValueAsString(input.getInput()));
585 } catch (JsonProcessingException e) {
586 log.error("exiting {} due to parse error on input data", svcOperation);
587 resp.setResponseCode("500");
588 resp.setResponseMessage("internal error");
589 resp.setAckFinalIndicator("Y");
590 retval.setOutput(resp);
591 return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
594 // Add config tree data to SvcLogicContext
595 List<ConfigServices> configServices = configServicesRepository.findBySvcInstanceId(svcInstanceId);
596 ConfigServices configService = null;
597 if (configServices != null && !configServices.isEmpty()) {
598 configService = configServices.get(0);
599 if (configService.getSvcData() != null) {
600 ctxIn.mergeJson("service-data", configService.getSvcData());
603 configService = new ConfigServices(svcInstanceId, null);
606 // Add operational tree data to SvcLogicContext
607 List<OperationalServices> operServices = operationalServicesRepository.findBySvcInstanceId(svcInstanceId);
608 OperationalServices operService = null;
609 boolean saveOperationalData = false;
611 if (operServices != null && !operServices.isEmpty()) {
612 operService = operServices.get(0);
613 ctxIn.mergeJson("operational-data", operService.getSvcData());
615 operService = new OperationalServices(svcInstanceId, null, null);
618 // Update service status info in config entry from input
619 configService.setServiceStatusAction(input.getInput().getRequestInformation().getRequestAction().toString());
620 configService.setServiceStatusRpcAction(input.getInput().getSdncRequestHeader().getSvcAction().toString());
621 configService.setServiceStatusRpcName(svcOperation);
626 // Any of these can throw a nullpointer exception
627 // execute should only throw a SvcLogicException
628 SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
629 Properties respProps = ctxOut.toProperties();
631 resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
632 resp.setResponseCode(respProps.getProperty("error-code", "200"));
633 resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
634 configService.setServiceStatusRequestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE.toString());
636 if ("200".equals(resp.getResponseCode())) {
637 // If DG returns success, update svcData in config and operational trees
638 // and remember to save operational data.
639 String ctxJson = ctxOut.toJsonString("service-data");
640 configService.setSvcData(ctxJson);
641 operService.setSvcData(ctxJson);
642 saveOperationalData = true;
645 } catch (NullPointerException npe) {
646 resp.setAckFinalIndicator("true");
647 resp.setResponseCode("500");
648 resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
649 } catch (SvcLogicException e) {
650 resp.setAckFinalIndicator("true");
651 resp.setResponseCode("500");
652 resp.setResponseMessage(e.getMessage());
655 // Update status in config services entry
657 configService.setServiceStatusFinalIndicator(resp.getAckFinalIndicator());
658 configService.setServiceStatusResponseCode(resp.getResponseCode());
659 configService.setServiceStatusResponseMessage(resp.getResponseMessage());
660 configService.setServiceStatusResponseTimestamp(Iso8601Util.now());
662 // Update config tree
663 configServicesRepository.save(configService);
665 // If necessary, sync status to operation service entry and save
666 if (saveOperationalData) {
667 operService.setServiceStatus(configService.getServiceStatus());
668 operationalServicesRepository.save(operService);
670 retval.setOutput(resp);
671 return (new ResponseEntity<>(retval, HttpStatus.OK));