Include delay in provmns requests for k6 testing 73/143073/4
authorseanbeirne <sean.beirne@est.tech>
Wed, 28 Jan 2026 09:35:17 +0000 (09:35 +0000)
committerseanbeirne <sean.beirne@est.tech>
Tue, 3 Feb 2026 11:32:04 +0000 (11:32 +0000)
- extracted delay method to common sleeper class
- Changed /v1/data delay from write to read as per NCMP code it will
  only ever be read once it reaches the DMI

Issue-ID: CPS-3133
Change-Id: I43f61549ea16c76ae7657cfdb5b58ea1eeb25b58
Signed-off-by: seanbeirne <sean.beirne@est.tech>
dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java
dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/ProvMnsStubController.java
dmi-stub/dmi-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/utils/Sleeper.java
dmi-stub/dmi-stub-service/src/main/resources/application.yml

index 2712985..34f0ce6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
+ *  Copyright (C) 2023-2026 OpenInfra Foundation Europe. All rights reserved.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -50,6 +50,7 @@ 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.dmi.rest.stub.utils.Sleeper;
 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;
@@ -89,6 +90,7 @@ public class DmiRestStubController {
     private final ApplicationContext applicationContext;
     private final AtomicInteger subJobWriteRequestCounter = new AtomicInteger();
     private final YangModuleFactory yangModuleFactory;
+    private final Sleeper sleeper;
 
     @Value("${app.ncmp.async-m2m.topic}")
     private String ncmpAsyncM2mTopic;
@@ -224,9 +226,9 @@ public class DmiRestStubController {
         log.debug("DMI AUTH HEADER: {}", authorization);
         final String passthroughOperationType = getPassthroughOperationType(requestBody);
         if (passthroughOperationType.equals("read")) {
-            delay(readDataForCmHandleDelayMs);
+            sleeper.delay(readDataForCmHandleDelayMs);
         } else {
-            delay(writeDataForCmHandleDelayMs);
+            sleeper.delay(writeDataForCmHandleDelayMs);
         }
         log.debug("Logging request body {}", requestBody);
 
@@ -248,7 +250,7 @@ public class DmiRestStubController {
             @RequestParam(value = "topic") final String topic,
             @RequestParam(value = "requestId") final String requestId,
             @RequestBody final DmiDataOperationRequest dmiDataOperationRequest) {
-        delay(writeDataForCmHandleDelayMs);
+        sleeper.delay(readDataForCmHandleDelayMs);
         try {
             log.info("Request received from the NCMP to DMI Plugin: {}",
                     objectMapper.writeValueAsString(dmiDataOperationRequest));
@@ -390,7 +392,7 @@ public class DmiRestStubController {
             moduleResponseContent = yangModuleFactory.getModuleReferencesJson(moduleSetTag);
         }
 
-        delay(simulatedResponseDelay);
+        sleeper.delay(simulatedResponseDelay);
         return ResponseEntity.ok(moduleResponseContent);
     }
 
@@ -421,15 +423,6 @@ public class DmiRestStubController {
         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();
-        }
-    }
-
     private static String getCompositeNetworkId(final String cmHandleId) {
         final String servletUri = ServletUriComponentsBuilder
             .fromCurrentContextPath()    // scheme://host:port
index dffccb9..20e0094 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2025 OpenInfra Foundation Europe
+ *  Copyright (C) 2025-2026 OpenInfra Foundation Europe
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@ import org.onap.cps.ncmp.dmi.provmns.model.Resource;
 import org.onap.cps.ncmp.dmi.provmns.model.ResourceOneOf;
 import org.onap.cps.ncmp.dmi.provmns.model.Scope;
 import org.onap.cps.ncmp.dmi.rest.stub.utils.Sleeper;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -65,6 +66,11 @@ public class ProvMnsStubController implements ProvMnS {
         dummyResource.setAttributes(Collections.singletonMap("dummyAttribute", "dummy value"));
     }
 
+    @Value("${delay.provmns-read-delay-ms}")
+    private long provMnSReadDelayMs;
+    @Value("${delay.provmns-write-delay-ms}")
+    private long provMnSWriteDelayMs;
+
     /**
      * Replaces a complete single resource or creates it if it does not exist.
      *
@@ -80,7 +86,8 @@ public class ProvMnsStubController implements ProvMnS {
         stubResource.setObjectClass("ObjectClass set by Stub");
         stubResource.setObjectInstance("ObjectInstance set by Stub");
         stubResource.setAttributes("Attribute set by Stub");
-        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest);
+        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest,
+            provMnSWriteDelayMs);
         return optionalResponseEntity.orElseGet(() -> new ResponseEntity<>(stubResource, HttpStatus.OK));
     }
 
@@ -111,7 +118,8 @@ public class ProvMnsStubController implements ProvMnS {
                                            final ClassNameIdGetDataNodeSelectorParameter dataNodeSelector) {
         log.info("getMoi: scope: {}, filter: {}, attributes: {}, fields: {}, dataNodeSelector: {}",
                 scope, filter, attributes, fields, dataNodeSelector);
-        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest);
+        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest,
+            provMnSReadDelayMs);
         return optionalResponseEntity.orElseGet(() -> new ResponseEntity<>(dummyResource, HttpStatus.OK));
     }
 
@@ -129,7 +137,8 @@ public class ProvMnsStubController implements ProvMnS {
         final List<PatchItem> stubResponse = new ArrayList<>();
         stubResponse.add(new PatchItem(PatchOperation.ADD, "/path=setByStub"));
         stubResponse.add(new PatchItem(PatchOperation.REMOVE, "/path=alsoSetByStub"));
-        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest);
+        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest,
+            provMnSWriteDelayMs);
         return optionalResponseEntity.orElseGet(() -> new ResponseEntity<>(stubResponse, HttpStatus.OK));
     }
 
@@ -142,11 +151,13 @@ public class ProvMnsStubController implements ProvMnS {
     @Override
     public ResponseEntity<Object> deleteMoi(final HttpServletRequest httpServletRequest) {
         log.info("deleteMoi:");
-        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest);
+        final Optional<ResponseEntity<Object>> optionalResponseEntity = simulate(httpServletRequest,
+            provMnSWriteDelayMs);
         return optionalResponseEntity.orElseGet(() -> new ResponseEntity<>(HttpStatus.OK));
     }
 
-    private Optional<ResponseEntity<Object>> simulate(final HttpServletRequest httpServletRequest) {
+    private Optional<ResponseEntity<Object>> simulate(final HttpServletRequest httpServletRequest,
+                                                      final long defaultDelay) {
         Matcher matcher = PATTERN_SIMULATION.matcher(httpServletRequest.getRequestURI());
         if (matcher.find()) {
             final String simulation = matcher.group(1);
@@ -158,6 +169,8 @@ public class ProvMnsStubController implements ProvMnS {
             if (matcher.matches()) {
                 return Optional.of(createErrorRsponseEntity(Integer.parseInt(matcher.group(1))));
             }
+        } else {
+            sleeper.delay(defaultDelay);
         }
         return Optional.empty();
     }
index c100e31..5a2dfd0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2025 OpenInfra Foundation Europe
+ *  Copyright (C) 2025-2026 OpenInfra Foundation Europe
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
 package org.onap.cps.ncmp.dmi.rest.stub.utils;
 
 import java.util.concurrent.TimeUnit;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
 /**
  * This class is to extract out sleep functionality so the interrupted exception handling can
  * be covered with a test (e.g. using spy on Sleeper) and help to get too 100% code coverage.
  */
+@Slf4j
 @Component
 public class Sleeper {
+    /**
+     * Pauses execution for the specified duration in seconds.
+     *
+     * @param durationInSeconds the duration to sleep in seconds
+     * @throws InterruptedException if the thread is interrupted while sleeping
+     */
     public void haveALittleRest(final int durationInSeconds) throws InterruptedException {
         TimeUnit.SECONDS.sleep(durationInSeconds);
     }
+
+    /**
+     * Pauses execution for the specified duration in milliseconds.
+     * Handles InterruptedException internally by logging and restoring interrupt status.
+     *
+     * @param milliseconds the duration to sleep in milliseconds
+     */
+    public void delay(final long milliseconds) {
+        try {
+            Thread.sleep(milliseconds);
+        } catch (final InterruptedException e) {
+            log.error("Thread sleep interrupted: {}", e.getMessage());
+            Thread.currentThread().interrupt();
+        }
+    }
 }
index 65a1bec..3a0a1aa 100644 (file)
@@ -64,4 +64,6 @@ delay:
     module-initial-processing-delay-ms: ${MODULE_INITIAL_PROCESSING_DELAY_MS:120000}
     read-data-for-cm-handle-delay-ms: ${READ_DATA_FOR_CM_HANDLE_DELAY_MS:300}
     write-data-for-cm-handle-delay-ms: ${WRITE_DATA_FOR_CM_HANDLE_DELAY_MS:670}
+    provmns-read-delay-ms: ${PROVMNS_READ_DELAY_MS:300}
+    provmns-write-delay-ms: ${PROVMNS_WRITE_DELAY_MS:670}