2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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 * ===================================================================
24 package org.onap.clamp.policy.operational;
26 import com.google.gson.GsonBuilder;
27 import com.google.gson.JsonElement;
28 import com.google.gson.JsonObject;
30 import java.util.ArrayList;
31 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.TreeMap;
36 import org.apache.commons.lang3.math.NumberUtils;
37 import org.onap.clamp.loop.Loop;
38 import org.yaml.snakeyaml.DumperOptions;
39 import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
40 import org.yaml.snakeyaml.Yaml;
43 * This class contains the code required to support the sending of Legacy
44 * operational payload to policy engine. This will probably disappear in El
47 public class LegacyOperationalPolicy {
49 private LegacyOperationalPolicy() {
53 private static void translateStringValues(String jsonKey, String stringValue, JsonElement parentJsonElement) {
54 if (stringValue.equalsIgnoreCase("true") || stringValue.equalsIgnoreCase("false")) {
55 parentJsonElement.getAsJsonObject().addProperty(jsonKey, Boolean.valueOf(stringValue));
57 } else if (NumberUtils.isParsable(stringValue)) {
58 parentJsonElement.getAsJsonObject().addProperty(jsonKey, Long.parseLong(stringValue));
62 private static JsonElement removeAllQuotes(JsonElement jsonElement) {
63 if (jsonElement.isJsonArray()) {
64 for (JsonElement element : jsonElement.getAsJsonArray()) {
65 removeAllQuotes(element);
67 } else if (jsonElement.isJsonObject()) {
68 for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) {
69 if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
70 translateStringValues(entry.getKey(), entry.getValue().getAsString(), jsonElement);
72 removeAllQuotes(entry.getValue());
80 * This method rework the payload attribute (yaml) that is normally wrapped in a
81 * string when coming from the UI.
83 * @param policyJson The operational policy json config
84 * @return The same object reference but modified
86 public static JsonElement reworkPayloadAttributes(JsonElement policyJson) {
87 for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
88 JsonElement payloadElem = policy.getAsJsonObject().get("payload");
89 String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
90 if (!payloadString.isEmpty()) {
91 Map<String, String> testMap = new Yaml().load(payloadString);
92 String json = new GsonBuilder().create().toJson(testMap);
93 policy.getAsJsonObject().add("payload", new GsonBuilder().create().fromJson(json, JsonElement.class));
99 private static void replacePropertiesIfEmpty(JsonElement policy, String key, String valueIfEmpty) {
100 JsonElement payloadElem = policy.getAsJsonObject().get(key);
101 String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
102 if (payloadString.isEmpty()) {
103 policy.getAsJsonObject().addProperty(key, valueIfEmpty);
107 private static JsonElement fulfillPoliciesTreeField(JsonElement policyJson) {
108 for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
109 replacePropertiesIfEmpty(policy, "success", "final_success");
110 replacePropertiesIfEmpty(policy, "failure", "final_failure");
111 replacePropertiesIfEmpty(policy, "failure_timeout", "final_failure_timeout");
112 replacePropertiesIfEmpty(policy, "failure_retries", "final_failure_retries");
113 replacePropertiesIfEmpty(policy, "failure_exception", "final_failure_exception");
114 replacePropertiesIfEmpty(policy, "failure_guard", "final_failure_guard");
115 // Again special case for payload, should remove it if it's there but empty
116 // otherwise policy crashes
117 JsonElement payloadElem = policy.getAsJsonObject().get("payload");
118 if (payloadElem != null && payloadElem.isJsonPrimitive() && payloadElem.getAsString().isEmpty()) {
119 policy.getAsJsonObject().remove("payload");
125 private static Map<String, Object> createMap(JsonElement jsonElement) {
126 Map<String, Object> mapResult = new TreeMap<>();
128 if (jsonElement.isJsonObject()) {
129 for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) {
130 if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
131 mapResult.put(entry.getKey(), entry.getValue().getAsString());
132 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isBoolean()) {
133 mapResult.put(entry.getKey(), entry.getValue().getAsBoolean());
134 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isNumber()) {
135 // Only int ro long normally, we don't need float here
136 mapResult.put(entry.getKey(), entry.getValue().getAsLong());
137 } else if (entry.getValue().isJsonArray()) {
138 List<Map<String, Object>> newArray = new ArrayList<>();
139 mapResult.put(entry.getKey(), newArray);
140 for (JsonElement element : entry.getValue().getAsJsonArray()) {
141 newArray.add(createMap(element));
143 } else if (entry.getValue().isJsonObject()) {
144 mapResult.put(entry.getKey(), createMap(entry.getValue()));
152 * This method transforms the configuration json to a Yaml format.
154 * @param operationalPolicyJsonElement The operational policy json config
155 * @return The Yaml as string
157 public static String createPolicyPayloadYamlLegacy(JsonElement operationalPolicyJsonElement) {
158 DumperOptions options = new DumperOptions();
159 options.setDefaultScalarStyle(ScalarStyle.PLAIN);
160 options.setIndent(2);
161 options.setPrettyFlow(true);
162 // Policy can't support { } in the yaml
163 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
164 return (new Yaml(options)).dump(createMap(fulfillPoliciesTreeField(
165 removeAllQuotes(reworkPayloadAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy())))));
169 * This method load mandatory field in the operational policy configuration
172 * @param configurationsJson The operational policy JSON
173 * @param loop The parent loop object
175 public static void preloadConfiguration(JsonObject configurationsJson, Loop loop) {
176 if (configurationsJson != null && configurationsJson.entrySet().isEmpty()) {
177 JsonObject controlLoopName = new JsonObject();
178 controlLoopName.addProperty("controlLoopName",
179 loop != null ? loop.getName() : "Empty (NO loop loaded yet)");
180 JsonObject controlLoop = new JsonObject();
181 controlLoop.add("controlLoop", controlLoopName);
182 configurationsJson.add("operational_policy", controlLoop);