Merge "CLAMP-CDS integration to display all CDS actions for blueprint in CL"
[clamp.git] / src / main / java / org / onap / clamp / policy / operational / OperationalPolicy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                             reserved.
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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  * ===================================================================
22  *
23  */
24
25 package org.onap.clamp.policy.operational;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import com.google.gson.Gson;
30 import com.google.gson.GsonBuilder;
31 import com.google.gson.JsonArray;
32 import com.google.gson.JsonElement;
33 import com.google.gson.JsonObject;
34 import com.google.gson.JsonSyntaxException;
35 import com.google.gson.annotations.Expose;
36 import java.io.IOException;
37 import java.io.Serializable;
38 import java.io.UnsupportedEncodingException;
39 import java.net.URLEncoder;
40 import java.nio.charset.StandardCharsets;
41 import java.util.HashMap;
42 import java.util.Map;
43 import javax.persistence.Column;
44 import javax.persistence.Entity;
45 import javax.persistence.FetchType;
46 import javax.persistence.Id;
47 import javax.persistence.JoinColumn;
48 import javax.persistence.JoinColumns;
49 import javax.persistence.ManyToOne;
50 import javax.persistence.Table;
51 import javax.persistence.Transient;
52 import org.hibernate.annotations.TypeDef;
53 import org.hibernate.annotations.TypeDefs;
54 import org.onap.clamp.clds.tosca.ToscaYamlToJsonConvertor;
55 import org.onap.clamp.clds.util.JsonUtils;
56 import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
57 import org.onap.clamp.loop.Loop;
58 import org.onap.clamp.loop.template.LoopElementModel;
59 import org.onap.clamp.loop.template.PolicyModel;
60 import org.onap.clamp.policy.Policy;
61 import org.yaml.snakeyaml.DumperOptions;
62 import org.yaml.snakeyaml.Yaml;
63
64 @Entity
65 @Table(name = "operational_policies")
66 @TypeDefs({@TypeDef(name = "json", typeClass = StringJsonUserType.class)})
67 public class OperationalPolicy extends Policy implements Serializable {
68     /**
69      * The serial version ID.
70      */
71     private static final long serialVersionUID = 6117076450841538255L;
72
73     @Transient
74     private static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicy.class);
75
76     @Id
77     @Expose
78     @Column(nullable = false, name = "name", unique = true)
79     private String name;
80
81     @ManyToOne(fetch = FetchType.LAZY)
82     @JoinColumn(name = "loop_id", nullable = false)
83     private Loop loop;
84
85     public OperationalPolicy() {
86         // Serialization
87     }
88
89     /**
90      * The constructor.
91      *
92      * @param name               The name of the operational policy
93      * @param loop               The loop that uses this operational policy
94      * @param configurationsJson The operational policy property in the format of
95      *                           json
96      * @param policyModel        The policy model associated if any, can be null
97      * @param loopElementModel   The loop element from which this instance is supposed to be created
98      * @param pdpGroup           The Pdp Group info
99      * @param pdpSubgroup        The Pdp Subgroup info
100      */
101     public OperationalPolicy(String name, Loop loop, JsonObject configurationsJson, PolicyModel policyModel,
102                              LoopElementModel loopElementModel, String pdpGroup, String pdpSubgroup) {
103         this.name = name;
104         this.loop = loop;
105         this.setPolicyModel(policyModel);
106         this.setConfigurationsJson(configurationsJson);
107         this.setPdpGroup(pdpGroup);
108         this.setPdpSubgroup(pdpSubgroup);
109         this.setLoopElementModel(loopElementModel);
110         this.setJsonRepresentation(this.generateJsonRepresentation(policyModel));
111
112     }
113
114     private JsonObject generateJsonRepresentation(PolicyModel policyModel) {
115         JsonObject jsonReturned = new JsonObject();
116         if (policyModel == null) {
117             return new JsonObject();
118         }
119         try {
120             if (isLegacy()) {
121                 // Op policy Legacy case
122                 LegacyOperationalPolicy.preloadConfiguration(jsonReturned, loop);
123                 this.setJsonRepresentation(
124                         OperationalPolicyRepresentationBuilder.generateOperationalPolicySchema(loop.getModelService()));
125             } else {
126                 // Generic Case
127                 this.setJsonRepresentation(JsonUtils.GSON
128                         .fromJson(new ToscaYamlToJsonConvertor().parseToscaYaml(policyModel.getPolicyModelTosca(),
129                                 policyModel.getPolicyModelType()), JsonObject.class));
130             }
131         } catch (JsonSyntaxException | IOException | NullPointerException e) {
132             logger.error("Unable to generate the operational policy Schema ... ", e);
133             this.setJsonRepresentation(new JsonObject());
134         }
135         return jsonReturned;
136     }
137
138     public void setLoop(Loop loopName) {
139         this.loop = loopName;
140     }
141
142     public Loop getLoop() {
143         return loop;
144     }
145
146     @Override
147     public String getName() {
148         return name;
149     }
150
151     /**
152      * name setter.
153      *
154      * @param name the name to set
155      */
156     @Override
157     public void setName(String name) {
158         this.name = name;
159     }
160
161     @Override
162     public int hashCode() {
163         final int prime = 31;
164         int result = 1;
165         result = prime * result + ((name == null) ? 0 : name.hashCode());
166         return result;
167     }
168
169     @Override
170     public boolean equals(Object obj) {
171         if (this == obj) {
172             return true;
173         }
174         if (obj == null) {
175             return false;
176         }
177         if (getClass() != obj.getClass()) {
178             return false;
179         }
180         OperationalPolicy other = (OperationalPolicy) obj;
181         if (name == null) {
182             if (other.name != null) {
183                 return false;
184             }
185         } else if (!name.equals(other.name)) {
186             return false;
187         }
188         return true;
189     }
190
191     public Boolean isLegacy() {
192         return (this.getPolicyModel() != null) && this.getPolicyModel().getPolicyModelType().contains("legacy");
193     }
194
195     /**
196      * Create policy Yaml from json defined here.
197      *
198      * @return A string containing Yaml
199      */
200     public String createPolicyPayloadYaml() {
201         JsonObject policyPayloadResult = new JsonObject();
202
203         policyPayloadResult.addProperty("tosca_definitions_version", "tosca_simple_yaml_1_0_0");
204
205         JsonObject topologyTemplateNode = new JsonObject();
206         policyPayloadResult.add("topology_template", topologyTemplateNode);
207
208         JsonArray policiesArray = new JsonArray();
209         topologyTemplateNode.add("policies", policiesArray);
210
211         JsonObject operationalPolicy = new JsonObject();
212         policiesArray.add(operationalPolicy);
213
214         JsonObject operationalPolicyDetails = new JsonObject();
215         operationalPolicy.add(this.name, operationalPolicyDetails);
216         operationalPolicyDetails.addProperty("type", "onap.policies.controlloop.Operational");
217         operationalPolicyDetails.addProperty("version", "1.0.0");
218
219         JsonObject metadata = new JsonObject();
220         operationalPolicyDetails.add("metadata", metadata);
221         metadata.addProperty("policy-id", this.name);
222
223         operationalPolicyDetails.add("properties", LegacyOperationalPolicy
224                 .reworkActorAttributes(this.getConfigurationsJson().get("operational_policy").deepCopy()));
225
226         DumperOptions options = new DumperOptions();
227         options.setIndent(2);
228         options.setPrettyFlow(true);
229         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
230         Gson gson = new GsonBuilder().create();
231
232         return (new Yaml(options)).dump(gson.fromJson(gson.toJson(policyPayloadResult), Map.class));
233     }
234
235     @Override
236     public String createPolicyPayload() throws UnsupportedEncodingException {
237         if (isLegacy()) {
238             // Now using the legacy payload fo Dublin
239             JsonObject payload = new JsonObject();
240             payload.addProperty("policy-id", this.getName());
241             payload.addProperty("content",
242                     URLEncoder.encode(
243                             LegacyOperationalPolicy
244                                     .createPolicyPayloadYamlLegacy(
245                                             this.getConfigurationsJson().get("operational_policy")),
246                             StandardCharsets.UTF_8.toString()));
247             String opPayload = new GsonBuilder().setPrettyPrinting().create().toJson(payload);
248             logger.info("Operational policy payload: " + opPayload);
249             return opPayload;
250         } else {
251             return super.createPolicyPayload();
252         }
253     }
254
255     /**
256      * Return a map containing all Guard policies indexed by Guard policy Name.
257      *
258      * @return The Guards map
259      */
260     public Map<String, String> createGuardPolicyPayloads() {
261         Map<String, String> result = new HashMap<>();
262
263         if (this.getConfigurationsJson() != null) {
264             JsonElement guardsList = this.getConfigurationsJson().get("guard_policies");
265             if (guardsList != null) {
266                 for (JsonElement guardElem : guardsList.getAsJsonArray()) {
267                     result.put(guardElem.getAsJsonObject().get("policy-id").getAsString(),
268                         new GsonBuilder().create().toJson(guardElem));
269                 }
270             }
271         }
272         logger.info("Guard policy payload: " + result);
273         return result;
274     }
275
276     /**
277      * Regenerate the Operational Policy Json Representation.
278      */
279     public void updateJsonRepresentation() {
280         try {
281             this.setJsonRepresentation(
282                     OperationalPolicyRepresentationBuilder.generateOperationalPolicySchema(loop.getModelService()));
283         } catch (JsonSyntaxException | IOException | NullPointerException e) {
284             logger.error("Unable to generate the operational policy Schema ... ", e);
285             this.setJsonRepresentation(new JsonObject());
286         }
287     }
288 }