From: danielhanrahan Date: Wed, 29 Nov 2023 18:51:16 +0000 (+0000) Subject: Add passthrough read operation (synchronous) to DMI stub X-Git-Tag: 3.4.5~5^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?p=cps.git;a=commitdiff_plain;h=5543875f9f3a6a772a09c17f7f0b1a3939c78292 Add passthrough read operation (synchronous) to DMI stub - Implement DMI stub endpoint needed for for NCMP passthrough data operation, returning a fixed JSON response and adding delay. POST /dmi/v1/ch/{cmHandleId}/data/ds/{datastoreName} - Add script to measure average overhead for many requests Test results indicate the NCMP adds up to 150ms per request. Issue-ID: CPS-2099 Signed-off-by: danielhanrahan Change-Id: I2aba8285f8a52f3570fc1699a8687caffa9d9c77 --- diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java index d77cbcc96..1819dcc47 100644 --- a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java +++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java @@ -117,6 +117,30 @@ public class DmiRestStubController { return ResponseEntity.ok(moduleResourcesResponseContent); } + /** + * Get 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 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) { + delay(dataForCmHandleDelayMs); + final String sampleJson = ResourceFileReaderUtil.getResourceFileContent(applicationContext.getResource( + ResourceLoader.CLASSPATH_URL_PREFIX + "data/operational/ietf-network-topology-sample-rfc8345.json")); + return ResponseEntity.ok(sampleJson); + } + /** * This method is not implemented for ONAP DMI plugin. * @@ -126,12 +150,10 @@ public class DmiRestStubController { * @return (@ code ResponseEntity) response entity */ @PostMapping("/v1/data") - public ResponseEntity getResourceDataForCmHandleDataOperation(@RequestParam(value = "topic") - final String topic, - @RequestParam(value = "requestId") - final String requestId, - @RequestBody final DmiDataOperationRequest - dmiDataOperationRequest) { + public ResponseEntity getResourceDataForCmHandleDataOperation( + @RequestParam(value = "topic") final String topic, + @RequestParam(value = "requestId") final String requestId, + @RequestBody final DmiDataOperationRequest dmiDataOperationRequest) { delay(dataForCmHandleDelayMs); try { log.info("Request received from the NCMP to DMI Plugin: {}", diff --git a/test-tools/perf-test-ncmp-passthrough-read.sh b/test-tools/perf-test-ncmp-passthrough-read.sh new file mode 100755 index 000000000..21b031ce9 --- /dev/null +++ b/test-tools/perf-test-ncmp-passthrough-read.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# +# Copyright 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. +# + +# This script measures the performance of NCMP data passthrough operations: +# NCMP endpoint tested: /ncmp/v1/ch/{cmHandleId}/data/ds/{datastoreName} + +set -o errexit # Exit on most errors +set -o nounset # Disallow expansion of unset variables +set -o pipefail # Use last non-zero exit code in a pipeline +#set -o xtrace # Uncomment for debugging + +############################ +# Configuration parameters # +############################ +CPS_HOST=localhost +CPS_PORT=8883 +CPS_USERNAME=cpsuser +CPS_PASSWORD=cpsr0cks! +PARALLEL_REQUESTS=12 +WARMUP_REQUESTS=600 +MEASUREMENT_REQUESTS=240 + +SCRIPT_DIR=$(dirname -- "${BASH_SOURCE[0]}") +# Read DMI delay from docker-compose.yml +DMI_DATA_DELAY=$(grep 'DATA_FOR_CM_HANDLE_DELAY_MS:' "$SCRIPT_DIR"/../docker-compose/docker-compose.yml | grep -oE '[0-9]+') + +function cmHandleExists() { + local cmHandleId=$1 + curl --silent --fail --output /dev/null --user "$CPS_USERNAME:$CPS_PASSWORD" --basic "http://$CPS_HOST:$CPS_PORT/ncmp/v1/ch/$cmHandleId" +} + +function failIfCmHandlesNotFound() { + # Just check to see if last needed CM-handle exists + local MAX_NEEDED_CM_HANDLES=$((WARMUP_REQUESTS > MEASUREMENT_REQUESTS ? WARMUP_REQUESTS : MEASUREMENT_REQUESTS)) + local cmHandleId="ch-$MAX_NEEDED_CM_HANDLES" + if ! cmHandleExists "$cmHandleId"; then + echo "ERROR: CM-handles not registered ($cmHandleId not found)" >&2 + echo "Note: this test assumes CM-handles have IDs ch-1, ch-2... ch-$MAX_NEEDED_CM_HANDLES" >&2 + exit 1 + fi +} + +function warnIfLessThan20kCmHandlesFound() { + local cmHandleId='ch-20000' + if ! cmHandleExists "$cmHandleId"; then + echo "WARNING: testing with less than 20,000 CM-handles is not recommended ($cmHandleId not found)" >&2 + fi +} + +function measureAverageResponseTimeInMillis() { + local totalRequests=$1 + curl --show-error --fail --fail-early \ + --output /dev/null --write-out '%{time_total}\n' \ + --parallel --parallel-max $PARALLEL_REQUESTS --parallel-immediate \ + --user "$CPS_USERNAME:$CPS_PASSWORD" --basic \ + --request POST "http://$CPS_HOST:$CPS_PORT/ncmp/v1/ch/ch-[1-$totalRequests]/data/ds/ncmp-datastore%3Apassthrough-operational?resourceIdentifier=x&include-descendants=true" | + awk '{ sum += $1; n++ } END { if (n > 0) print (sum / n) * 1000; }' +} + +# Sanity checks +failIfCmHandlesNotFound +warnIfLessThan20kCmHandlesFound + +# Do JVM warmup +echo "Warming up ($WARMUP_REQUESTS requests, ignoring results)" +measureAverageResponseTimeInMillis "$WARMUP_REQUESTS" > /dev/null + +# Measure performance +echo "Measuring average time of $MEASUREMENT_REQUESTS total requests, sending $PARALLEL_REQUESTS requests in parallel" +ncmpResponseTime=$(measureAverageResponseTimeInMillis "$MEASUREMENT_REQUESTS") +ncmpOverhead=$(echo "$ncmpResponseTime - $DMI_DATA_DELAY" | bc) + +# Report performance +echo "Average response time from NCMP: $ncmpResponseTime ms" +echo "Average response time from DMI: $DMI_DATA_DELAY ms" +echo "NCMP overhead: $ncmpOverhead ms"