aboutsummaryrefslogtreecommitdiffstats
path: root/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
blob: 6676cb74c2ce83eaa23a16f167a745942890fc87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 *  ============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.integration.base

import static org.onap.cps.integration.base.CpsIntegrationSpecBase.readResourceDataFile

import org.springframework.http.HttpHeaders
import java.util.regex.Matcher
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType

/**
 * This class simulates responses from the DMI server in NCMP integration tests.
 *
 * It is to be used with a MockWebServer, using mockWebServer.setDispatcher(new DmiDispatcher()).
 *
 * It currently implements the following endpoints:
 * - /actuator/health: healthcheck endpoint that responds with 200 OK / {"status":"UP"}
 * - /dmi/v1/ch/{cmHandleId}/modules: returns module references for a CM handle
 * - /dmi/v1/ch/{cmHandleId}/moduleResources: returns modules resources for a CM handle
 *
 * The module resource/reference responses are generated based on the module names in the map moduleNamesPerCmHandleId.
 * To configure the DMI so that CM handle 'ch-1' will have modules 'M1' and 'M2', you may use:
 *   dmiDispatcher.moduleNamesPerCmHandleId.put('ch-1', ['M1', 'M2']);
 *
 * To simulate the DMI not being available, the boolean isAvailable may be set to false, in which case the mock server
 * will always respond with 503 Service Unavailable.
 */
class DmiDispatcher extends Dispatcher {

    static final MODULE_REFERENCES_RESPONSE_TEMPLATE = readResourceDataFile('mock-dmi-responses/moduleReferencesTemplate.json')
    static final MODULE_RESOURCES_RESPONSE_TEMPLATE = readResourceDataFile('mock-dmi-responses/moduleResourcesTemplate.json')

    def isAvailable = true

    Map<String, List<String>> moduleNamesPerCmHandleId = [:]

    @Override
    MockResponse dispatch(RecordedRequest request) {
        if (!isAvailable) {
            return new MockResponse().setResponseCode(HttpStatus.SERVICE_UNAVAILABLE.value())
        }
        switch (request.path) {
            case ~/^\/dmi\/v1\/ch\/(.*)\/modules$/:
                def cmHandleId = Matcher.lastMatcher[0][1]
                return getModuleReferencesResponse(cmHandleId)

            case ~/^\/dmi\/v1\/ch\/(.*)\/moduleResources$/:
                def cmHandleId = Matcher.lastMatcher[0][1]
                return getModuleResourcesResponse(cmHandleId)

            default:
                throw new IllegalArgumentException('Mock DMI does not handle path ' + request.path)
        }
    }

    private getModuleReferencesResponse(cmHandleId) {
        def moduleReferences = '{"schemas":[' + getModuleNamesForCmHandle(cmHandleId).collect {
            MODULE_REFERENCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
        }.join(',') + ']}'
        return mockOkResponseWithBody(moduleReferences)
    }

    private getModuleResourcesResponse(cmHandleId) {
        def moduleResources = '[' + getModuleNamesForCmHandle(cmHandleId).collect {
            MODULE_RESOURCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
        }.join(',') + ']'
        return mockOkResponseWithBody(moduleResources)
    }

    private getModuleNamesForCmHandle(cmHandleId) {
        if (!moduleNamesPerCmHandleId.containsKey(cmHandleId)) {
            throw new IllegalArgumentException('Mock DMI has no modules configured for ' + cmHandleId)
        }
        return moduleNamesPerCmHandleId.get(cmHandleId)
    }

    private static mockOkResponseWithBody(responseBody) {
        return new MockResponse()
                .setResponseCode(HttpStatus.OK.value())
                .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
                .setBody(responseBody)
    }
}