diff options
author | 2024-11-20 14:43:25 +0000 | |
---|---|---|
committer | 2024-11-20 15:43:50 +0000 | |
commit | 9ad11f2914b10b3d5049aa8dde050c998b1f9f82 (patch) | |
tree | 4520cf3d4b3d5e6bb1ef5e8b9cd87136011aa9dd /dmi-stub/dmi-stub-service/src/main/java | |
parent | 38becbcbbc5552150133ee1b4b477903f0f1e6c6 (diff) |
[DMI] Fix for DMI merge master Job
- module names of onap dmi and stub is changed
- reverted to 1.6.0-SNAPSHOT
Issue-ID: CPS-2499
Change-Id: I2ca6f98ceb38bfc366997358ab9ecb0624098ac9
Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
Diffstat (limited to 'dmi-stub/dmi-stub-service/src/main/java')
13 files changed, 1030 insertions, 0 deletions
diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java new file mode 100644 index 00000000..cf18f239 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java @@ -0,0 +1,417 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023-2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.controller; + +import static org.onap.cps.ncmp.dmi.rest.stub.utils.ModuleResponseType.MODULE_REFERENCE_RESPONSE; +import static org.onap.cps.ncmp.dmi.rest.stub.utils.ModuleResponseType.MODULE_RESOURCE_RESPONSE; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.onap.cps.ncmp.dmi.datajobs.model.SubjobWriteRequest; +import org.onap.cps.ncmp.dmi.datajobs.model.SubjobWriteResponse; +import org.onap.cps.ncmp.dmi.rest.stub.controller.aop.ModuleInitialProcess; +import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.DataOperationRequest; +import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.DmiDataOperationRequest; +import org.onap.cps.ncmp.dmi.rest.stub.model.data.operational.DmiOperationCmHandle; +import org.onap.cps.ncmp.dmi.rest.stub.service.YangModuleFactory; +import org.onap.cps.ncmp.dmi.rest.stub.utils.EventDateTimeFormatter; +import org.onap.cps.ncmp.dmi.rest.stub.utils.ModuleResponseType; +import org.onap.cps.ncmp.dmi.rest.stub.utils.ResourceFileReaderUtil; +import org.onap.cps.ncmp.events.async1_0_0.Data; +import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent; +import org.onap.cps.ncmp.events.async1_0_0.Response; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${rest.api.dmi-stub-base-path}") +@Slf4j +@RequiredArgsConstructor +public class DmiRestStubController { + + private static final String DEFAULT_PASSTHROUGH_OPERATION = "read"; + private static final String DATA_OPERATION_EVENT_TYPE = "org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent"; + private static final Map<String, String> moduleSetTagPerCmHandleId = new HashMap<>(); + private static final List<String> MODULE_SET_TAGS = YangModuleFactory.generateTags(); + private static final String DEFAULT_TAG = "tagDefault"; + + private final KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate; + private final ObjectMapper objectMapper; + private final ApplicationContext applicationContext; + private final AtomicInteger subJobWriteRequestCounter = new AtomicInteger(); + private final YangModuleFactory yangModuleFactory; + + @Value("${app.ncmp.async-m2m.topic}") + private String ncmpAsyncM2mTopic; + @Value("${delay.module-references-delay-ms}") + private long moduleReferencesDelayMs; + @Value("${delay.module-resources-delay-ms}") + private long moduleResourcesDelayMs; + @Value("${delay.read-data-for-cm-handle-delay-ms}") + private long readDataForCmHandleDelayMs; + @Value("${delay.write-data-for-cm-handle-delay-ms}") + private long writeDataForCmHandleDelayMs; + + /** + * This code defines a REST API endpoint for adding new the module set tag mapping. The endpoint receives the + * cmHandleId and moduleSetTag as request body and add into moduleSetTagPerCmHandleId map with the provided + * values. + * + * @param requestBody map of cmHandleId and moduleSetTag + * @return a ResponseEntity object containing the updated moduleSetTagPerCmHandleId map as the response body + */ + @PostMapping("/v1/tagMapping") + public ResponseEntity<Map<String, String>> addTagForMapping(@RequestBody final Map<String, String> requestBody) { + moduleSetTagPerCmHandleId.putAll(requestBody); + return new ResponseEntity<>(requestBody, HttpStatus.CREATED); + } + + /** + * This code defines a GET endpoint of module set tag mapping. + * + * @return The map represents the module set tag mapping. + */ + @GetMapping("/v1/tagMapping") + public ResponseEntity<Map<String, String>> getTagMapping() { + return ResponseEntity.ok(moduleSetTagPerCmHandleId); + } + + /** + * This code defines a GET endpoint of module set tag by cm handle ID. + * + * @return The map represents the module set tag mapping filtered by cm handle ID. + */ + @GetMapping("/v1/tagMapping/ch/{cmHandleId}") + public ResponseEntity<String> getTagMappingByCmHandleId(@PathVariable final String cmHandleId) { + return ResponseEntity.ok(moduleSetTagPerCmHandleId.get(cmHandleId)); + } + + /** + * This code defines a REST API endpoint for updating the module set tag mapping. The endpoint receives the + * cmHandleId and moduleSetTag as request body and updates the moduleSetTagPerCmHandleId map with the provided + * values. + * + * @param requestBody map of cmHandleId and moduleSetTag + * @return a ResponseEntity object containing the updated moduleSetTagPerCmHandleId map as the response body + */ + + @PutMapping("/v1/tagMapping") + public ResponseEntity<Map<String, String>> updateTagMapping(@RequestBody final Map<String, String> requestBody) { + moduleSetTagPerCmHandleId.putAll(requestBody); + return ResponseEntity.noContent().build(); + } + + /** + * It contains a method to delete an entry from the moduleSetTagPerCmHandleId map. + * The method takes a cmHandleId as a parameter and removes the corresponding entry from the map. + * + * @return a ResponseEntity containing the updated map. + */ + @DeleteMapping("/v1/tagMapping/ch/{cmHandleId}") + public ResponseEntity<String> deleteTagMappingByCmHandleId(@PathVariable final String cmHandleId) { + moduleSetTagPerCmHandleId.remove(cmHandleId); + return ResponseEntity.ok(String.format("Mapping of %s is deleted successfully", cmHandleId)); + } + + /** + * Get all modules for given cm handle. + * + * @param cmHandleId The identifier for a network function, network element, subnetwork, + * or any other cm object by managed Network CM Proxy + * @param moduleReferencesRequest module references request body + * @return ResponseEntity response entity having module response as json string. + */ + @PostMapping("/v1/ch/{cmHandleId}/modules") + @ModuleInitialProcess + public ResponseEntity<String> getModuleReferences(@PathVariable("cmHandleId") final String cmHandleId, + @RequestBody final Object moduleReferencesRequest) { + return processModuleRequest(moduleReferencesRequest, MODULE_REFERENCE_RESPONSE, moduleReferencesDelayMs); + } + + /** + * Get module resources for a given cmHandleId. + * + * @param cmHandleId The identifier for a network function, network element, subnetwork, + * or any other cm object by managed Network CM Proxy + * @param moduleResourcesReadRequest module resources read request body + * @return ResponseEntity response entity having module resources response as json string. + */ + @PostMapping("/v1/ch/{cmHandleId}/moduleResources") + @ModuleInitialProcess + public ResponseEntity<String> getModuleResources( + @PathVariable("cmHandleId") final String cmHandleId, + @RequestBody final Object moduleResourcesReadRequest) { + return processModuleRequest(moduleResourcesReadRequest, MODULE_RESOURCE_RESPONSE, moduleResourcesDelayMs); + } + + /** + * Create resource data from passthrough operational or running for a cm handle. + * + * @param cmHandleId The identifier for a network function, network element, subnetwork, + * or any other cm object by managed Network CM Proxy + * @param datastoreName datastore name + * @param resourceIdentifier resource identifier + * @param options options + * @param topic client given topic name + * @return (@ code ResponseEntity) response entity + */ + @PostMapping("/v1/ch/{cmHandleId}/data/ds/{datastoreName}") + public ResponseEntity<String> getResourceDataForCmHandle( + @PathVariable("cmHandleId") final String cmHandleId, + @PathVariable("datastoreName") final String datastoreName, + @RequestParam(value = "resourceIdentifier") final String resourceIdentifier, + @RequestParam(value = "options", required = false) final String options, + @RequestParam(value = "topic", required = false) final String topic, + @RequestHeader(value = "Authorization", required = false) final String authorization, + @RequestBody final String requestBody) { + log.info("DMI AUTH HEADER: {}", authorization); + final String passthroughOperationType = getPassthroughOperationType(requestBody); + if (passthroughOperationType.equals("read")) { + delay(readDataForCmHandleDelayMs); + } else { + delay(writeDataForCmHandleDelayMs); + } + log.info("Logging request body {}", requestBody); + + final String sampleJson = ResourceFileReaderUtil.getResourceFileContent(applicationContext.getResource( + ResourceLoader.CLASSPATH_URL_PREFIX + "data/ietf-network-topology-sample-rfc8345.json")); + return ResponseEntity.ok(sampleJson); + } + + /** + * This method is not implemented for ONAP DMI plugin. + * + * @param topic client given topic name + * @param requestId requestId generated by NCMP as an ack for client + * @param dmiDataOperationRequest list of operation details + * @return (@ code ResponseEntity) response entity + */ + @PostMapping("/v1/data") + public ResponseEntity<Void> getResourceDataForCmHandleDataOperation( + @RequestParam(value = "topic") final String topic, + @RequestParam(value = "requestId") final String requestId, + @RequestBody final DmiDataOperationRequest dmiDataOperationRequest) { + delay(writeDataForCmHandleDelayMs); + try { + log.info("Request received from the NCMP to DMI Plugin: {}", + objectMapper.writeValueAsString(dmiDataOperationRequest)); + } catch (final JsonProcessingException jsonProcessingException) { + log.info("Unable to process dmi data operation request to json string"); + } + dmiDataOperationRequest.getOperations().forEach(dmiDataOperation -> { + final DataOperationEvent dataOperationEvent = getDataOperationEvent(dmiDataOperation); + dmiDataOperation.getCmHandles().forEach(dmiOperationCmHandle -> { + log.info("Module Set Tag received: {}", dmiOperationCmHandle.getModuleSetTag()); + dataOperationEvent.getData().getResponses().get(0).setIds(List.of(dmiOperationCmHandle.getId())); + final CloudEvent cloudEvent = buildAndGetCloudEvent(topic, requestId, dataOperationEvent); + cloudEventKafkaTemplate.send(ncmpAsyncM2mTopic, UUID.randomUUID().toString(), cloudEvent); + }); + }); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + /** + * Consume sub-job write requests from NCMP. + * + * @param subJobWriteRequest contains a collection of write requests and metadata. + * @param destination the destination of the results. ( e.g. S3 Bucket). + * @return (@ code ResponseEntity) response for the write request. + */ + @PostMapping("/v1/cmwriteJob") + public ResponseEntity<SubjobWriteResponse> consumeWriteSubJobs( + @RequestBody final SubjobWriteRequest subJobWriteRequest, + @RequestParam("destination") final String destination) { + log.debug("Destination: {}", destination); + log.debug("Request body: {}", subJobWriteRequest); + return ResponseEntity.ok(new SubjobWriteResponse(String.valueOf(subJobWriteRequestCounter.incrementAndGet()), + "some-dmi-service-name", "my-data-producer-id")); + } + + /** + * Retrieves the status of a given data job identified by {@code requestId} and {@code dataProducerJobId}. + * + * @param dataProducerId ID of the producer registered by DMI for the alternateIDs + * in the operations in this request. + * @param dataProducerJobId Identifier of the data producer job. + * @return A ResponseEntity with HTTP status 200 (OK) and the data job's status as a string. + */ + @GetMapping("/v1/cmwriteJob/dataProducer/{dataProducerId}/dataProducerJob/{dataProducerJobId}/status") + public ResponseEntity<Map<String, String>> retrieveDataJobStatus( + @PathVariable("dataProducerId") final String dataProducerId, + @PathVariable("dataProducerJobId") final String dataProducerJobId) { + log.info("Received request to retrieve data job status. Request ID: {}, Data Producer Job ID: {}", + dataProducerId, dataProducerJobId); + return ResponseEntity.ok(Map.of("status", "FINISHED")); + } + + /** + * Retrieves the result of a given data job identified by {@code requestId} and {@code dataProducerJobId}. + * + * @param dataProducerId Identifier for the data producer as a query parameter (required) + * @param dataProducerJobId Identifier for the data producer job (required) + * @param destination The destination of the results, Kafka topic name or s3 bucket name (required) + * @return A ResponseEntity with HTTP status 200 (OK) and the data job's result as an Object. + */ + @GetMapping("/v1/cmwriteJob/dataProducer/{dataProducerId}/dataProducerJob/{dataProducerJobId}/result") + public ResponseEntity<Object> retrieveDataJobResult( + @PathVariable("dataProducerId") final String dataProducerId, + @PathVariable("dataProducerJobId") final String dataProducerJobId, + @RequestParam(name = "destination") final String destination) { + log.debug("Received request to retrieve data job result. Data Producer ID: {}, " + + "Data Producer Job ID: {}, Destination: {}", + dataProducerId, dataProducerJobId, destination); + return ResponseEntity.ok(Map.of("result", "some status")); + } + + private CloudEvent buildAndGetCloudEvent(final String topic, final String requestId, + final DataOperationEvent dataOperationEvent) { + CloudEvent cloudEvent = null; + try { + cloudEvent = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSource(URI.create("DMI")) + .withType(DATA_OPERATION_EVENT_TYPE) + .withDataSchema(URI.create("urn:cps:" + DATA_OPERATION_EVENT_TYPE + ":1.0.0")) + .withTime(EventDateTimeFormatter.toIsoOffsetDateTime( + EventDateTimeFormatter.getCurrentIsoFormattedDateTime())) + .withData(objectMapper.writeValueAsBytes(dataOperationEvent)) + .withExtension("destination", topic) + .withExtension("correlationid", requestId) + .build(); + } catch (final JsonProcessingException jsonProcessingException) { + log.error("Unable to parse event into bytes. cause : {}", jsonProcessingException.getMessage()); + } + return cloudEvent; + } + + private DataOperationEvent getDataOperationEvent(final DataOperationRequest dataOperationRequest) { + final Response response = new Response(); + + response.setOperationId(dataOperationRequest.getOperationId()); + response.setStatusCode("0"); + response.setStatusMessage("Successfully applied changes"); + response.setIds(dataOperationRequest.getCmHandles().stream().map(DmiOperationCmHandle::getId) + .collect(Collectors.toList())); + response.setResourceIdentifier(dataOperationRequest.getResourceIdentifier()); + response.setOptions(dataOperationRequest.getOptions()); + final String ietfNetworkTopologySample = ResourceFileReaderUtil.getResourceFileContent( + applicationContext.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + + "data/ietf-network-topology-sample-rfc8345.json")); + final JSONParser jsonParser = new JSONParser(); + try { + response.setResult(jsonParser.parse(ietfNetworkTopologySample)); + } catch (final ParseException parseException) { + log.error("Unable to parse event result as json object. cause : {}", parseException.getMessage()); + } + final List<Response> responseList = new ArrayList<>(1); + responseList.add(response); + final Data data = new Data(); + data.setResponses(responseList); + final DataOperationEvent dataOperationEvent = new DataOperationEvent(); + dataOperationEvent.setData(data); + return dataOperationEvent; + } + + private ResponseEntity<String> processModuleRequest(final Object moduleRequest, + final ModuleResponseType moduleResponseType, + final long simulatedResponseDelay) { + logRequestBody(moduleRequest); + String moduleResponseContent = ""; + String moduleSetTag = extractModuleSetTagFromRequest(moduleRequest); + + moduleSetTag = (!isModuleSetTagNullOrEmpty(moduleSetTag) + && MODULE_SET_TAGS.contains(moduleSetTag)) ? moduleSetTag : DEFAULT_TAG; + + if (MODULE_RESOURCE_RESPONSE == moduleResponseType) { + moduleResponseContent = yangModuleFactory.getModuleResourcesJson(moduleSetTag); + } else { + moduleResponseContent = yangModuleFactory.getModuleReferencesJson(moduleSetTag); + } + + delay(simulatedResponseDelay); + return ResponseEntity.ok(moduleResponseContent); + } + + private String extractModuleSetTagFromRequest(final Object moduleReferencesRequest) { + final JsonNode rootNode = objectMapper.valueToTree(moduleReferencesRequest); + return rootNode.path("moduleSetTag").asText(null); + } + + private boolean isModuleSetTagNullOrEmpty(final String moduleSetTag) { + return moduleSetTag == null || moduleSetTag.trim().isEmpty(); + } + + private void logRequestBody(final Object request) { + try { + log.info("Incoming DMI request body: {}", objectMapper.writeValueAsString(request)); + } catch (final JsonProcessingException jsonProcessingException) { + log.info("Unable to parse DMI request to json string"); + } + } + + private String getPassthroughOperationType(final String requestBody) { + try { + final JsonNode rootNode = objectMapper.readTree(requestBody); + return rootNode.path("operation").asText(); + } catch (final JsonProcessingException jsonProcessingException) { + log.error("Invalid JSON format. cause : {}", jsonProcessingException.getMessage()); + } + return DEFAULT_PASSTHROUGH_OPERATION; + } + + private void delay(final long milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (final InterruptedException e) { + log.error("Thread sleep interrupted: {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } +}
\ No newline at end of file diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcess.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcess.java new file mode 100644 index 00000000..8444dd58 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcess.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.controller.aop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to mark methods that require initial processing for module set tag. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ModuleInitialProcess { +}
\ No newline at end of file diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcessAspect.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcessAspect.java new file mode 100644 index 00000000..2cecc145 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/aop/ModuleInitialProcessAspect.java @@ -0,0 +1,107 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.controller.aop; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + + +/** + * Aspect to handle initial processing for methods annotated with @ModuleInitialProcess. + */ +@Slf4j +@Aspect +@Component +@RequiredArgsConstructor +public class ModuleInitialProcessAspect { + + private final ObjectMapper objectMapper; + private static final Map<String, Long> firstRequestTimePerModuleSetTag = new ConcurrentHashMap<>(); + + @Value("${delay.module-initial-processing-delay-ms:120000}") + private long moduleInitialProcessingDelayMs; + + /** + * Around advice to handle methods annotated with @ModuleInitialProcess. + * + * @param proceedingJoinPoint the join point representing the method execution + * @param moduleInitialProcess the annotation containing the module set tag + * @return the result of the method execution or a ResponseEntity indicating that the service is unavailable + */ + @Around("@annotation(moduleInitialProcess)") + public Object handleModuleInitialProcess(final ProceedingJoinPoint proceedingJoinPoint, + final ModuleInitialProcess moduleInitialProcess) throws Throwable { + log.debug("Aspect invoked for method: {}", proceedingJoinPoint.getSignature()); + final Object moduleRequest = proceedingJoinPoint.getArgs()[1]; + final String moduleSetTag = extractModuleSetTagFromRequest(moduleRequest); + + if (isModuleSetTagEmptyOrInvalid(moduleSetTag)) { + log.debug("Received request with an empty or null moduleSetTag. Returning default processing."); + return proceedingJoinPoint.proceed(); + } + + final long firstRequestTimestamp = getFirstRequestTimestamp(moduleSetTag); + final long currentTimestamp = System.currentTimeMillis(); + + if (isInitialProcessingCompleted(currentTimestamp, firstRequestTimestamp)) { + log.debug("Initial processing for moduleSetTag '{}' is completed.", moduleSetTag); + return proceedingJoinPoint.proceed(); + } + + final long remainingProcessingTime = calculateRemainingProcessingTime(currentTimestamp, firstRequestTimestamp); + log.info("Initial processing for moduleSetTag '{}' is still active. Returning HTTP 503. Remaining time: {} ms.", + moduleSetTag, remainingProcessingTime); + return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build(); + } + + private String extractModuleSetTagFromRequest(final Object moduleRequest) { + final JsonNode rootNode = objectMapper.valueToTree(moduleRequest); + return rootNode.path("moduleSetTag").asText(null); + } + + private boolean isModuleSetTagEmptyOrInvalid(final String moduleSetTag) { + return moduleSetTag == null || moduleSetTag.trim().isEmpty(); + } + + private long getFirstRequestTimestamp(final String moduleSetTag) { + return firstRequestTimePerModuleSetTag + .computeIfAbsent(moduleSetTag, firstRequestTime -> System.currentTimeMillis()); + } + + private boolean isInitialProcessingCompleted(final long currentTimestamp, final long firstRequestTimestamp) { + return currentTimestamp - firstRequestTimestamp >= moduleInitialProcessingDelayMs; + } + + private long calculateRemainingProcessingTime(final long currentTimestamp, final long firstRequestTimestamp) { + return moduleInitialProcessingDelayMs - (currentTimestamp - firstRequestTimestamp); + } +} diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DataOperationRequest.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DataOperationRequest.java new file mode 100644 index 00000000..41077493 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DataOperationRequest.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.data.operational; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Setter +@Getter +public class DataOperationRequest { + private String operation; + private String operationId; + private String datastore; + private String options; + private String resourceIdentifier; + private List<DmiOperationCmHandle> cmHandles = new ArrayList<>(); +} diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiDataOperationRequest.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiDataOperationRequest.java new file mode 100644 index 00000000..ae78c033 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiDataOperationRequest.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.data.operational; + +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class DmiDataOperationRequest { + + private List<DataOperationRequest> operations; + +} diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiOperationCmHandle.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiOperationCmHandle.java new file mode 100644 index 00000000..5cb24bc3 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/data/operational/DmiOperationCmHandle.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.data.operational; + +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class DmiOperationCmHandle { + private String id; + private Map<String, String> cmHandleProperties = new HashMap<>(); + private String moduleSetTag; +} diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReference.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReference.java new file mode 100644 index 00000000..5b1c30e2 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReference.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.module; + +public record ModuleReference ( + String moduleName, + String revision +){ } diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReferences.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReferences.java new file mode 100644 index 00000000..36516452 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReferences.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.module; + +import java.util.List; + +public record ModuleReferences( + List<ModuleReference> schemas +) { } diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleResource.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleResource.java new file mode 100644 index 00000000..f4decb8d --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleResource.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.model.module; + +public record ModuleResource ( + String moduleName, + String revision, + String yangSource +) { } diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/service/YangModuleFactory.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/service/YangModuleFactory.java new file mode 100644 index 00000000..42459222 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/service/YangModuleFactory.java @@ -0,0 +1,161 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.PostConstruct; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.dmi.rest.stub.model.module.ModuleReference; +import org.onap.cps.ncmp.dmi.rest.stub.model.module.ModuleReferences; +import org.onap.cps.ncmp.dmi.rest.stub.model.module.ModuleResource; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class YangModuleFactory { + + private static final int TARGET_FILE_SIZE_IN_KB = 32 * 1024; + private static final List<String> MODULE_SET_TAGS = generateTags(); + private static final String DEFAULT_TAG = "tagDefault"; + private static final int NUMBER_OF_MODULES_PER_MODULE_SET = 200; + private static final int NUMBER_OF_MODULES_NOT_IN_MODULE_SET = 10; + private static final String SERIALIZATION_ERROR = "Error serializing {}: {}"; + private static final String MODULE_TEMPLATE = """ + module <MODULE_NAME> { + yang-version 1.1; + namespace "org:onap:cps:test:<MODULE_NAME>"; + prefix tree; + revision "<MODULE_REVISION>" { + description "<DESCRIPTION>"; + } + container tree { + list branch { + key "name"; + leaf name { + type string; + } + } + } + } + """; + + private final ObjectMapper objectMapper; + private final Map<String, String> moduleReferencesJsonMap = new HashMap<>(); + private final Map<String, String> moduleResourcesJsonMap = new HashMap<>(); + + @PostConstruct + private void initializeModuleJsonStrings() { + MODULE_SET_TAGS.forEach(tag -> { + moduleReferencesJsonMap.put(tag, createModuleReferencesJson(tag, NUMBER_OF_MODULES_PER_MODULE_SET)); + moduleResourcesJsonMap.put(tag, createModuleResourcesJson(tag, NUMBER_OF_MODULES_PER_MODULE_SET)); + }); + + // Initialize default tag + moduleReferencesJsonMap.put(DEFAULT_TAG, + createModuleReferencesJson(DEFAULT_TAG, NUMBER_OF_MODULES_NOT_IN_MODULE_SET)); + moduleResourcesJsonMap.put(DEFAULT_TAG, + createModuleResourcesJson(DEFAULT_TAG, NUMBER_OF_MODULES_NOT_IN_MODULE_SET)); + } + + /** + * Retrieves the JSON representation of module references for the given tag. + * + * @param tag the tag identifying the set of module references + * @return the JSON string of module references for the specified tag, or the default tag if not found + */ + public String getModuleReferencesJson(final String tag) { + return moduleReferencesJsonMap.getOrDefault(tag, moduleReferencesJsonMap.get(DEFAULT_TAG)); + } + + /** + * Retrieves the JSON representation of module resources for the given tag. + * + * @param tag the tag identifying the set of module resources + * @return the JSON string of module resources for the specified tag, or the default tag if not found + */ + public String getModuleResourcesJson(final String tag) { + return moduleResourcesJsonMap.getOrDefault(tag, moduleResourcesJsonMap.get(DEFAULT_TAG)); + } + + /** + * Generates a list of tags from 'A' to 'E'. + * + * @return a list of tags in the format "tagX" where X is each character from 'A' to 'E' + */ + public static List<String> generateTags() { + final List<String> tags = new ArrayList<>(5); + for (char currentChar = 'A'; currentChar <= 'E'; currentChar++) { + tags.add("tag" + currentChar); + } + return tags; + } + + private String createModuleReferencesJson(final String tag, final int numberOfModules) { + final List<ModuleReference> moduleReferencesList = new ArrayList<>(numberOfModules); + final String moduleRevision = generateModuleRevision(tag); + for (int i = 0; i < numberOfModules; i++) { + moduleReferencesList.add(new ModuleReference("module" + i, moduleRevision)); + } + return serializeToJson(new ModuleReferences(moduleReferencesList), "ModuleReferences"); + } + + private String createModuleResourcesJson(final String tag, final int numberOfModules) { + final List<ModuleResource> moduleResourceList = new ArrayList<>(numberOfModules); + final String moduleRevision = generateModuleRevision(tag); + for (int i = 0; i < numberOfModules; i++) { + final String moduleName = "module" + i; + final String yangSource = generateYangSource(moduleName, moduleRevision); + moduleResourceList.add(new ModuleResource(moduleName, moduleRevision, yangSource)); + } + return serializeToJson(moduleResourceList, "ModuleResources"); + } + + private String serializeToJson(final Object objectToSerialize, final String objectType) { + try { + return objectMapper.writeValueAsString(objectToSerialize); + } catch (final JsonProcessingException jsonProcessingException) { + log.error(SERIALIZATION_ERROR, objectType, jsonProcessingException.getMessage()); + return null; + } + } + + private String generateModuleRevision(final String tag) { + // set tagIndex to 0 for the default tag, otherwise set it to the index of the tag in the list + final int tagIndex = tag.equals(DEFAULT_TAG) ? 0 : MODULE_SET_TAGS.indexOf(tag); + return LocalDate.of(2024, tagIndex + 1, tagIndex + 1).toString(); + } + + private static String generateYangSource(final String moduleName, final String moduleRevision) { + final int paddingSize = TARGET_FILE_SIZE_IN_KB - MODULE_TEMPLATE.length(); + final String padding = "*".repeat(Math.max(0, paddingSize)); + return MODULE_TEMPLATE.replaceAll("<MODULE_NAME>", moduleName) + .replace("<MODULE_REVISION>", moduleRevision) + .replace("<DESCRIPTION>", padding); + } +}
\ No newline at end of file diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/EventDateTimeFormatter.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/EventDateTimeFormatter.java new file mode 100644 index 00000000..7b6d1ab7 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/EventDateTimeFormatter.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.utils; + +import java.time.OffsetDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import org.apache.commons.lang3.StringUtils; + +public interface EventDateTimeFormatter { + + String ISO_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_PATTERN); + + /** + * Gets current date time. + * + * @return the current date time + */ + static String getCurrentIsoFormattedDateTime() { + return ZonedDateTime.now().format(ISO_TIMESTAMP_FORMATTER); + } + + static OffsetDateTime toIsoOffsetDateTime(final String dateTimestampAsString) { + return StringUtils.isNotBlank(dateTimestampAsString) + ? OffsetDateTime.parse(dateTimestampAsString, ISO_TIMESTAMP_FORMATTER) : null; + } +} diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ModuleResponseType.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ModuleResponseType.java new file mode 100644 index 00000000..9c5482d1 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ModuleResponseType.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.utils; + +public enum ModuleResponseType { + MODULE_REFERENCE_RESPONSE, + MODULE_RESOURCE_RESPONSE; +} + diff --git a/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ResourceFileReaderUtil.java b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ResourceFileReaderUtil.java new file mode 100644 index 00000000..0d2adee4 --- /dev/null +++ b/dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ResourceFileReaderUtil.java @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.rest.stub.utils; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.Resource; +import org.springframework.util.StreamUtils; + +/** + * Common convenience methods for reading resource file content. + */ +@Slf4j +public class ResourceFileReaderUtil { + + /** + * Converts a resource file content into string. + * + * @param fileClasspath to name of the file in test/resources + * @return the content of the file as a String + * @throws IOException when there is an IO issue + */ + public static String getResourceFileContent(final Resource fileClasspath) { + String fileContent = null; + try { + fileContent = StreamUtils.copyToString(fileClasspath.getInputStream(), StandardCharsets.UTF_8); + } catch (final IOException ioException) { + log.debug("unable to read resource file content. cause : {}", ioException.getMessage()); + } + return fileContent; + } +} |