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
228 BluePrintConstants.DATA_TYPE_MAP -> jsonNode.isContainerNode
233 fun getValue(value: JsonNode): Any {
234 return when (value) {
235 is BooleanNode -> value.booleanValue()
236 is IntNode -> value.intValue()
237 is FloatNode -> value.floatValue()
238 is DoubleNode -> value.doubleValue()
239 is TextNode -> value.textValue()
244 fun getValue(value: Any, type: String): Any {
245 return when (type.toLowerCase()) {
246 BluePrintConstants.DATA_TYPE_BOOLEAN -> (value as BooleanNode).booleanValue()
247 BluePrintConstants.DATA_TYPE_INTEGER -> (value as IntNode).intValue()
248 BluePrintConstants.DATA_TYPE_FLOAT -> (value as FloatNode).floatValue()
249 BluePrintConstants.DATA_TYPE_DOUBLE -> (value as DoubleNode).doubleValue()
250 BluePrintConstants.DATA_TYPE_STRING -> (value as TextNode).textValue()
251 else -> (value as JsonNode)
255 fun populatePrimitiveValues(key: String, value: JsonNode, primitiveType: String, objectNode: ObjectNode) {
256 when (primitiveType.toLowerCase()) {
257 BluePrintConstants.DATA_TYPE_BOOLEAN,
258 BluePrintConstants.DATA_TYPE_INTEGER,
259 BluePrintConstants.DATA_TYPE_FLOAT,
260 BluePrintConstants.DATA_TYPE_DOUBLE,
261 BluePrintConstants.DATA_TYPE_TIMESTAMP,
262 BluePrintConstants.DATA_TYPE_STRING,
263 BluePrintConstants.DATA_TYPE_NULL ->
264 objectNode.set(key, value)
265 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
269 fun populatePrimitiveValues(value: JsonNode, primitiveType: String, arrayNode: ArrayNode) {
270 when (primitiveType.toLowerCase()) {
271 BluePrintConstants.DATA_TYPE_BOOLEAN,
272 BluePrintConstants.DATA_TYPE_INTEGER,
273 BluePrintConstants.DATA_TYPE_FLOAT,
274 BluePrintConstants.DATA_TYPE_DOUBLE,
275 BluePrintConstants.DATA_TYPE_TIMESTAMP,
276 BluePrintConstants.DATA_TYPE_STRING,
277 BluePrintConstants.DATA_TYPE_NULL ->
279 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
283 fun populatePrimitiveDefaultValues(key: String, primitiveType: String, objectNode: ObjectNode) {
284 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
285 ?: throw BluePrintException("populatePrimitiveDefaultValues expected only primitive values! Received type ($primitiveType)")
286 objectNode.set(key, defaultValue)
289 fun populatePrimitiveDefaultValuesForArrayNode(primitiveType: String, arrayNode: ArrayNode) {
290 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
291 ?: throw BluePrintException("populatePrimitiveDefaultValuesForArrayNode expected only primitive values! Received type ($primitiveType)")
292 arrayNode.add(defaultValue)
295 private fun getDefaultValueOfPrimitiveAsJsonNode(primitiveType: String): JsonNode? {
296 return when (primitiveType.toLowerCase()) {
297 BluePrintConstants.DATA_TYPE_BOOLEAN -> BooleanNode.valueOf(false)
298 BluePrintConstants.DATA_TYPE_INTEGER -> IntNode.valueOf(0)
299 BluePrintConstants.DATA_TYPE_FLOAT -> FloatNode.valueOf(0.0f)
300 BluePrintConstants.DATA_TYPE_DOUBLE -> DoubleNode.valueOf(0.0)
301 BluePrintConstants.DATA_TYPE_STRING -> MissingNode.getInstance()
306 fun populateJsonNodeValues(key: String, nodeValue: JsonNode?, type: String, objectNode: ObjectNode) {
307 if (nodeValue == null || nodeValue is NullNode) {
308 objectNode.set(key, nodeValue)
309 } else if (BluePrintTypes.validPrimitiveTypes().contains(type)) {
310 populatePrimitiveValues(key, nodeValue, type, objectNode)
312 objectNode.set(key, nodeValue)
316 fun convertPrimitiveResourceValue(type: String, value: String): JsonNode {
317 return when (type.toLowerCase()) {
318 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNodeFromObject(value.toBoolean())
319 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNodeFromObject(value.toInt())
320 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNodeFromObject(value.toFloat())
321 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNodeFromObject(value.toDouble())
322 BluePrintConstants.DATA_TYPE_STRING -> jsonNodeFromObject(value)
323 else -> getJsonNode(value)