2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights
7 * Modifications Copyright (C) 2020 Huawei Technologies Co., Ltd.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END============================================
21 * ===================================================================
25 package org.onap.clamp.policy.operational;
27 import com.google.gson.GsonBuilder;
28 import com.google.gson.JsonElement;
29 import com.google.gson.JsonObject;
31 import java.util.ArrayList;
32 import java.util.List;
34 import java.util.Map.Entry;
35 import java.util.TreeMap;
37 import org.apache.commons.lang3.math.NumberUtils;
38 import org.onap.clamp.loop.Loop;
39 import org.yaml.snakeyaml.DumperOptions;
40 import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
41 import org.yaml.snakeyaml.Yaml;
44 * This class contains the code required to support the sending of Legacy
45 * operational payload to policy engine. This will probably disappear in El
48 public class LegacyOperationalPolicy {
50 private static final String ACTOR = "actor";
51 private static final String RECIPE = "recipe";
52 private static final String POLICIES = "policies";
53 private static final String PAYLOAD = "payload";
55 private LegacyOperationalPolicy() {
59 private static void translateStringValues(String jsonKey, String stringValue, JsonElement parentJsonElement) {
60 if (stringValue.equalsIgnoreCase("true") || stringValue.equalsIgnoreCase("false")) {
61 parentJsonElement.getAsJsonObject().addProperty(jsonKey, Boolean.valueOf(stringValue));
63 } else if (NumberUtils.isParsable(stringValue)) {
64 parentJsonElement.getAsJsonObject().addProperty(jsonKey, Long.parseLong(stringValue));
68 private static JsonElement removeAllQuotes(JsonElement jsonElement) {
69 if (jsonElement.isJsonArray()) {
70 for (JsonElement element : jsonElement.getAsJsonArray()) {
71 removeAllQuotes(element);
73 } else if (jsonElement.isJsonObject()) {
74 for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) {
75 if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
76 translateStringValues(entry.getKey(), entry.getValue().getAsString(), jsonElement);
78 removeAllQuotes(entry.getValue());
86 * This method rework the payload attribute (yaml) that is normally wrapped in a
87 * string when coming from the UI.
89 * @param policyJson The operational policy json config
90 * @return The same object reference but modified
92 public static JsonElement reworkPayloadAttributes(JsonElement policyJson) {
93 for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
94 JsonElement payloadElem = policy.getAsJsonObject().get("payload");
95 String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
96 if (!payloadString.isEmpty()) {
97 Map<String, String> testMap = new Yaml().load(payloadString);
98 String json = new GsonBuilder().create().toJson(testMap);
99 policy.getAsJsonObject().add("payload", new GsonBuilder().create().fromJson(json, JsonElement.class));
105 private static void replacePropertiesIfEmpty(JsonElement policy, String key, String valueIfEmpty) {
106 JsonElement payloadElem = policy.getAsJsonObject().get(key);
107 String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
108 if (payloadString.isEmpty()) {
109 policy.getAsJsonObject().addProperty(key, valueIfEmpty);
113 private static JsonElement fulfillPoliciesTreeField(JsonElement policyJson) {
114 for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
115 replacePropertiesIfEmpty(policy, "success", "final_success");
116 replacePropertiesIfEmpty(policy, "failure", "final_failure");
117 replacePropertiesIfEmpty(policy, "failure_timeout", "final_failure_timeout");
118 replacePropertiesIfEmpty(policy, "failure_retries", "final_failure_retries");
119 replacePropertiesIfEmpty(policy, "failure_exception", "final_failure_exception");
120 replacePropertiesIfEmpty(policy, "failure_guard", "final_failure_guard");
121 // Again special case for payload, should remove it if it's there but empty
122 // otherwise policy crashes
123 JsonElement payloadElem = policy.getAsJsonObject().get("payload");
124 if (payloadElem != null && payloadElem.isJsonPrimitive() && payloadElem.getAsString().isEmpty()) {
125 policy.getAsJsonObject().remove("payload");
131 private static Map<String, Object> createMap(JsonElement jsonElement) {
132 Map<String, Object> mapResult = new TreeMap<>();
134 if (jsonElement.isJsonObject()) {
135 for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) {
136 if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
137 mapResult.put(entry.getKey(), entry.getValue().getAsString());
138 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isBoolean()) {
139 mapResult.put(entry.getKey(), entry.getValue().getAsBoolean());
140 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isNumber()) {
141 // Only int ro long normally, we don't need float here
142 mapResult.put(entry.getKey(), entry.getValue().getAsLong());
143 } else if (entry.getValue().isJsonArray()) {
144 List<Map<String, Object>> newArray = new ArrayList<>();
145 mapResult.put(entry.getKey(), newArray);
146 for (JsonElement element : entry.getValue().getAsJsonArray()) {
147 newArray.add(createMap(element));
149 } else if (entry.getValue().isJsonObject()) {
150 mapResult.put(entry.getKey(), createMap(entry.getValue()));
158 * This method transforms the configuration json to a Yaml format.
160 * @param operationalPolicyJsonElement The operational policy json config
161 * @return The Yaml as string
163 public static String createPolicyPayloadYamlLegacy(JsonElement operationalPolicyJsonElement) {
164 DumperOptions options = new DumperOptions();
165 options.setDefaultScalarStyle(ScalarStyle.PLAIN);
166 options.setIndent(2);
167 options.setPrettyFlow(true);
168 // Policy can't support { } in the yaml
169 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
170 return (new Yaml(options)).dump(createMap(fulfillPoliciesTreeField(
171 removeAllQuotes(reworkActorAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy())))));
175 * This method load mandatory field in the operational policy configuration
178 * @param configurationsJson The operational policy JSON
179 * @param loop The parent loop object
181 public static void preloadConfiguration(JsonObject configurationsJson, Loop loop) {
182 if (configurationsJson != null && configurationsJson.entrySet().isEmpty()) {
183 JsonObject controlLoopName = new JsonObject();
184 controlLoopName.addProperty("controlLoopName",
185 loop != null ? loop.getName() : "Empty (NO loop loaded yet)");
186 JsonObject controlLoop = new JsonObject();
187 controlLoop.add("controlLoop", controlLoopName);
188 configurationsJson.add("operational_policy", controlLoop);
193 * This method rework on the actor/recipe and payload attribute.
195 * @param policyJson The operational policy json config
196 * @return The same object reference but modified
198 public static JsonElement reworkActorAttributes(JsonElement policyJson) {
199 for (JsonElement policy : policyJson.getAsJsonObject().get(POLICIES).getAsJsonArray()) {
200 JsonObject actor = policy.getAsJsonObject().get(ACTOR).getAsJsonObject();
201 policy.getAsJsonObject().remove(ACTOR);
202 String actorStr = actor.getAsJsonObject().get(ACTOR).getAsString();
203 policy.getAsJsonObject().addProperty(ACTOR, actorStr);
204 policy.getAsJsonObject().addProperty(RECIPE, getRecipe(actor));
206 if ("CDS".equalsIgnoreCase(actorStr)) {
207 addPayloadAttributes(actor.getAsJsonObject(ACTOR).getAsJsonObject(RECIPE), policy);
209 addPayloadAttributes(actor, policy);
215 private static void addPayloadAttributes(JsonObject jsonObject,
216 JsonElement policy) {
217 JsonElement payloadElem = jsonObject.getAsJsonObject().get(PAYLOAD);
218 String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
219 if (!payloadString.isEmpty()) {
220 Map<String, String> testMap = new Yaml().load(payloadString);
221 String json = new GsonBuilder().create().toJson(testMap);
222 policy.getAsJsonObject().add(PAYLOAD,
223 new GsonBuilder().create().fromJson(json, JsonElement.class));
225 policy.getAsJsonObject().addProperty(PAYLOAD, "");
229 private static String getRecipe(JsonObject actor) {
230 return actor.getAsJsonObject().get("type").getAsString();