Enabling Code Formatter
[ccsdk/cds.git] / ms / blueprintsprocessor / application / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / uat / utils / UatDefinition.kt
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.ccsdk.cds.blueprintsprocessor.uat.utils
21
22 import com.fasterxml.jackson.annotation.JsonAlias
23 import com.fasterxml.jackson.annotation.JsonInclude
24 import com.fasterxml.jackson.databind.JsonNode
25 import com.fasterxml.jackson.databind.ObjectMapper
26 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
27 import com.fasterxml.jackson.module.kotlin.convertValue
28 import org.yaml.snakeyaml.DumperOptions
29 import org.yaml.snakeyaml.Yaml
30 import org.yaml.snakeyaml.nodes.Tag
31
32 @JsonInclude(JsonInclude.Include.NON_EMPTY)
33 data class ProcessDefinition(
34     val name: String,
35     val request: JsonNode,
36     val expectedResponse: JsonNode? = null,
37     val responseNormalizerSpec: JsonNode? = null
38 )
39
40 @JsonInclude(JsonInclude.Include.NON_EMPTY)
41 data class RequestDefinition(
42     val method: String,
43     @JsonDeserialize(using = PathDeserializer::class)
44     val path: String,
45     val headers: Map<String, String> = emptyMap(),
46     val body: JsonNode? = null
47 )
48
49 @JsonInclude(JsonInclude.Include.NON_EMPTY)
50 data class ResponseDefinition(
51     val status: Int = 200,
52     val body: JsonNode? = null,
53     val headers: Map<String, String> = mapOf("Content-Type" to "application/json")
54 ) {
55
56     companion object {
57
58         val DEFAULT_RESPONSES = listOf(ResponseDefinition())
59     }
60 }
61
62 @JsonInclude(JsonInclude.Include.NON_EMPTY)
63 class ExpectationDefinition(
64     val request: RequestDefinition,
65     response: ResponseDefinition?,
66     responses: List<ResponseDefinition>? = null,
67     val times: String = ">= 1"
68 ) {
69
70     val responses: List<ResponseDefinition> = resolveOneOrMany(response, responses, ResponseDefinition.DEFAULT_RESPONSES)
71
72     companion object {
73
74         fun <T> resolveOneOrMany(one: T?, many: List<T>?, defaultMany: List<T>): List<T> = when {
75             many != null -> many
76             one != null -> listOf(one)
77             else -> defaultMany
78         }
79     }
80 }
81
82 @JsonInclude(JsonInclude.Include.NON_EMPTY)
83 data class ServiceDefinition(val selector: String, val expectations: List<ExpectationDefinition>)
84
85 @JsonInclude(JsonInclude.Include.NON_EMPTY)
86 data class UatDefinition(
87     val processes: List<ProcessDefinition>,
88     @JsonAlias("external-services")
89     val externalServices: List<ServiceDefinition> = emptyList()
90 ) {
91
92     fun dump(mapper: ObjectMapper, excludedProperties: List<String> = emptyList()): String {
93         val uatAsMap: Map<String, Any> = mapper.convertValue(this)
94         if (excludedProperties.isNotEmpty()) {
95             pruneTree(uatAsMap, excludedProperties)
96         }
97         return Yaml().dumpAs(uatAsMap, Tag.MAP, DumperOptions.FlowStyle.BLOCK)
98     }
99
100     fun toBare(): UatDefinition {
101         val newProcesses = processes.map { p ->
102             ProcessDefinition(p.name, p.request, null, p.responseNormalizerSpec)
103         }
104         return UatDefinition(newProcesses)
105     }
106
107     private fun pruneTree(node: Any?, excludedProperties: List<String>) {
108         when (node) {
109             is MutableMap<*, *> -> {
110                 excludedProperties.forEach { key -> node.remove(key) }
111                 node.forEach { (_, value) -> pruneTree(value, excludedProperties) }
112             }
113             is List<*> -> node.forEach { value -> pruneTree(value, excludedProperties) }
114         }
115     }
116
117     companion object {
118
119         fun load(mapper: ObjectMapper, spec: String): UatDefinition =
120             mapper.convertValue(Yaml().load(spec), UatDefinition::class.java)
121     }
122 }