2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2023 Nordix Foundation
 
   4  *  ================================================================================
 
   5  *  Licensed under the Apache License, Version 2.0 (the "License");
 
   6  *  you may not use this file except in compliance with the License.
 
   7  *  You may obtain a copy of the License at
 
   9  *        http://www.apache.org/licenses/LICENSE-2.0
 
  11  *  Unless required by applicable law or agreed to in writing, software
 
  12  *  distributed under the License is distributed on an "AS IS" BASIS,
 
  13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  *  See the License for the specific language governing permissions and
 
  15  *  limitations under the License.
 
  17  *  SPDX-License-Identifier: Apache-2.0
 
  18  *  ============LICENSE_END=========================================================
 
  21 package org.onap.cps.ncmp.dmi.rest.stub.controller;
 
  23 import com.fasterxml.jackson.core.JsonProcessingException;
 
  24 import com.fasterxml.jackson.databind.ObjectMapper;
 
  25 import io.cloudevents.CloudEvent;
 
  26 import io.cloudevents.core.builder.CloudEventBuilder;
 
  28 import java.util.ArrayList;
 
  29 import java.util.List;
 
  30 import java.util.UUID;
 
  31 import java.util.stream.Collectors;
 
  32 import lombok.RequiredArgsConstructor;
 
  33 import lombok.extern.slf4j.Slf4j;
 
  34 import org.json.simple.parser.JSONParser;
 
  35 import org.json.simple.parser.ParseException;
 
  36 import org.onap.cps.ncmp.api.NcmpEventResponseCode;
 
  37 import org.onap.cps.ncmp.api.impl.utils.EventDateTimeFormatter;
 
  38 import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.CmHandle;
 
  39 import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.DataOperationRequest;
 
  40 import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.DmiDataOperationRequest;
 
  41 import org.onap.cps.ncmp.dmi.rest.stub.utils.ResourceFileReaderUtil;
 
  42 import org.onap.cps.ncmp.events.async1_0_0.Data;
 
  43 import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent;
 
  44 import org.onap.cps.ncmp.events.async1_0_0.Response;
 
  45 import org.springframework.beans.factory.annotation.Value;
 
  46 import org.springframework.context.ApplicationContext;
 
  47 import org.springframework.core.io.ResourceLoader;
 
  48 import org.springframework.http.HttpStatus;
 
  49 import org.springframework.http.ResponseEntity;
 
  50 import org.springframework.kafka.core.KafkaTemplate;
 
  51 import org.springframework.web.bind.annotation.PathVariable;
 
  52 import org.springframework.web.bind.annotation.PostMapping;
 
  53 import org.springframework.web.bind.annotation.RequestBody;
 
  54 import org.springframework.web.bind.annotation.RequestMapping;
 
  55 import org.springframework.web.bind.annotation.RequestParam;
 
  56 import org.springframework.web.bind.annotation.RestController;
 
  59 @RequestMapping("${rest.api.dmi-stub-base-path}")
 
  60 @RequiredArgsConstructor
 
  62 public class DmiRestStubController {
 
  64     private final KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate;
 
  65     private final ObjectMapper objectMapper;
 
  66     private final ApplicationContext applicationContext;
 
  68     @Value("${app.ncmp.async-m2m.topic}")
 
  69     private String ncmpAsyncM2mTopic;
 
  71     private String dataOperationEventType = "org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent";
 
  74      * Get all modules for given cm handle.
 
  76      * @param cmHandle                The identifier for a network function, network element, subnetwork,
 
  77      *                                or any other cm object by managed Network CM Proxy
 
  78      * @param moduleReferencesRequest module references request body
 
  79      * @return ResponseEntity response entity having module response as json string.
 
  81     @PostMapping("/v1/ch/{cmHandle}/modules")
 
  82     public ResponseEntity<String> getModuleReferences(@PathVariable final String cmHandle,
 
  83                                                       @RequestBody final Object moduleReferencesRequest) {
 
  84         final String moduleResponseContent = ResourceFileReaderUtil
 
  85                 .getResourceFileContent(applicationContext.getResource(
 
  86                         ResourceLoader.CLASSPATH_URL_PREFIX + "module/moduleResponse.json"));
 
  87         return ResponseEntity.ok(moduleResponseContent);
 
  91      * Get all module resources for given cm handle.
 
  93      * @param cmHandle                   The identifier for a network function, network element, subnetwork,
 
  94      *                                   or any other cm object by managed Network CM Proxy
 
  95      * @param moduleResourcesReadRequest module resources read request body
 
  96      * @return ResponseEntity response entity having module resources response as json string.
 
  98     @PostMapping("/v1/ch/{cmHandle}/moduleResources")
 
  99     public ResponseEntity<String> retrieveModuleResources(
 
 100             @PathVariable final String cmHandle,
 
 101             @RequestBody final Object moduleResourcesReadRequest) {
 
 102         final String moduleResourcesResponseContent = ResourceFileReaderUtil
 
 103                 .getResourceFileContent(applicationContext.getResource(
 
 104                         ResourceLoader.CLASSPATH_URL_PREFIX + "module/moduleResourcesResponse.json"));
 
 105         return ResponseEntity.ok(moduleResourcesResponseContent);
 
 109      * This method is not implemented for ONAP DMI plugin.
 
 111      * @param topic                   client given topic name
 
 112      * @param requestId               requestId generated by NCMP as an ack for client
 
 113      * @param dmiDataOperationRequest list of operation details
 
 114      * @return (@ code ResponseEntity) response entity
 
 116     @PostMapping("/v1/data")
 
 117     public ResponseEntity<Void> getResourceDataForCmHandleDataOperation(@RequestParam(value = "topic")
 
 119                                                                         @RequestParam(value = "requestId")
 
 120                                                                         final String requestId,
 
 121                                                                         @RequestBody final DmiDataOperationRequest
 
 122                                                                                     dmiDataOperationRequest) {
 
 124             log.info("Request received from the NCMP to DMI Plugin: {}",
 
 125                     objectMapper.writeValueAsString(dmiDataOperationRequest));
 
 126         } catch (final JsonProcessingException jsonProcessingException) {
 
 127             log.info("Unable to process dmi data operation request to json string");
 
 129         dmiDataOperationRequest.getOperations().forEach(dmiDataOperation -> {
 
 130             final DataOperationEvent dataOperationEvent = getDataOperationEvent(dmiDataOperation);
 
 131             dmiDataOperation.getCmHandles().forEach(cmHandle -> {
 
 132                 dataOperationEvent.getData().getResponses().get(0).setIds(List.of(cmHandle.getId()));
 
 133                 final CloudEvent cloudEvent = buildAndGetCloudEvent(topic, requestId, dataOperationEvent);
 
 134                 cloudEventKafkaTemplate.send(ncmpAsyncM2mTopic, UUID.randomUUID().toString(), cloudEvent);
 
 137         return new ResponseEntity<>(HttpStatus.ACCEPTED);
 
 140     private CloudEvent buildAndGetCloudEvent(final String topic, final String requestId,
 
 141                                              final DataOperationEvent dataOperationEvent) {
 
 142         CloudEvent cloudEvent = null;
 
 144             cloudEvent = CloudEventBuilder.v1()
 
 145                     .withId(UUID.randomUUID().toString())
 
 146                     .withSource(URI.create("DMI"))
 
 147                     .withType(dataOperationEventType)
 
 148                     .withDataSchema(URI.create("urn:cps:" + dataOperationEventType + ":1.0.0"))
 
 149                     .withTime(EventDateTimeFormatter.toIsoOffsetDateTime(
 
 150                             EventDateTimeFormatter.getCurrentIsoFormattedDateTime()))
 
 151                     .withData(objectMapper.writeValueAsBytes(dataOperationEvent))
 
 152                     .withExtension("destination", topic)
 
 153                     .withExtension("correlationid", requestId)
 
 155         } catch (final JsonProcessingException jsonProcessingException) {
 
 156             log.error("Unable to parse event into bytes. cause : {}", jsonProcessingException.getMessage());
 
 161     private DataOperationEvent getDataOperationEvent(final DataOperationRequest dataOperationRequest) {
 
 162         final Response response = new Response();
 
 163         response.setOperationId(dataOperationRequest.getOperationId());
 
 164         response.setStatusCode(NcmpEventResponseCode.SUCCESS.getStatusCode());
 
 165         response.setStatusMessage(NcmpEventResponseCode.SUCCESS.getStatusMessage());
 
 166         response.setIds(dataOperationRequest.getCmHandles().stream().map(CmHandle::getId).collect(Collectors.toList()));
 
 167         final String ietfNetworkTopologySample = ResourceFileReaderUtil
 
 168                 .getResourceFileContent(applicationContext.getResource(
 
 169                         ResourceLoader.CLASSPATH_URL_PREFIX
 
 170                                 + "data/operational/ietf-network-topology-sample-rfc8345.json"));
 
 171         final JSONParser jsonParser = new JSONParser();
 
 173             response.setResult(jsonParser.parse(ietfNetworkTopologySample));
 
 174         } catch (final ParseException parseException) {
 
 175             log.error("Unable to parse event result as json object. cause : {}", parseException.getMessage());
 
 177         final List<Response> responseList = new ArrayList<>();
 
 178         responseList.add(response);
 
 179         final Data data = new Data();
 
 180         data.setResponses(responseList);
 
 181         final DataOperationEvent dataOperationEvent = new DataOperationEvent();
 
 182         dataOperationEvent.setData(data);
 
 183         return dataOperationEvent;