e21979be3c319b3eca09fbc888492800a08ad6ca
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaPolicy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Model
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
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  *
20  * SPDX-License-Identifier: Apache-2.0
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.policy.models.tosca.simple.concepts;
25
26 import java.util.ArrayList;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31
32 import javax.persistence.AttributeOverride;
33 import javax.persistence.AttributeOverrides;
34 import javax.persistence.Column;
35 import javax.persistence.ElementCollection;
36 import javax.persistence.Entity;
37 import javax.persistence.Inheritance;
38 import javax.persistence.InheritanceType;
39 import javax.persistence.Lob;
40 import javax.persistence.Table;
41
42 import lombok.Data;
43 import lombok.EqualsAndHashCode;
44 import lombok.NonNull;
45
46 import org.onap.policy.common.utils.validation.Assertions;
47 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
48 import org.onap.policy.models.base.PfAuthorative;
49 import org.onap.policy.models.base.PfConcept;
50 import org.onap.policy.models.base.PfConceptKey;
51 import org.onap.policy.models.base.PfKey;
52 import org.onap.policy.models.base.PfUtils;
53 import org.onap.policy.models.base.PfValidationMessage;
54 import org.onap.policy.models.base.PfValidationResult;
55 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
57
58 /**
59  * Class to represent the policy in TOSCA definition.
60  *
61  * @author Chenfei Gao (cgao@research.att.com)
62  * @author Liam Fallon (liam.fallon@est.tech)
63  */
64 @Entity
65 @Table(name = "ToscaPolicy")
66 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
67 @Data
68 @EqualsAndHashCode(callSuper = true)
69 public class JpaToscaPolicy extends JpaToscaEntityType<ToscaPolicy> implements PfAuthorative<ToscaPolicy> {
70     private static final long serialVersionUID = 3265174757061982805L;
71
72     // Tags for metadata
73     private static final String METADATA_POLICY_ID_TAG = "policy-id";
74     private static final String METADATA_POLICY_VERSION_TAG = "policy-version";
75
76     // @formatter:off
77     @Column
78     @AttributeOverrides({
79         @AttributeOverride(name = "name",
80                            column = @Column(name = "type_name")),
81         @AttributeOverride(name = "version",
82                            column = @Column(name = "type_version"))
83         })
84     private PfConceptKey type;
85
86     @ElementCollection
87     @Lob
88     private Map<String, String> properties;
89
90     @ElementCollection
91     private List<PfConceptKey> targets;
92     // @formatter:on
93
94     /**
95      * The Default Constructor creates a {@link JpaToscaPolicy} object with a null key.
96      */
97     public JpaToscaPolicy() {
98         this(new PfConceptKey());
99     }
100
101     /**
102      * The Key Constructor creates a {@link JpaToscaPolicy} object with the given concept key.
103      *
104      * @param key the key
105      */
106     public JpaToscaPolicy(@NonNull final PfConceptKey key) {
107         this(key, new PfConceptKey());
108     }
109
110     /**
111      * The full Constructor creates a {@link JpaToscaPolicy} object with all mandatory fields.
112      *
113      * @param key the key
114      * @param type the type of the policy
115      */
116     public JpaToscaPolicy(@NonNull final PfConceptKey key, @NonNull final PfConceptKey type) {
117         super(key);
118         this.type = type;
119     }
120
121     /**
122      * Copy constructor.
123      *
124      * @param copyConcept the concept to copy from
125      */
126     public JpaToscaPolicy(@NonNull final JpaToscaPolicy copyConcept) {
127         super(copyConcept);
128     }
129
130     /**
131      * Authorative constructor.
132      *
133      * @param authorativeConcept the authorative concept to copy from
134      */
135     public JpaToscaPolicy(final ToscaPolicy authorativeConcept) {
136         super(new PfConceptKey());
137         type = new PfConceptKey();
138         this.fromAuthorative(authorativeConcept);
139     }
140
141     @Override
142     public ToscaPolicy toAuthorative() {
143         ToscaPolicy toscaPolicy = new ToscaPolicy();
144         super.setToscaEntity(toscaPolicy);
145         super.toAuthorative();
146
147         toscaPolicy.setType(type.getName());
148
149         if (!PfKey.NULL_KEY_VERSION.equals(type.getVersion())) {
150             toscaPolicy.setTypeVersion(type.getVersion());
151         }
152         else {
153             toscaPolicy.setTypeVersion(null);
154         }
155
156         if (properties != null) {
157             Map<String, Object> propertyMap = new LinkedHashMap<>();
158
159             for (Entry<String, String> entry : properties.entrySet()) {
160                 propertyMap.put(entry.getKey(), entry.getValue());
161             }
162
163             toscaPolicy.setProperties(propertyMap);
164         }
165
166         return toscaPolicy;
167     }
168
169     @Override
170     public void fromAuthorative(@NonNull final ToscaPolicy toscaPolicy) {
171         super.fromAuthorative(toscaPolicy);
172
173         type.setName(toscaPolicy.getType());
174         type.setVersion(toscaPolicy.getTypeVersion());
175         if (type.getVersion() == null) {
176             type.setVersion(PfKey.NULL_KEY_VERSION);
177         }
178
179         if (toscaPolicy.getProperties() != null) {
180             properties = new LinkedHashMap<>();
181
182             for (Entry<String, Object> propertyEntry : toscaPolicy.getProperties().entrySet()) {
183                 // TODO: This is a HACK, we need to validate the properties against their
184                 // TODO: their data type in their policy type definition in TOSCA, which means reading
185                 // TODO: the policy type from the database and parsing the property value object correctly
186                 // TODO: Here we are simply serializing the property value into a string and storing it
187                 // TODO: unvalidated into the database
188                 properties.put(propertyEntry.getKey(), propertyEntry.getValue().toString());
189             }
190         }
191
192         // Add the property metadata if it doesn't exist already
193         if (toscaPolicy.getMetadata() == null) {
194             setMetadata(new LinkedHashMap<>());
195         }
196
197         // Add the policy name and version fields to the metadata
198         getMetadata().put(METADATA_POLICY_ID_TAG, getKey().getName());
199         getMetadata().put(METADATA_POLICY_VERSION_TAG, Integer.toString(getKey().getMajorVersion()));
200     }
201
202     @Override
203     public List<PfKey> getKeys() {
204         final List<PfKey> keyList = super.getKeys();
205
206         keyList.addAll(type.getKeys());
207
208         if (targets != null) {
209             keyList.addAll(targets);
210         }
211
212         return keyList;
213     }
214
215     @Override
216     public void clean() {
217         super.clean();
218
219         type.clean();
220
221         if (targets != null) {
222             for (PfConceptKey target : targets) {
223                 target.clean();
224             }
225         }
226     }
227
228     @Override
229     public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
230         PfValidationResult result = super.validate(resultIn);
231
232         if (type == null || type.isNullKey()) {
233             result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
234                     "type is null or a null key"));
235         } else {
236             result = type.validate(result);
237         }
238
239         if (properties != null) {
240             result = validateProperties(result);
241         }
242
243         if (targets != null) {
244             result = validateTargets(result);
245         }
246
247         return result;
248     }
249
250     /**
251      * Validate the policy properties.
252      *
253      * @param result The result of validations up to now
254      * @return the validation result
255      */
256     private PfValidationResult validateProperties(final PfValidationResult resultIn) {
257         PfValidationResult result = resultIn;
258
259         for (Entry<String, String> propertyEntry : properties.entrySet()) {
260             if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
261                 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
262                         "policy property key may not be null "));
263             } else if (propertyEntry.getValue() == null) {
264                 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
265                         "policy property value may not be null "));
266             }
267         }
268         return result;
269     }
270
271     /**
272      * Validate the policy targets.
273      *
274      * @param result The result of validations up to now
275      * @return the validation result
276      */
277     private PfValidationResult validateTargets(final PfValidationResult resultIn) {
278         PfValidationResult result = resultIn;
279
280         for (PfConceptKey target : targets) {
281             if (target == null) {
282                 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
283                         "policy target may not be null "));
284             } else {
285                 result = target.validate(result);
286             }
287         }
288         return result;
289     }
290
291     @Override
292     public int compareTo(final PfConcept otherConcept) {
293         if (otherConcept == null) {
294             return -1;
295         }
296
297         if (this == otherConcept) {
298             return 0;
299         }
300
301         if (getClass() != otherConcept.getClass()) {
302             return this.hashCode() - otherConcept.hashCode();
303         }
304
305         final JpaToscaPolicy other = (JpaToscaPolicy) otherConcept;
306         if (!super.equals(other)) {
307             return super.compareTo(other);
308         }
309
310         if (!type.equals(other.type)) {
311             return type.compareTo(other.type);
312         }
313
314         int retVal = PfUtils.compareObjects(properties, other.properties);
315         if (retVal != 0) {
316             return retVal;
317         }
318
319         return PfUtils.compareObjects(targets, other.targets);
320     }
321
322     @Override
323     public PfConcept copyTo(@NonNull PfConcept target) {
324         final Object copyObject = target;
325         Assertions.instanceOf(copyObject, PfConcept.class);
326
327         final JpaToscaPolicy copy = ((JpaToscaPolicy) copyObject);
328         super.copyTo(target);
329
330         copy.setType(new PfConceptKey(type));
331
332         if (properties == null) {
333             copy.setProperties(null);
334         } else {
335             copy.setProperties(properties);
336         }
337
338         if (targets == null) {
339             copy.setTargets(null);
340         } else {
341             final List<PfConceptKey> newTargets = new ArrayList<>();
342             for (final PfConceptKey oldTarget : targets) {
343                 newTargets.add(new PfConceptKey(oldTarget));
344             }
345             copy.setTargets(newTargets);
346         }
347
348         return copy;
349     }
350 }