32cb6ac77221742fdf0c1181cdf1d091e5a52210
[ccsdk/cds.git] / ms / controllerblueprints / modules / blueprint-core / src / main / kotlin / org / onap / ccsdk / cds / controllerblueprints / core / service / BluePrintExpressionService.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2018 IBM.
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
18 package org.onap.ccsdk.cds.controllerblueprints.core.service
19
20 import org.slf4j.LoggerFactory
21 import com.fasterxml.jackson.databind.JsonNode
22 import com.fasterxml.jackson.databind.node.ArrayNode
23 import com.fasterxml.jackson.databind.node.ObjectNode
24 import com.fasterxml.jackson.databind.node.TextNode
25 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
26 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
27 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
28 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
29
30 /**
31  *
32  *
33  * @author Brinda Santh
34  */
35 object BluePrintExpressionService {
36     val log= LoggerFactory.getLogger(this::class.toString())
37
38     @JvmStatic
39     fun checkContainsExpression(propertyAssignmentNode: JsonNode): Boolean {
40         val json = propertyAssignmentNode.toString()
41         // FIXME("Check if any Optimisation needed")
42         return (json.contains(BluePrintConstants.EXPRESSION_GET_INPUT)
43                 || json.contains(BluePrintConstants.EXPRESSION_GET_ATTRIBUTE)
44                 || json.contains(BluePrintConstants.EXPRESSION_GET_PROPERTY))
45
46     }
47
48     @JvmStatic
49     fun getExpressionData(propertyAssignmentNode: JsonNode): ExpressionData {
50         log.trace("Assignment Data/Expression : {}", propertyAssignmentNode)
51         val expressionData = ExpressionData(valueNode = propertyAssignmentNode)
52         if (propertyAssignmentNode is ObjectNode) {
53             val commands: Set<String> = propertyAssignmentNode.fieldNames().asSequence().toList().intersect(BluePrintTypes.validCommands())
54             if (commands.isNotEmpty()) {
55                 expressionData.isExpression = true
56                 expressionData.command = commands.first()
57                 expressionData.expressionNode = propertyAssignmentNode
58
59                 when (expressionData.command) {
60                     BluePrintConstants.EXPRESSION_GET_INPUT -> {
61                         expressionData.inputExpression = populateInputExpression(propertyAssignmentNode)
62                     }
63                     BluePrintConstants.EXPRESSION_GET_ATTRIBUTE -> {
64                         expressionData.attributeExpression = populateAttributeExpression(propertyAssignmentNode)
65                     }
66                     BluePrintConstants.EXPRESSION_GET_PROPERTY -> {
67                         expressionData.propertyExpression = populatePropertyExpression(propertyAssignmentNode)
68                     }
69                     BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT -> {
70                         expressionData.operationOutputExpression = populateOperationOutputExpression(propertyAssignmentNode)
71                     }
72                     BluePrintConstants.EXPRESSION_GET_ARTIFACT -> {
73                         expressionData.artifactExpression = populateArtifactExpression(propertyAssignmentNode)
74                     }
75                 }
76             }
77         } else if (propertyAssignmentNode is TextNode
78                 && propertyAssignmentNode.textValue().startsWith(BluePrintConstants.EXPRESSION_DSL_REFERENCE)) {
79             expressionData.isExpression = true
80             expressionData.command = BluePrintConstants.EXPRESSION_DSL_REFERENCE
81             expressionData.dslExpression = populateDSLExpression(propertyAssignmentNode)
82         }
83         return expressionData
84     }
85
86     @JvmStatic
87     fun populateDSLExpression(jsonNode: TextNode): DSLExpression {
88         return DSLExpression(propertyName = jsonNode.textValue()
89                 .removePrefix(BluePrintConstants.EXPRESSION_DSL_REFERENCE))
90     }
91
92     @JvmStatic
93     fun populateInputExpression(jsonNode: JsonNode): InputExpression {
94         return InputExpression(propertyName = jsonNode.first().textValue())
95     }
96
97     @JvmStatic
98     fun populatePropertyExpression(jsonNode: JsonNode): PropertyExpression {
99         val arrayNode: ArrayNode = jsonNode.first() as ArrayNode
100         check(arrayNode.size() >= 2) {
101             throw BluePrintException(String.format("missing property expression, " +
102                     "it should be [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>, " +
103                     "<nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ] , but present {}", jsonNode))
104         }
105         var reqOrCapEntityName: String? = null
106         var propertyName = ""
107         var subProperty: String? = null
108         when {
109             arrayNode.size() == 2 -> propertyName = arrayNode[1].textValue()
110             arrayNode.size() == 3 -> {
111                 reqOrCapEntityName = arrayNode[1].textValue()
112                 propertyName = arrayNode[2].textValue()
113             }
114             arrayNode.size() > 3 -> {
115                 reqOrCapEntityName = arrayNode[1].textValue()
116                 propertyName = arrayNode[2].textValue()
117                 val propertyPaths: List<String> = arrayNode.filterIndexed { index, _ ->
118                     index >= 3
119                 }.map { it.textValue() }
120                 subProperty = propertyPaths.joinToString("/")
121             }
122         }
123
124         return PropertyExpression(modelableEntityName = arrayNode[0].asText(),
125                 reqOrCapEntityName = reqOrCapEntityName,
126                 propertyName = propertyName,
127                 subPropertyName = subProperty
128         )
129     }
130
131     @JvmStatic
132     fun populateAttributeExpression(jsonNode: JsonNode): AttributeExpression {
133         val arrayNode: ArrayNode = jsonNode.first() as ArrayNode
134         check(arrayNode.size() >= 2) {
135             throw BluePrintException(String.format("missing attribute expression, " +
136                     "it should be [ <modelable_entity_name>, <optional_req_or_cap_name>, <attribute_name>," +
137                     " <nested_attribute_name_or_index_1>, ..., <nested_attribute_name_or_index_n> ] , but present {}", jsonNode))
138         }
139
140         var reqOrCapEntityName: String? = null
141         var attributeName = ""
142         var subAttributeName: String? = null
143         when {
144             arrayNode.size() == 2 -> attributeName = arrayNode[1].textValue()
145             arrayNode.size() == 3 -> {
146                 reqOrCapEntityName = arrayNode[1].textValue()
147                 attributeName = arrayNode[2].textValue()
148             }
149             arrayNode.size() > 3 -> {
150                 reqOrCapEntityName = arrayNode[1].textValue()
151                 attributeName = arrayNode[2].textValue()
152                 val propertyPaths: List<String> = arrayNode.filterIndexed { index, _ ->
153                     index >= 3
154                 }.map { it.textValue() }
155                 subAttributeName = propertyPaths.joinToString("/")
156             }
157         }
158         return AttributeExpression(modelableEntityName = arrayNode[0].asText(),
159                 reqOrCapEntityName = reqOrCapEntityName,
160                 attributeName = attributeName,
161                 subAttributeName = subAttributeName
162         )
163     }
164
165     @JvmStatic
166     fun populateOperationOutputExpression(jsonNode: JsonNode): OperationOutputExpression {
167         val arrayNode: ArrayNode = jsonNode.first() as ArrayNode
168
169         check(arrayNode.size() >= 4) {
170             throw BluePrintException(String.format("missing operation output expression, " +
171                     "it should be (<modelable_entity_name>, <interface_name>, <operation_name>, <output_variable_name>) , but present {}", jsonNode))
172         }
173         return OperationOutputExpression(modelableEntityName = arrayNode[0].asText(),
174                 interfaceName = arrayNode[1].asText(),
175                 operationName = arrayNode[2].asText(),
176                 propertyName = arrayNode[3].asText()
177         )
178     }
179
180     @JvmStatic
181     fun populateArtifactExpression(jsonNode: JsonNode): ArtifactExpression {
182         val arrayNode: ArrayNode = jsonNode.first() as ArrayNode
183
184         check(arrayNode.size() >= 2) {
185             throw BluePrintException(String.format("missing artifact expression, " +
186                     "it should be [ <modelable_entity_name>, <artifact_name>, <location>, <remove> ] , but present {}", jsonNode))
187         }
188         return ArtifactExpression(modelableEntityName = arrayNode[0].asText(),
189                 artifactName = arrayNode[1].asText(),
190                 location = arrayNode[2]?.asText() ?: "LOCAL_FILE",
191                 remove = arrayNode[3]?.asBoolean() ?: false
192         )
193     }
194 }