2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 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.integration.base
23 import static org.onap.cps.integration.base.CpsIntegrationSpecBase.readResourceDataFile
25 import org.springframework.http.HttpHeaders
26 import java.util.regex.Matcher
27 import okhttp3.mockwebserver.Dispatcher
28 import okhttp3.mockwebserver.MockResponse
29 import okhttp3.mockwebserver.RecordedRequest
30 import org.springframework.http.HttpStatus
31 import org.springframework.http.MediaType
34 * This class simulates responses from the DMI server in NCMP integration tests.
36 * It is to be used with a MockWebServer, using mockWebServer.setDispatcher(new DmiDispatcher()).
38 * It currently implements the following endpoints:
39 * - /actuator/health: healthcheck endpoint that responds with 200 OK / {"status":"UP"}
40 * - /dmi/v1/ch/{cmHandleId}/modules: returns module references for a CM handle
41 * - /dmi/v1/ch/{cmHandleId}/moduleResources: returns modules resources for a CM handle
43 * The module resource/reference responses are generated based on the module names in the map moduleNamesPerCmHandleId.
44 * To configure the DMI so that CM handle 'ch-1' will have modules 'M1' and 'M2', you may use:
45 * dmiDispatcher.moduleNamesPerCmHandleId.put('ch-1', ['M1', 'M2']);
47 * To simulate the DMI not being available, the boolean isAvailable may be set to false, in which case the mock server
48 * will always respond with 503 Service Unavailable.
50 class DmiDispatcher extends Dispatcher {
52 static final MODULE_REFERENCES_RESPONSE_TEMPLATE = readResourceDataFile('mock-dmi-responses/moduleReferencesTemplate.json')
53 static final MODULE_RESOURCES_RESPONSE_TEMPLATE = readResourceDataFile('mock-dmi-responses/moduleResourcesTemplate.json')
55 def isAvailable = true
57 Map<String, List<String>> moduleNamesPerCmHandleId = [:]
60 MockResponse dispatch(RecordedRequest request) {
62 return new MockResponse().setResponseCode(HttpStatus.SERVICE_UNAVAILABLE.value())
64 switch (request.path) {
65 case ~/^\/dmi\/v1\/ch\/(.*)\/modules$/:
66 def cmHandleId = Matcher.lastMatcher[0][1]
67 return getModuleReferencesResponse(cmHandleId)
69 case ~/^\/dmi\/v1\/ch\/(.*)\/moduleResources$/:
70 def cmHandleId = Matcher.lastMatcher[0][1]
71 return getModuleResourcesResponse(cmHandleId)
74 throw new IllegalArgumentException('Mock DMI does not handle path ' + request.path)
78 private getModuleReferencesResponse(cmHandleId) {
79 def moduleReferences = '{"schemas":[' + getModuleNamesForCmHandle(cmHandleId).collect {
80 MODULE_REFERENCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
82 return mockOkResponseWithBody(moduleReferences)
85 private getModuleResourcesResponse(cmHandleId) {
86 def moduleResources = '[' + getModuleNamesForCmHandle(cmHandleId).collect {
87 MODULE_RESOURCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
89 return mockOkResponseWithBody(moduleResources)
92 private getModuleNamesForCmHandle(cmHandleId) {
93 if (!moduleNamesPerCmHandleId.containsKey(cmHandleId)) {
94 throw new IllegalArgumentException('Mock DMI has no modules configured for ' + cmHandleId)
96 return moduleNamesPerCmHandleId.get(cmHandleId)
99 private static mockOkResponseWithBody(responseBody) {
100 return new MockResponse()
101 .setResponseCode(HttpStatus.OK.value())
102 .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
103 .setBody(responseBody)