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