b4020c18e7962137991fc51fcdcbdb51b09d03df
[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.config.LegacyOperationalPolicyController;
54 import org.onap.clamp.clds.tosca.update.ToscaConverterWithDictionarySupport;
55 import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
56 import org.onap.clamp.loop.Loop;
57 import org.onap.clamp.loop.service.Service;
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     /**
86      * Constructor for serialization.
87      */
88     public OperationalPolicy() {
89     }
90
91     /**
92      * The constructor.
93      *
94      * @param name               The name of the operational policy
95      * @param configurationsJson The operational policy property in the format of
96      *                           json
97      * @param jsonRepresentation The jsonObject defining the json schema
98      * @param policyModel        The policy model associated if any, can be null
99      * @param loopElementModel   The loop element from which this instance is supposed to be created
100      * @param pdpGroup           The Pdp Group info
101      * @param pdpSubgroup        The Pdp Subgroup info
102      */
103     public OperationalPolicy(String name, JsonObject configurationsJson,
104                              JsonObject jsonRepresentation, PolicyModel policyModel,
105                              LoopElementModel loopElementModel, String pdpGroup, String pdpSubgroup) {
106         this.name = name;
107         this.setPolicyModel(policyModel);
108         this.setConfigurationsJson(configurationsJson);
109         this.setPdpGroup(pdpGroup);
110         this.setPdpSubgroup(pdpSubgroup);
111         this.setLoopElementModel(loopElementModel);
112         this.setJsonRepresentation(jsonRepresentation);
113
114     }
115
116     /**
117      * Create an operational policy from a loop element model.
118      *
119      * @param loop             The parent loop
120      * @param service          The loop service
121      * @param loopElementModel The loop element model
122      * @param toscaConverter   The tosca converter that must be used to create the Json representation
123      */
124     public OperationalPolicy(Loop loop, Service service, LoopElementModel loopElementModel,
125                              ToscaConverterWithDictionarySupport toscaConverter) {
126         this(Policy.generatePolicyName("OPERATIONAL", service.getName(), service.getVersion(),
127                 loopElementModel.getPolicyModels().first().getPolicyAcronym() + '_'
128                         + loopElementModel.getPolicyModels().first().getVersion(),
129                 RandomStringUtils.randomAlphanumeric(3)), new JsonObject(),
130                 new JsonObject(), loopElementModel.getPolicyModels().first(), loopElementModel, null, null);
131         this.setLoop(loop);
132         this.updateJsonRepresentation(toscaConverter, service);
133     }
134
135     /**
136      * Create an operational policy from a policy model.
137      *
138      * @param loop           The parent loop
139      * @param service        The loop service
140      * @param policyModel    The policy model
141      * @param toscaConverter The tosca converter that must be used to create the Json representation
142      * @throws IOException In case of issues with the legacy files (generated from resource files
143      */
144     public OperationalPolicy(Loop loop, Service service, PolicyModel policyModel,
145                              ToscaConverterWithDictionarySupport toscaConverter) throws IOException {
146         this(Policy.generatePolicyName("OPERATIONAL", service.getName(), service.getVersion(),
147                 policyModel.getPolicyAcronym() + '_' + policyModel.getVersion(),
148                 RandomStringUtils.randomAlphanumeric(3)),
149                 new JsonObject(),
150                 new JsonObject(), policyModel, null, null, null);
151         this.setLoop(loop);
152         this.updateJsonRepresentation(toscaConverter, service);
153     }
154
155     public void setLoop(Loop loopName) {
156         this.loop = loopName;
157     }
158
159     public Loop getLoop() {
160         return loop;
161     }
162
163     @Override
164     public String getName() {
165         return name;
166     }
167
168     /**
169      * name setter.
170      *
171      * @param name the name to set
172      */
173     @Override
174     public void setName(String name) {
175         this.name = name;
176     }
177
178     @Override
179     public void updateJsonRepresentation(ToscaConverterWithDictionarySupport toscaConverter, Service serviceModel) {
180         {
181             this.setJsonRepresentation(new JsonObject());
182             if (this.getPolicyModel() == null) {
183                 return;
184             }
185             if (this.isLegacy()) {
186                 // Op policy Legacy case
187                 LegacyOperationalPolicy.preloadConfiguration(this.getConfigurationsJson(), this.loop);
188                 this.setJsonRepresentation(OperationalPolicyRepresentationBuilder
189                         .generateOperationalPolicySchema(this.loop.getModelService()));
190             }
191             else {
192                 // Generic Case
193                 this.setJsonRepresentation(toscaConverter.convertToscaToJsonSchemaObject(
194                         this.getPolicyModel().getPolicyModelTosca(),
195                         this.getPolicyModel().getPolicyModelType(), serviceModel));
196             }
197         }
198     }
199
200     @Override
201     public int hashCode() {
202         final int prime = 31;
203         int result = 1;
204         result = prime * result + ((name == null) ? 0 : name.hashCode());
205         return result;
206     }
207
208     @Override
209     public boolean equals(Object obj) {
210         if (this == obj) {
211             return true;
212         }
213         if (obj == null) {
214             return false;
215         }
216         if (getClass() != obj.getClass()) {
217             return false;
218         }
219         OperationalPolicy other = (OperationalPolicy) obj;
220         if (name == null) {
221             if (other.name != null) {
222                 return false;
223             }
224         }
225         else if (!name.equals(other.name)) {
226             return false;
227         }
228         return true;
229     }
230
231     public Boolean isLegacy() {
232         return (this.getPolicyModel() != null) && this.getPolicyModel().getPolicyModelType().contains(
233                 LegacyOperationalPolicyController.OPERATIONAL_POLICY_LEGACY);
234     }
235
236     /**
237      * Create policy Yaml from json defined here.
238      *
239      * @return A string containing Yaml
240      */
241     public String createPolicyPayloadYaml() {
242         JsonObject policyPayloadResult = new JsonObject();
243
244         policyPayloadResult.addProperty("tosca_definitions_version", "tosca_simple_yaml_1_0_0");
245
246         JsonObject topologyTemplateNode = new JsonObject();
247         policyPayloadResult.add("topology_template", topologyTemplateNode);
248
249         JsonArray policiesArray = new JsonArray();
250         topologyTemplateNode.add("policies", policiesArray);
251
252         JsonObject operationalPolicy = new JsonObject();
253         policiesArray.add(operationalPolicy);
254
255         JsonObject operationalPolicyDetails = new JsonObject();
256         operationalPolicy.add(this.name, operationalPolicyDetails);
257         operationalPolicyDetails.addProperty("type", "onap.policies.controlloop.Operational");
258         operationalPolicyDetails.addProperty("version", "1.0.0");
259
260         JsonObject metadata = new JsonObject();
261         operationalPolicyDetails.add("metadata", metadata);
262         metadata.addProperty("policy-id", this.name);
263
264         operationalPolicyDetails.add("properties", LegacyOperationalPolicy
265                 .reworkActorAttributes(this.getConfigurationsJson().get("operational_policy").deepCopy()));
266
267         DumperOptions options = new DumperOptions();
268         options.setIndent(2);
269         options.setPrettyFlow(true);
270         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
271         Gson gson = new GsonBuilder().create();
272
273         return (new Yaml(options)).dump(gson.fromJson(gson.toJson(policyPayloadResult), Map.class));
274     }
275
276     @Override
277     public String createPolicyPayload() throws UnsupportedEncodingException {
278         if (isLegacy()) {
279             // Now using the legacy payload fo Dublin
280             JsonObject payload = new JsonObject();
281             payload.addProperty("policy-id", this.getName());
282             payload.addProperty("content",
283                     URLEncoder.encode(
284                             LegacyOperationalPolicy
285                                     .createPolicyPayloadYamlLegacy(
286                                             this.getConfigurationsJson().get("operational_policy")),
287                             StandardCharsets.UTF_8.toString()));
288             String opPayload = new GsonBuilder().setPrettyPrinting().create().toJson(payload);
289             logger.info("Operational policy payload: " + opPayload);
290             return opPayload;
291         }
292         else {
293             return super.createPolicyPayload();
294         }
295     }
296 }