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, includeNull: Boolean = false): String {
137 val objectMapper = jacksonObjectMapper()
139 objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS)
141 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
144 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
146 return objectMapper.writeValueAsString(any)
149 fun getJsonNode(any: kotlin.Any?, pretty: Boolean = false): JsonNode {
150 val objectMapper = jacksonObjectMapper()
151 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
153 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
155 return objectMapper.valueToTree(any)
158 fun <T> getListFromJsonNode(node: JsonNode, valueType: Class<T>): List<T> {
159 return getListFromJson(node.toString(), valueType)
162 fun <T> getListFromJson(content: String, valueType: Class<T>): List<T> {
163 val objectMapper = jacksonObjectMapper()
164 val javaType = objectMapper.typeFactory.constructCollectionType(List::class.java, valueType)
165 return objectMapper.readValue<List<T>>(content, javaType)
168 fun <T> getListFromFile(fileName: String, valueType: Class<T>): List<T> {
169 val content: String = getContent(fileName)
170 return getListFromJson(content, valueType)
173 fun <T> getListFromClassPathFile(fileName: String, valueType: Class<T>): List<T> {
174 val content: String = getClassPathFileContent(fileName)
175 return getListFromJson(content, valueType)
178 fun <T> getMapFromJson(content: String, valueType: Class<T>): MutableMap<String, T> {
179 val objectMapper = jacksonObjectMapper()
180 val mapType = objectMapper.typeFactory.constructMapType(Map::class.java, String::class.java, valueType)
181 return objectMapper.readValue(content, mapType)
184 fun <T> getMapFromFile(file: File, valueType: Class<T>): MutableMap<String, T> = runBlocking {
185 val content: String = file.readNBText()
186 getMapFromJson(content, valueType)
189 fun <T> getMapFromFile(fileName: String, valueType: Class<T>): MutableMap<String, T> = getMapFromFile(File(fileName), valueType)
191 fun <T> getInstanceFromMap(properties: MutableMap<String, JsonNode>, classType: Class<T>): T {
192 return readValue(getJson(properties), classType)
193 ?: throw BluePrintProcessorException("failed to transform content ($properties) to type ($classType)")
196 fun checkJsonNodeValueOfType(type: String, jsonNode: JsonNode): Boolean {
197 if (BluePrintTypes.validPrimitiveTypes().contains(type.toLowerCase())) {
198 return checkJsonNodeValueOfPrimitiveType(type, jsonNode)
199 } else if (BluePrintTypes.validCollectionTypes().contains(type)) {
200 return checkJsonNodeValueOfCollectionType(type, jsonNode)
205 fun checkIfPrimitiveType(primitiveType: String): Boolean {
206 return when (primitiveType.toLowerCase()) {
207 BluePrintConstants.DATA_TYPE_STRING -> true
208 BluePrintConstants.DATA_TYPE_BOOLEAN -> true
209 BluePrintConstants.DATA_TYPE_INTEGER -> true
210 BluePrintConstants.DATA_TYPE_FLOAT -> true
211 BluePrintConstants.DATA_TYPE_DOUBLE -> true
212 BluePrintConstants.DATA_TYPE_TIMESTAMP -> true
217 fun checkJsonNodeValueOfPrimitiveType(primitiveType: String, jsonNode: JsonNode): Boolean {
218 return when (primitiveType.toLowerCase()) {
219 BluePrintConstants.DATA_TYPE_STRING -> jsonNode.isTextual
220 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNode.isBoolean
221 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNode.isInt
222 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNode.isDouble
223 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNode.isDouble
224 BluePrintConstants.DATA_TYPE_TIMESTAMP -> jsonNode.isTextual
229 fun checkJsonNodeValueOfCollectionType(type: String, jsonNode: JsonNode): Boolean {
230 return when (type.toLowerCase()) {
231 BluePrintConstants.DATA_TYPE_LIST -> jsonNode.isArray
236 fun getValue(value: JsonNode): Any {
237 return when (value) {
238 is BooleanNode -> value.booleanValue()
239 is IntNode -> value.intValue()
240 is FloatNode -> value.floatValue()
241 is DoubleNode -> value.doubleValue()
242 is TextNode -> value.textValue()
247 fun getValue(value: Any, type: String): Any {
248 return when (type.toLowerCase()) {
249 BluePrintConstants.DATA_TYPE_BOOLEAN -> (value as BooleanNode).booleanValue()
250 BluePrintConstants.DATA_TYPE_INTEGER -> (value as IntNode).intValue()
251 BluePrintConstants.DATA_TYPE_FLOAT -> (value as FloatNode).floatValue()
252 BluePrintConstants.DATA_TYPE_DOUBLE -> (value as DoubleNode).doubleValue()
253 BluePrintConstants.DATA_TYPE_STRING -> (value as TextNode).textValue()
254 else -> (value as JsonNode)
258 fun populatePrimitiveValues(key: String, value: JsonNode, primitiveType: String, objectNode: ObjectNode) {
259 when (primitiveType.toLowerCase()) {
260 BluePrintConstants.DATA_TYPE_BOOLEAN,
261 BluePrintConstants.DATA_TYPE_INTEGER,
262 BluePrintConstants.DATA_TYPE_FLOAT,
263 BluePrintConstants.DATA_TYPE_DOUBLE,
264 BluePrintConstants.DATA_TYPE_TIMESTAMP,
265 BluePrintConstants.DATA_TYPE_STRING,
266 BluePrintConstants.DATA_TYPE_NULL ->
267 objectNode.set(key, value)
268 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
272 fun populatePrimitiveValues(value: JsonNode, primitiveType: String, arrayNode: ArrayNode) {
273 when (primitiveType.toLowerCase()) {
274 BluePrintConstants.DATA_TYPE_BOOLEAN,
275 BluePrintConstants.DATA_TYPE_INTEGER,
276 BluePrintConstants.DATA_TYPE_FLOAT,
277 BluePrintConstants.DATA_TYPE_DOUBLE,
278 BluePrintConstants.DATA_TYPE_TIMESTAMP,
279 BluePrintConstants.DATA_TYPE_STRING,
280 BluePrintConstants.DATA_TYPE_NULL ->
282 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
286 fun populatePrimitiveDefaultValues(key: String, primitiveType: String, objectNode: ObjectNode) {
287 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
288 ?: throw BluePrintException("populatePrimitiveDefaultValues expected only primitive values! Received type ($primitiveType)")
289 objectNode.set<JsonNode>(key, defaultValue)
292 fun populatePrimitiveDefaultValuesForArrayNode(primitiveType: String, arrayNode: ArrayNode) {
293 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
294 ?: throw BluePrintException("populatePrimitiveDefaultValuesForArrayNode expected only primitive values! Received type ($primitiveType)")
295 arrayNode.add(defaultValue)
298 private fun getDefaultValueOfPrimitiveAsJsonNode(primitiveType: String): JsonNode? {
299 return when (primitiveType.toLowerCase()) {
300 BluePrintConstants.DATA_TYPE_BOOLEAN -> BooleanNode.valueOf(false)
301 BluePrintConstants.DATA_TYPE_INTEGER -> IntNode.valueOf(0)
302 BluePrintConstants.DATA_TYPE_FLOAT -> FloatNode.valueOf(0.0f)
303 BluePrintConstants.DATA_TYPE_DOUBLE -> DoubleNode.valueOf(0.0)
304 BluePrintConstants.DATA_TYPE_STRING -> MissingNode.getInstance()
309 fun populateJsonNodeValues(key: String, nodeValue: JsonNode?, type: String, objectNode: ObjectNode) {
310 if (nodeValue == null || nodeValue is NullNode) {
311 objectNode.set<JsonNode>(key, nodeValue)
312 } else if (BluePrintTypes.validPrimitiveTypes().contains(type)) {
313 populatePrimitiveValues(key, nodeValue, type, objectNode)
315 objectNode.set<JsonNode>(key, nodeValue)
319 fun convertPrimitiveResourceValue(type: String, value: String): JsonNode {
320 return when (type.toLowerCase()) {
321 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNodeFromObject(value.toBoolean())
322 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNodeFromObject(value.toInt())
323 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNodeFromObject(value.toFloat())
324 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNodeFromObject(value.toDouble())
325 BluePrintConstants.DATA_TYPE_STRING -> jsonNodeFromObject(value)
326 else -> getJsonNode(value)