Merge "Added more unit tests and fix import"
[clamp.git] / src / main / java / org / onap / clamp / policy / operational / LegacyOperationalPolicy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 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.clamp.policy.operational;
25
26 import com.google.gson.GsonBuilder;
27 import com.google.gson.JsonElement;
28
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.TreeMap;
34
35 import org.apache.commons.lang3.math.NumberUtils;
36 import org.yaml.snakeyaml.DumperOptions;
37 import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
38 import org.yaml.snakeyaml.Yaml;
39
40 /**
41  *
42  * This class contains the code required to support the sending of Legacy
43  * operational payload to policy engine. This will probably disappear in El
44  * Alto.
45  *
46  */
47 public class LegacyOperationalPolicy {
48
49     private LegacyOperationalPolicy() {
50
51     }
52
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));
56
57         } else if (NumberUtils.isParsable(stringValue)) {
58             parentJsonElement.getAsJsonObject().addProperty(jsonKey, Long.parseLong(stringValue));
59         }
60     }
61
62     private static JsonElement removeAllQuotes(JsonElement jsonElement) {
63         if (jsonElement.isJsonArray()) {
64             for (JsonElement element : jsonElement.getAsJsonArray()) {
65                 removeAllQuotes(element);
66             }
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);
71                 } else {
72                     removeAllQuotes(entry.getValue());
73                 }
74             }
75         }
76         return jsonElement;
77     }
78
79     public static JsonElement reworkPayloadAttributes(JsonElement policyJson) {
80         for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
81             JsonElement payloadElem = policy.getAsJsonObject().get("payload");
82             String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
83             if (!payloadString.isEmpty()) {
84                 Map<String, String> testMap = new Yaml().load(payloadString);
85                 String json = new GsonBuilder().create().toJson(testMap);
86                 policy.getAsJsonObject().add("payload", new GsonBuilder().create().fromJson(json, JsonElement.class));
87             }
88         }
89         return policyJson;
90     }
91
92     private static void replacePropertiesIfEmpty(JsonElement policy, String key, String valueIfEmpty) {
93         JsonElement payloadElem = policy.getAsJsonObject().get(key);
94         String payloadString = payloadElem != null ? payloadElem.getAsString() : "";
95         if (payloadString.isEmpty()) {
96             policy.getAsJsonObject().addProperty(key, valueIfEmpty);
97         }
98     }
99
100     private static JsonElement fulfillPoliciesTreeField(JsonElement policyJson) {
101         for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) {
102             replacePropertiesIfEmpty(policy, "success", "final_success");
103             replacePropertiesIfEmpty(policy, "failure", "final_failure");
104             replacePropertiesIfEmpty(policy, "failure_timeout", "final_failure_timeout");
105             replacePropertiesIfEmpty(policy, "failure_retries", "final_failure_retries");
106             replacePropertiesIfEmpty(policy, "failure_exception", "final_failure_exception");
107             replacePropertiesIfEmpty(policy, "failure_guard", "final_failure_guard");
108         }
109         return policyJson;
110     }
111
112     private static Map<String, Object> createMap(JsonElement jsonElement) {
113         Map<String, Object> mapResult = new TreeMap<>();
114
115         if (jsonElement.isJsonObject()) {
116             for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) {
117                 if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
118                     mapResult.put(entry.getKey(), entry.getValue().getAsString());
119                 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isBoolean()) {
120                     mapResult.put(entry.getKey(), entry.getValue().getAsBoolean());
121                 } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isNumber()) {
122                     // Only int ro long normally, we don't need float here
123                     mapResult.put(entry.getKey(), entry.getValue().getAsLong());
124                 } else if (entry.getValue().isJsonArray()) {
125                     List<Map<String, Object>> newArray = new ArrayList<>();
126                     mapResult.put(entry.getKey(), newArray);
127                     for (JsonElement element : entry.getValue().getAsJsonArray()) {
128                         newArray.add(createMap(element));
129                     }
130                 } else if (entry.getValue().isJsonObject()) {
131                     mapResult.put(entry.getKey(), createMap(entry.getValue()));
132                 }
133             }
134         }
135         return mapResult;
136     }
137
138     public static String createPolicyPayloadYamlLegacy(JsonElement operationalPolicyJsonElement) {
139         JsonElement opPolicy = fulfillPoliciesTreeField(
140             removeAllQuotes(reworkPayloadAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy())));
141         Map<?, ?> jsonMap = createMap(opPolicy);
142         DumperOptions options = new DumperOptions();
143         options.setDefaultScalarStyle(ScalarStyle.PLAIN);
144         options.setIndent(2);
145         options.setPrettyFlow(true);
146         // Policy can't support { } in the yaml
147         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
148         return (new Yaml(options)).dump(jsonMap);
149     }
150 }