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