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),
89 Charset.defaultCharset()
95 fun <T> readValueFromFile(fileName: String, valueType: Class<T>): T? {
96 val content: String = getContent(fileName)
97 return readValue(content, valueType)
100 fun <T> readValueFromClassPathFile(fileName: String, valueType: Class<T>): T? {
101 val content: String = getClassPathFileContent(fileName)
102 return readValue(content, valueType)
105 fun objectNodeFromObject(from: kotlin.Any): ObjectNode {
106 return objectMapper.convertValue(from, ObjectNode::class.java)
109 fun jsonNodeFromObject(from: kotlin.Any): JsonNode {
110 return objectMapper.convertValue(from, JsonNode::class.java)
113 fun jsonNodeFromClassPathFile(fileName: String): JsonNode {
114 val content: String = getClassPathFileContent(fileName)
115 return jsonNode(content)
118 fun jsonNodeFromFile(fileName: String): JsonNode {
119 val content: String = getContent(fileName)
120 return jsonNode(content)
123 fun jsonNode(content: String): JsonNode {
124 return jacksonObjectMapper().readTree(content)
127 fun getJson(any: kotlin.Any): String {
128 return getJson(any, false)
131 fun getWrappedJson(wrapper: String, any: kotlin.Any, pretty: Boolean = false): String {
132 val wrapperMap = hashMapOf<String, Any>()
133 wrapperMap[wrapper] = any
134 return getJson(wrapperMap, pretty)
137 fun getJson(any: kotlin.Any, pretty: Boolean = false, includeNull: Boolean = false): String {
138 val objectMapper = jacksonObjectMapper()
140 objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS)
142 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
145 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
147 return objectMapper.writeValueAsString(any)
150 fun getJsonNode(any: kotlin.Any?, pretty: Boolean = false): JsonNode {
151 val objectMapper = jacksonObjectMapper()
152 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
154 objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
156 return objectMapper.valueToTree(any)
159 fun <T> getListFromJsonNode(node: JsonNode, valueType: Class<T>): List<T> {
160 return getListFromJson(node.toString(), valueType)
163 fun <T> getListFromJson(content: String, valueType: Class<T>): List<T> {
164 val objectMapper = jacksonObjectMapper()
165 val javaType = objectMapper.typeFactory.constructCollectionType(List::class.java, valueType)
166 return objectMapper.readValue<List<T>>(content, javaType)
169 fun <T> getListFromFile(fileName: String, valueType: Class<T>): List<T> {
170 val content: String = getContent(fileName)
171 return getListFromJson(content, valueType)
174 fun <T> getListFromClassPathFile(fileName: String, valueType: Class<T>): List<T> {
175 val content: String = getClassPathFileContent(fileName)
176 return getListFromJson(content, valueType)
179 fun <T> getMapFromJson(content: String, valueType: Class<T>): MutableMap<String, T> {
180 val objectMapper = jacksonObjectMapper()
181 val mapType = objectMapper.typeFactory.constructMapType(Map::class.java, String::class.java, valueType)
182 return objectMapper.readValue(content, mapType)
185 fun <T> getMapFromFile(file: File, valueType: Class<T>): MutableMap<String, T> = runBlocking {
186 val content: String = file.readNBText()
187 getMapFromJson(content, valueType)
190 fun <T> getMapFromFile(fileName: String, valueType: Class<T>): MutableMap<String, T> = getMapFromFile(File(fileName), valueType)
192 fun <T> getInstanceFromMap(properties: MutableMap<String, JsonNode>, classType: Class<T>): T {
193 return readValue(getJson(properties), classType)
194 ?: throw BluePrintProcessorException("failed to transform content ($properties) to type ($classType)")
197 fun checkJsonNodeValueOfType(type: String, jsonNode: JsonNode): Boolean {
198 if (BluePrintTypes.validPrimitiveTypes().contains(type.toLowerCase())) {
199 return checkJsonNodeValueOfPrimitiveType(type, jsonNode)
200 } else if (BluePrintTypes.validCollectionTypes().contains(type)) {
201 return checkJsonNodeValueOfCollectionType(type, jsonNode)
206 fun checkIfPrimitiveType(primitiveType: String): Boolean {
207 return when (primitiveType.toLowerCase()) {
208 BluePrintConstants.DATA_TYPE_STRING -> true
209 BluePrintConstants.DATA_TYPE_BOOLEAN -> true
210 BluePrintConstants.DATA_TYPE_INTEGER -> true
211 BluePrintConstants.DATA_TYPE_FLOAT -> true
212 BluePrintConstants.DATA_TYPE_DOUBLE -> true
213 BluePrintConstants.DATA_TYPE_TIMESTAMP -> true
218 fun checkJsonNodeValueOfPrimitiveType(primitiveType: String, jsonNode: JsonNode): Boolean {
219 return when (primitiveType.toLowerCase()) {
220 BluePrintConstants.DATA_TYPE_STRING -> jsonNode.isTextual
221 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNode.isBoolean
222 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNode.isInt
223 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNode.isDouble
224 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNode.isDouble
225 BluePrintConstants.DATA_TYPE_TIMESTAMP -> jsonNode.isTextual
230 fun checkJsonNodeValueOfCollectionType(type: String, jsonNode: JsonNode): Boolean {
231 return when (type.toLowerCase()) {
232 BluePrintConstants.DATA_TYPE_LIST -> jsonNode.isArray
237 fun getValue(value: JsonNode): Any {
238 return when (value) {
239 is BooleanNode -> value.booleanValue()
240 is IntNode -> value.intValue()
241 is FloatNode -> value.floatValue()
242 is DoubleNode -> value.doubleValue()
243 is TextNode -> value.textValue()
248 fun getValue(value: Any, type: String): Any {
249 return when (type.toLowerCase()) {
250 BluePrintConstants.DATA_TYPE_BOOLEAN -> (value as BooleanNode).booleanValue()
251 BluePrintConstants.DATA_TYPE_INTEGER -> (value as IntNode).intValue()
252 BluePrintConstants.DATA_TYPE_FLOAT -> (value as FloatNode).floatValue()
253 BluePrintConstants.DATA_TYPE_DOUBLE -> (value as DoubleNode).doubleValue()
254 BluePrintConstants.DATA_TYPE_STRING -> (value as TextNode).textValue()
255 else -> (value as JsonNode)
259 fun populatePrimitiveValues(key: String, value: JsonNode, primitiveType: String, objectNode: ObjectNode) {
260 when (primitiveType.toLowerCase()) {
261 BluePrintConstants.DATA_TYPE_BOOLEAN,
262 BluePrintConstants.DATA_TYPE_INTEGER,
263 BluePrintConstants.DATA_TYPE_FLOAT,
264 BluePrintConstants.DATA_TYPE_DOUBLE,
265 BluePrintConstants.DATA_TYPE_TIMESTAMP,
266 BluePrintConstants.DATA_TYPE_STRING,
267 BluePrintConstants.DATA_TYPE_NULL ->
268 objectNode.set(key, value)
269 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
273 fun populatePrimitiveValues(value: JsonNode, primitiveType: String, arrayNode: ArrayNode) {
274 when (primitiveType.toLowerCase()) {
275 BluePrintConstants.DATA_TYPE_BOOLEAN,
276 BluePrintConstants.DATA_TYPE_INTEGER,
277 BluePrintConstants.DATA_TYPE_FLOAT,
278 BluePrintConstants.DATA_TYPE_DOUBLE,
279 BluePrintConstants.DATA_TYPE_TIMESTAMP,
280 BluePrintConstants.DATA_TYPE_STRING,
281 BluePrintConstants.DATA_TYPE_NULL ->
283 else -> throw BluePrintException("populatePrimitiveValues expected only primitive values! Received: ($value)")
287 fun populatePrimitiveDefaultValues(key: String, primitiveType: String, objectNode: ObjectNode) {
288 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
289 ?: throw BluePrintException("populatePrimitiveDefaultValues expected only primitive values! Received type ($primitiveType)")
290 objectNode.set<JsonNode>(key, defaultValue)
293 fun populatePrimitiveDefaultValuesForArrayNode(primitiveType: String, arrayNode: ArrayNode) {
294 val defaultValue = getDefaultValueOfPrimitiveAsJsonNode(primitiveType)
295 ?: throw BluePrintException("populatePrimitiveDefaultValuesForArrayNode expected only primitive values! Received type ($primitiveType)")
296 arrayNode.add(defaultValue)
299 private fun getDefaultValueOfPrimitiveAsJsonNode(primitiveType: String): JsonNode? {
300 return when (primitiveType.toLowerCase()) {
301 BluePrintConstants.DATA_TYPE_BOOLEAN -> BooleanNode.valueOf(false)
302 BluePrintConstants.DATA_TYPE_INTEGER -> IntNode.valueOf(0)
303 BluePrintConstants.DATA_TYPE_FLOAT -> FloatNode.valueOf(0.0f)
304 BluePrintConstants.DATA_TYPE_DOUBLE -> DoubleNode.valueOf(0.0)
305 BluePrintConstants.DATA_TYPE_STRING -> MissingNode.getInstance()
310 fun populateJsonNodeValues(key: String, nodeValue: JsonNode?, type: String, objectNode: ObjectNode) {
311 if (nodeValue == null || nodeValue is NullNode) {
312 objectNode.set<JsonNode>(key, nodeValue)
313 } else if (BluePrintTypes.validPrimitiveTypes().contains(type)) {
314 populatePrimitiveValues(key, nodeValue, type, objectNode)
316 objectNode.set<JsonNode>(key, nodeValue)
320 fun convertPrimitiveResourceValue(type: String, value: String): JsonNode {
321 return when (type.toLowerCase()) {
322 BluePrintConstants.DATA_TYPE_BOOLEAN -> jsonNodeFromObject(value.toBoolean())
323 BluePrintConstants.DATA_TYPE_INTEGER -> jsonNodeFromObject(value.toInt())
324 BluePrintConstants.DATA_TYPE_FLOAT -> jsonNodeFromObject(value.toFloat())
325 BluePrintConstants.DATA_TYPE_DOUBLE -> jsonNodeFromObject(value.toDouble())
326 BluePrintConstants.DATA_TYPE_STRING -> jsonNodeFromObject(value)
327 else -> getJsonNode(value)