2a886df3c4b8cac32106718478744b3fe70021a5
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  *
22  */
23
24 package org.onap.policy.clamp.clds.tosca.update.parser.metadata;
25
26 import com.google.gson.JsonArray;
27 import com.google.gson.JsonObject;
28 import java.util.ArrayList;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Optional;
32 import org.onap.policy.clamp.clds.tosca.JsonEditorSchemaConstants;
33 import org.onap.policy.clamp.clds.tosca.ToscaSchemaConstants;
34 import org.onap.policy.clamp.clds.tosca.update.elements.ToscaElementProperty;
35 import org.onap.policy.clamp.clds.tosca.update.execution.ToscaMetadataExecutor;
36 import org.onap.policy.clamp.loop.service.Service;
37 import org.onap.policy.clamp.tosca.DictionaryElement;
38 import org.onap.policy.clamp.tosca.DictionaryService;
39 import org.springframework.beans.factory.annotation.Autowired;
40 import org.springframework.stereotype.Component;
41
42 @Component
43 public class ToscaMetadataParserWithDictionarySupport implements ToscaMetadataParser {
44
45     @Autowired
46     private ToscaMetadataExecutor toscaMetadataExecutor;
47
48     @Autowired
49     private DictionaryService dictionaryService;
50
51     /**
52      * This method is used to start the processing of the metadata field.
53      *
54      * @param toscaElementProperty The property metadata as Json Object
55      * @return The jsonObject structure that must be added to the json schema
56      */
57     public JsonObject processAllMetadataElement(ToscaElementProperty toscaElementProperty, Service serviceModel) {
58         if (dictionaryService != null) {
59             return parseMetadataPossibleValues(toscaElementProperty.getItems(), dictionaryService, serviceModel,
60                     toscaMetadataExecutor);
61         } else {
62             return null;
63         }
64     }
65
66     @SuppressWarnings("unchecked")
67     private static JsonObject parseMetadataPossibleValues(LinkedHashMap<String, Object> childNodeMap,
68                                                           DictionaryService dictionaryService, Service serviceModel,
69                                                           ToscaMetadataExecutor toscaMetadataExecutor) {
70         var childObject = new JsonObject();
71         if (childNodeMap.containsKey(ToscaSchemaConstants.METADATA)
72                 && childNodeMap.get(ToscaSchemaConstants.METADATA) != null) {
73             ((LinkedHashMap<String, Object>) childNodeMap.get(ToscaSchemaConstants.METADATA)).forEach((key,
74                                                                                                        value) -> {
75                 if (key.equalsIgnoreCase(ToscaSchemaConstants.METADATA_CLAMP_POSSIBLE_VALUES)) {
76                     String[] multipleValues = ((String) value).split(",");
77                     for (String multipleValue : multipleValues) {
78                         if (multipleValue.contains(ToscaSchemaConstants.DICTIONARY)) {
79                             processDictionaryElements(multipleValue, childObject, dictionaryService);
80                         }
81                         if (multipleValue.contains("ClampExecution:")) {
82                             executeClampProcess(multipleValue.replaceFirst("ClampExecution:", ""), childObject,
83                                     serviceModel, toscaMetadataExecutor);
84                         }
85                     }
86
87                 }
88             });
89         }
90         return childObject;
91     }
92
93     private static void executeClampProcess(String processInfo, JsonObject childObject, Service serviceModel,
94                                             ToscaMetadataExecutor toscaMetadataExecutor) {
95         toscaMetadataExecutor.executeTheProcess(processInfo, childObject, serviceModel);
96     }
97
98     /**
99      * For dictionary with multiple levels (defined by #).
100      *
101      * @param dictionaryKeyArray the array containing the different elements
102      * @param childObject        the structure getting the new entries
103      * @param dictionaryService  the dictionary service bean
104      */
105     private static void processComplexDictionaryElements(String[] dictionaryKeyArray, JsonObject childObject,
106                                                          DictionaryService dictionaryService) {
107         // We support only one # as of now.
108         List<DictionaryElement> dictionaryElements = null;
109         if (dictionaryKeyArray.length == 2) {
110             dictionaryElements = new ArrayList<>(dictionaryService.getDictionary(dictionaryKeyArray[0])
111                     .getDictionaryElements());
112             var subDictionaryNames = new JsonArray();
113             new ArrayList<DictionaryElement>(dictionaryService.getDictionary(dictionaryKeyArray[1])
114                     .getDictionaryElements()).forEach(elem -> subDictionaryNames.add(elem.getShortName()));
115
116             var jsonArray = new JsonArray();
117
118             Optional.of(dictionaryElements).get().forEach(c -> {
119                 var jsonObject = new JsonObject();
120                 jsonObject.addProperty(JsonEditorSchemaConstants.TYPE, getJsonType(c.getType()));
121                 if (c.getType() != null
122                         && c.getType().equalsIgnoreCase(ToscaSchemaConstants.TYPE_STRING)) {
123                     jsonObject.addProperty(JsonEditorSchemaConstants.MIN_LENGTH, 1);
124
125                 }
126                 jsonObject.addProperty(JsonEditorSchemaConstants.ID, c.getName());
127                 jsonObject.addProperty(JsonEditorSchemaConstants.LABEL, c.getShortName());
128                 jsonObject.add(JsonEditorSchemaConstants.OPERATORS, subDictionaryNames);
129                 jsonArray.add(jsonObject);
130             });
131
132             var filterObject = new JsonObject();
133             filterObject.add(JsonEditorSchemaConstants.FILTERS, jsonArray);
134
135             childObject.addProperty(JsonEditorSchemaConstants.TYPE,
136                     JsonEditorSchemaConstants.TYPE_QBLDR);
137             // TO invoke validation on such parameters
138             childObject.addProperty(JsonEditorSchemaConstants.MIN_LENGTH, 1);
139             childObject.add(JsonEditorSchemaConstants.QSSCHEMA, filterObject);
140
141         }
142     }
143
144     /**
145      * For dictionary with single entry.
146      *
147      * @param dictionaryKeyArray the array containing the different elements
148      * @param childObject        the structure getting the new entries
149      * @param dictionaryService  the dictionary service bean
150      */
151     private static void processSimpleDictionaryElements(String[] dictionaryKeyArray, JsonObject childObject,
152                                                         DictionaryService dictionaryService) {
153         var dictionaryNames = new JsonArray();
154         var dictionaryFullNames = new JsonArray();
155         dictionaryService.getDictionary(dictionaryKeyArray[0]).getDictionaryElements().forEach(c -> {
156             // Json type will be translated before Policy creation
157             if (c.getType() != null && !c.getType().equalsIgnoreCase("json")) {
158                 dictionaryFullNames.add(c.getName());
159             }
160             dictionaryNames.add(c.getShortName());
161         });
162
163         if (dictionaryFullNames.size() > 0) {
164             if (childObject.get(JsonEditorSchemaConstants.ENUM) != null) {
165                 childObject.get(JsonEditorSchemaConstants.ENUM).getAsJsonArray().add(dictionaryFullNames);
166             } else {
167                 childObject.add(JsonEditorSchemaConstants.ENUM, dictionaryFullNames);
168             }
169             // Add Enum titles for generated translated values during JSON instance
170             // generation
171             var enumTitles = new JsonObject();
172             enumTitles.add(JsonEditorSchemaConstants.ENUM_TITLES, dictionaryNames);
173             if (childObject.get(JsonEditorSchemaConstants.OPTIONS) != null) {
174                 childObject.get(JsonEditorSchemaConstants.OPTIONS).getAsJsonArray().add(enumTitles);
175             } else {
176                 childObject.add(JsonEditorSchemaConstants.OPTIONS, enumTitles);
177             }
178
179         } else {
180             if (childObject.get(JsonEditorSchemaConstants.ENUM) != null) {
181                 childObject.get(JsonEditorSchemaConstants.ENUM).getAsJsonArray().add(dictionaryNames);
182             } else {
183                 childObject.add(JsonEditorSchemaConstants.ENUM, dictionaryNames);
184             }
185         }
186     }
187
188     private static void processDictionaryElements(String dictionaryReference, JsonObject childObject,
189                                                   DictionaryService dictionaryService) {
190         String[] dictionaryKeyArray =
191                 dictionaryReference.substring(dictionaryReference.indexOf(ToscaSchemaConstants.DICTIONARY) + 11,
192                         dictionaryReference.length()).split("#");
193         if (dictionaryKeyArray.length > 1) {
194             processComplexDictionaryElements(dictionaryKeyArray, childObject, dictionaryService);
195         } else {
196             processSimpleDictionaryElements(dictionaryKeyArray, childObject, dictionaryService);
197         }
198     }
199
200     private static String getJsonType(String toscaType) {
201         String jsonType = null;
202         if (toscaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_INTEGER)) {
203             jsonType = JsonEditorSchemaConstants.TYPE_INTEGER;
204         } else if (toscaType.equalsIgnoreCase(ToscaSchemaConstants.TYPE_LIST)) {
205             jsonType = JsonEditorSchemaConstants.TYPE_ARRAY;
206         } else {
207             jsonType = JsonEditorSchemaConstants.TYPE_STRING;
208         }
209         return jsonType;
210     }
211
212 }