2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2018-2019 IBM.
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 package org.onap.ccsdk.cds.controllerblueprints.core.utils
19 import com.fasterxml.jackson.annotation.JsonInclude
20 import com.fasterxml.jackson.databind.JsonNode
21 import com.fasterxml.jackson.databind.SerializationFeature
22 import com.fasterxml.jackson.databind.node.ArrayNode
23 import com.fasterxml.jackson.databind.node.BooleanNode
24 import com.fasterxml.jackson.databind.node.DoubleNode
25 import com.fasterxml.jackson.databind.node.FloatNode
26 import com.fasterxml.jackson.databind.node.IntNode
27 import com.fasterxml.jackson.databind.node.MissingNode
28 import com.fasterxml.jackson.databind.node.NullNode
29 import com.fasterxml.jackson.databind.node.ObjectNode
30 import com.fasterxml.jackson.databind.node.TextNode
31 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
32 import kotlinx.coroutines.Dispatchers
33 import kotlinx.coroutines.runBlocking
34 import kotlinx.coroutines.withContext
35 import org.apache.commons.io.IOUtils
36 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
37 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
38 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
39 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
40 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
41 import org.onap.ccsdk.cds.controllerblueprints.core.readNBText
43 import java.io.InputStream
44 import java.nio.charset.Charset
49 * @author Brinda Santh
55 val objectMapper = jacksonObjectMapper()
57 inline fun <reified T : Any> readValue(content: String): T =
58 objectMapper.readValue(content, T::class.java)
60 inline fun <reified T : Any> readValue(stream: InputStream): T =
61 objectMapper.readValue(stream, T::class.java)
63 fun <T> readValue(content: String, valueType: Class<T>): T? {
64 return objectMapper.readValue(content, valueType)
67 fun <T> readValue(stream: InputStream, valueType: Class<T>): T? {
68 return objectMapper.readValue(stream, valueType)
71 fun <T> readValue(node: JsonNode, valueType: Class<T>): T? {
72 return objectMapper.treeToValue(node, valueType)
75 fun getContent(fileName: String): String = runBlocking {
77 normalizedFile(fileName).readNBText()
78 } catch (e: Exception) {
79 throw BluePrintException("couldn't get file ($fileName) content : ${e.message}")
83 fun getClassPathFileContent(fileName: String): String {
85 withContext(Dispatchers.Default) {
87 JacksonUtils::class.java.classLoader
88 .getResourceAsStream(fileName), Charset.defaultCharset()
94 fun <T> readValueFromFile(fileName: String, valueType: Class<T>): T? {
95 val content: String = getContent(fileName)
96 return readValue(content, valueType)
99 fun <T> readValueFromClassPathFile(fileName: String, valueType: Class<T>): T? {
100 val content: String = getClassPathFileContent(fileName)
101 return readValue(content, valueType)
104 fun objectNodeFromObject(from: kotlin.Any): ObjectNode {
105 return objectMapper.convertValue(from, ObjectNode::class.java)
108 fun jsonNodeFromObject(from: kotlin.Any): JsonNode {
109 return objectMapper.convertValue(from, JsonNode::class.java)
112 fun jsonNodeFromClassPathFile(fileName: String): JsonNode {
113 val content: String = getClassPathFileContent(fileName)
114 return jsonNode(content)
117 fun jsonNodeFromFile(fileName: String): JsonNode {
118 val content: String = getContent(fileName)
119 return jsonNode(content)
122 fun jsonNode(content: String): JsonNode {
123 return jacksonObjectMapper().readTree(content)
126 fun getJson(any: kotlin.Any): String {
127 return getJson(any, false)
130 fun getWrappedJson(wrapper: String, any: kotlin.Any, pretty: Boolean = false): String {
131 val wrapperMap = hashMapOf<String, Any>()
132 wrapperMap[wrapper] = any
133 return getJson(wrapperMap, pretty)
136 fun getJson(any: kotlin.Any, pretty: Boolean = false): String {
137 val objectMapper = jacksonObjectMapper()
138 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
140 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
142 return objectMapper.writeValueAsString(any)
145 fun getJsonNode(any: kotlin.Any?, pretty: Boolean = false): JsonNode {
146 val objectMapper = jacksonObjectMapper()
147 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
149 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
151 return objectMapper.valueToTree(any)
154 fun <T> getListFromJsonNode(node: JsonNode, valueType: Class<T>): List<T> {
155 return getListFromJson(node.toString(), valueType)
158 fun <T> getListFromJson(content: String, valueType: Class<T>): List<T> {
159 val objectMapper = jacksonObjectMapper()
160 val javaType = objectMapper.typeFactory.constructCollectionType(List::class.java, valueType)
161 return objectMapper.readValue<List<T>>(content, javaType)
164 fun <T> getListFromFile(fileName: String, valueType: Class<T>): List<T> {
165 val content: String = getContent(fileName)
166 return getListFromJson(content, valueType)
169 fun <T> getListFromClassPathFile(fileName: String, valueType: Class<T>): List<T> {
170 val content: String = getClassPathFileContent(fileName)
171 return getListFromJson(content, valueType)
174 fun <T> getMapFromJson(content: String, valueType: Class<T>): MutableMap<String, T> {
175 val objectMapper = jacksonObjectMapper()
176 val mapType = objectMapper.typeFactory.constructMapType(Map::class.java, String::class.java, valueType)
177 return objectMapper.readValue(content, mapType)
180 fun <T> getMapFromFile(file: File, valueType: Class<T>): MutableMap<String, T> = runBlocking {
181 val content: String = file.readNBText()
182 getMapFromJson(content, valueType)
185 fun <T> getMapFromFile(fileName: String, valueType: Class<T>): MutableMap<String, T> = getMapFromFile(File(fileName), valueType)
187 fun <T> getInstanceFromMap(properties: MutableMap<String, JsonNode>, classType: Class<T>): T {
188 return readValue(getJson(properties), classType)
189 ?: throw BluePrintProcessorException("failed to transform content ($properties) to type ($classType)")
192 fun checkJsonNodeValueOfType(type: String, jsonNode: JsonNode): Boolean {
193 if (BluePrintTypes.validPrimitiveTypes().contains(type.toLowerCase())) {
194 return checkJsonNodeValueOfPrimitiveType(type, jsonNode)
195 } else if (BluePrintTypes.validCollectionTypes().contains(type)) {
196 return checkJsonNodeValueOfCollectionType(type, jsonNode)
201 fun checkIfPrimitiveType(primitiveType: String): Boolean {
202 return when (primitiveType.toLowerCase()) {
203 BluePrintConstants.DATA_TYPE_STRING -> true
204 BluePrintConstants.DATA_TYPE_BOOLEAN -> true
205 BluePrintConstants.DATA_TYPE_INTEGER -> true
206 BluePrintConstants.DATA_TYPE_FLOAT -> true
207 BluePrintConstants.DATA_TYPE_DOUBLE -> true
208 BluePrintConstants.DATA_TYPE_TIMESTAMP -> true
213 fun checkJsonNodeValueOfPrimitiveType(primitiveType: String, jsonNode: JsonNode): Boolean {
214 return when (primitiveType.toLowerCase()) {
215 BluePrintConstants.DATA_TYPE_STRING -> jsonNode.isTextual
216 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNode.isBoolean
217 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNode.isInt
218 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNode.isDouble
219 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNode.isDouble
220 BluePrintConstants.DATA_TYPE_TIMESTAMP -> jsonNode.isTextual
225 fun checkJsonNodeValueOfCollectionType(type: String, jsonNode: JsonNode): Boolean {
226 return when (type.toLowerCase()) {
227 BluePrintConstants.DATA_TYPE_LIST -> jsonNode.isArray
232 fun getValue(value: JsonNode): Any {
233 return when (value) {
234 is BooleanNode -> value.booleanValue()
235 is IntNode -> value.intValue()
236 is FloatNode -> value.floatValue()
237 is DoubleNode -> value.doubleValue()
238 is TextNode -> value.textValue()
243 fun getValue(value: Any, type: String): Any {
244 return when (type.toLowerCase()) {
245 BluePrintConstants.DATA_TYPE_BOOLEAN -> (value as BooleanNode).booleanValue()
246 BluePrintConstants.DATA_TYPE_INTEGER -> (value as IntNode).intValue()
247 BluePrintConstants.DATA_TYPE_FLOAT -> (value as FloatNode).floatValue()
248 BluePrintConstants.DATA_TYPE_DOUBLE -> (value as DoubleNode).doubleValue()
249 BluePrintConstants.DATA_TYPE_STRING -> (value as TextNode).textValue()
250 else -> (value as JsonNode)
254 fun populatePrimitiveValues(key: String, value: JsonNode, primitiveType: String, objectNode: ObjectNode) {
255 when (primitiveType.toLowerCase()) {
256 BluePrintConstants.DATA_TYPE_BOOLEAN,
257 BluePrintConstants.DATA_TYPE_INTEGER,
258 BluePrintConstants.DATA_TYPE_FLOAT,
259 BluePrintConstants.DATA_TYPE_DOUBLE,
260 BluePrintConstants.DATA_TYPE_TIMESTAMP,
261 BluePrintConstants.DATA_TYPE_STRING,
262 BluePrintConstants.DATA_TYPE_NULL ->
263 objectNode.set(key, value)
264 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
268 fun populatePrimitiveValues(value: JsonNode, primitiveType: String, arrayNode: ArrayNode) {
269 when (primitiveType.toLowerCase()) {
270 BluePrintConstants.DATA_TYPE_BOOLEAN,
271 BluePrintConstants.DATA_TYPE_INTEGER,
272 BluePrintConstants.DATA_TYPE_FLOAT,
273 BluePrintConstants.DATA_TYPE_DOUBLE,
274 BluePrintConstants.DATA_TYPE_TIMESTAMP,
275 BluePrintConstants.DATA_TYPE_STRING,
276 BluePrintConstants.DATA_TYPE_NULL ->
278 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
282 fun populatePrimitiveDefaultValues(key: String, primitiveType: String, objectNode: ObjectNode) {
283 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
284 ?: throw BluePrintException("populatePrimitiveDefaultValues expected only primitive values! Received type ($primitiveType)")
285 objectNode.set<JsonNode>(key, defaultValue)
288 fun populatePrimitiveDefaultValuesForArrayNode(primitiveType: String, arrayNode: ArrayNode) {
289 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
290 ?: throw BluePrintException("populatePrimitiveDefaultValuesForArrayNode expected only primitive values! Received type ($primitiveType)")
291 arrayNode.add(defaultValue)
294 private fun getDefaultValueOfPrimitiveAsJsonNode(primitiveType: String): JsonNode? {
295 return when (primitiveType.toLowerCase()) {
296 BluePrintConstants.DATA_TYPE_BOOLEAN -> BooleanNode.valueOf(false)
297 BluePrintConstants.DATA_TYPE_INTEGER -> IntNode.valueOf(0)
298 BluePrintConstants.DATA_TYPE_FLOAT -> FloatNode.valueOf(0.0f)
299 BluePrintConstants.DATA_TYPE_DOUBLE -> DoubleNode.valueOf(0.0)
300 BluePrintConstants.DATA_TYPE_STRING -> MissingNode.getInstance()
305 fun populateJsonNodeValues(key: String, nodeValue: JsonNode?, type: String, objectNode: ObjectNode) {
306 if (nodeValue == null || nodeValue is NullNode) {
307 objectNode.set<JsonNode>(key, nodeValue)
308 } else if (BluePrintTypes.validPrimitiveTypes().contains(type)) {
309 populatePrimitiveValues(key, nodeValue, type, objectNode)
311 objectNode.set<JsonNode>(key, nodeValue)
315 fun convertPrimitiveResourceValue(type: String, value: String): JsonNode {
316 return when (type.toLowerCase()) {
317 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNodeFromObject(value.toBoolean())
318 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNodeFromObject(value.toInt())
319 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNodeFromObject(value.toFloat())
320 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNodeFromObject(value.toDouble())
321 BluePrintConstants.DATA_TYPE_STRING -> jsonNodeFromObject(value)
322 else -> getJsonNode(value)