diff options
author | halil.cakal <halil.cakal@est.tech> | 2024-10-11 17:22:06 +0100 |
---|---|---|
committer | halil.cakal <halil.cakal@est.tech> | 2024-10-25 11:51:22 +0100 |
commit | 62abb22f7c495892afc45d72b8994112ebf1dfb5 (patch) | |
tree | 3c525bd27f4c8aefda48efb18877e29efb4a921d /dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java | |
parent | 1e1f49f7947271b15fa9b096a022e827d952a043 (diff) |
DMI simulator serving yang modules dynamically
- all modules and module references are created once,
then are served as requested
- 5 module-set-tag supported from tagA to tagE
- 200 yang modules per module-set-tag
- module sizes are fixed at 32KiB each
- the average response size is 200 * 32KiB = 6.4MiB
for each
Issue-ID: CPS-2410
Change-Id: Ie7ac73b8c0bd464b114a8d76104db4b569ae36f4
Signed-off-by: halil.cakal <halil.cakal@est.tech>
Diffstat (limited to 'dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java')
6 files changed, 298 insertions, 21 deletions
diff --git a/dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java b/dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java index 85d454b2..cf18f239 100644 --- a/dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java +++ b/dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java @@ -20,6 +20,9 @@ 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; @@ -43,14 +46,15 @@ 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.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -73,11 +77,17 @@ import org.springframework.web.bind.annotation.RestController; public class DmiRestStubController { private static final String DEFAULT_PASSTHROUGH_OPERATION = "read"; - private static final String dataOperationEventType = "org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent"; + 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}") @@ -88,7 +98,6 @@ public class DmiRestStubController { private long readDataForCmHandleDelayMs; @Value("${delay.write-data-for-cm-handle-delay-ms}") private long writeDataForCmHandleDelayMs; - private final AtomicInteger subJobWriteRequestCounter = new AtomicInteger(); /** * This code defines a REST API endpoint for adding new the module set tag mapping. The endpoint receives the @@ -163,7 +172,7 @@ public class DmiRestStubController { @ModuleInitialProcess public ResponseEntity<String> getModuleReferences(@PathVariable("cmHandleId") final String cmHandleId, @RequestBody final Object moduleReferencesRequest) { - return processModuleRequest(moduleReferencesRequest, "ModuleResponse.json", moduleReferencesDelayMs); + return processModuleRequest(moduleReferencesRequest, MODULE_REFERENCE_RESPONSE, moduleReferencesDelayMs); } /** @@ -179,7 +188,7 @@ public class DmiRestStubController { public ResponseEntity<String> getModuleResources( @PathVariable("cmHandleId") final String cmHandleId, @RequestBody final Object moduleResourcesReadRequest) { - return processModuleRequest(moduleResourcesReadRequest, "ModuleResourcesResponse.json", moduleResourcesDelayMs); + return processModuleRequest(moduleResourcesReadRequest, MODULE_RESOURCE_RESPONSE, moduleResourcesDelayMs); } /** @@ -308,8 +317,8 @@ public class DmiRestStubController { cloudEvent = CloudEventBuilder.v1() .withId(UUID.randomUUID().toString()) .withSource(URI.create("DMI")) - .withType(dataOperationEventType) - .withDataSchema(URI.create("urn:cps:" + dataOperationEventType + ":1.0.0")) + .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)) @@ -350,11 +359,22 @@ public class DmiRestStubController { return dataOperationEvent; } - private ResponseEntity<String> processModuleRequest(final Object moduleRequest, final String responseFileName, + private ResponseEntity<String> processModuleRequest(final Object moduleRequest, + final ModuleResponseType moduleResponseType, final long simulatedResponseDelay) { - final String moduleSetTag = extractModuleSetTagFromRequest(moduleRequest); logRequestBody(moduleRequest); - final String moduleResponseContent = getModuleResponseContent(moduleSetTag, responseFileName); + 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); } @@ -376,17 +396,6 @@ public class DmiRestStubController { } } - private String getModuleResponseContent(final String moduleSetTag, final String responseFileName) { - final String moduleResponseFilePath = isModuleSetTagNullOrEmpty(moduleSetTag) - ? String.format("module/ietfYang-%s", responseFileName) - : String.format("module/%s-%s", moduleSetTag, responseFileName); - log.info("Using module responses from : {}", moduleResponseFilePath); - - final Resource moduleResponseResource = applicationContext.getResource( - ResourceLoader.CLASSPATH_URL_PREFIX + moduleResponseFilePath); - return ResourceFileReaderUtil.getResourceFileContent(moduleResponseResource); - } - private String getPassthroughOperationType(final String requestBody) { try { final JsonNode rootNode = objectMapper.readTree(requestBody); diff --git a/dmi-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReference.java b/dmi-stub/dmi-plugin-demo-and-csit-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-plugin-demo-and-csit-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-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleReferences.java b/dmi-stub/dmi-plugin-demo-and-csit-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-plugin-demo-and-csit-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-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/model/module/ModuleResource.java b/dmi-stub/dmi-plugin-demo-and-csit-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-plugin-demo-and-csit-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-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/service/YangModuleFactory.java b/dmi-stub/dmi-plugin-demo-and-csit-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-plugin-demo-and-csit-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-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/ModuleResponseType.java b/dmi-stub/dmi-plugin-demo-and-csit-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-plugin-demo-and-csit-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; +} + |