Use ValidationResult for models v2.0
[policy/models.git] / models-pdp / src / main / java / org / onap / policy / models / pdp / persistence / concepts / JpaPdpSubGroup.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Model
4  * ================================================================================
5  * Copyright (C) 2019-2020 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.pdp.persistence.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 import javax.persistence.CascadeType;
32 import javax.persistence.Column;
33 import javax.persistence.ElementCollection;
34 import javax.persistence.EmbeddedId;
35 import javax.persistence.Entity;
36 import javax.persistence.FetchType;
37 import javax.persistence.Inheritance;
38 import javax.persistence.InheritanceType;
39 import javax.persistence.JoinColumn;
40 import javax.persistence.JoinTable;
41 import javax.persistence.OneToMany;
42 import javax.persistence.Table;
43 import lombok.Data;
44 import lombok.EqualsAndHashCode;
45 import lombok.NonNull;
46 import org.onap.policy.common.parameters.BeanValidationResult;
47 import org.onap.policy.models.base.PfAuthorative;
48 import org.onap.policy.models.base.PfConcept;
49 import org.onap.policy.models.base.PfConceptKey;
50 import org.onap.policy.models.base.PfKey;
51 import org.onap.policy.models.base.PfKeyUse;
52 import org.onap.policy.models.base.PfReferenceKey;
53 import org.onap.policy.models.base.PfSearchableKey;
54 import org.onap.policy.models.base.PfUtils;
55 import org.onap.policy.models.base.Validated;
56 import org.onap.policy.models.pdp.concepts.Pdp;
57 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
60
61 /**
62  * Class to represent a PDP subgroup in the database.
63  *
64  * @author Liam Fallon (liam.fallon@est.tech)
65  */
66 @Entity
67 @Table(name = "PdpSubGroup")
68 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
69 @Data
70 @EqualsAndHashCode(callSuper = false)
71 public class JpaPdpSubGroup extends PfConcept implements PfAuthorative<PdpSubGroup> {
72     private static final long serialVersionUID = -357224425637789775L;
73
74     @EmbeddedId
75     private PfReferenceKey key;
76
77     @ElementCollection
78     private List<PfSearchableKey> supportedPolicyTypes;
79
80     @ElementCollection
81     private List<PfConceptKey> policies;
82
83     @Column
84     private int currentInstanceCount;
85
86     @Column
87     private int desiredInstanceCount;
88
89     @ElementCollection
90     private Map<String, String> properties;
91
92     // @formatter:off
93     @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
94     @JoinTable (
95             joinColumns = {
96                 @JoinColumn(name = "pdpParentKeyName",    referencedColumnName = "parentKeyName"),
97                 @JoinColumn(name = "pdpParentKeyVersion", referencedColumnName = "parentKeyVersion"),
98                 @JoinColumn(name = "pdpParentLocalName",  referencedColumnName = "parentLocalName"),
99                 @JoinColumn(name = "pdpLocalName",        referencedColumnName = "localName")
100             }
101         )
102     // formatter:on
103     private List<JpaPdp> pdpInstances;
104
105     /**
106      * The Default Constructor creates a {@link JpaPdpSubGroup} object with a null key.
107      */
108     public JpaPdpSubGroup() {
109         this(new PfReferenceKey());
110     }
111
112     /**
113      * The Key Constructor creates a {@link JpaPdpSubGroup} object with the given concept key.
114      *
115      * @param key the key
116      */
117     public JpaPdpSubGroup(@NonNull final PfReferenceKey key) {
118         this(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
119     }
120
121     /**
122      * The Key Constructor creates a {@link JpaPdpSubGroup} object with all mandatory fields.
123      *
124      * @param key the key
125      * @param supportedPolicyTypes Supported policy types
126      * @param policies policies deployed on this PDP subgroups
127      * @param pdpInstances the PDP instances on this PDP subgroups
128      */
129     public JpaPdpSubGroup(@NonNull final PfReferenceKey key, @NonNull final List<PfSearchableKey> supportedPolicyTypes,
130             @NonNull List<PfConceptKey> policies, @NonNull final List<JpaPdp> pdpInstances) {
131         this.key = key;
132         this.supportedPolicyTypes = supportedPolicyTypes;
133         this.policies = policies;
134         this.pdpInstances = pdpInstances;
135     }
136
137     /**
138      * Copy constructor.
139      *
140      * @param copyConcept the concept to copy from
141      */
142     public JpaPdpSubGroup(@NonNull final JpaPdpSubGroup copyConcept) {
143         super(copyConcept);
144         this.key = new PfReferenceKey(copyConcept.key);
145         this.supportedPolicyTypes = PfUtils.mapList(copyConcept.supportedPolicyTypes,
146                                         PfSearchableKey::new, new ArrayList<>(0));
147         this.policies = PfUtils.mapList(copyConcept.policies, PfConceptKey::new, new ArrayList<>(0));
148         this.currentInstanceCount = copyConcept.currentInstanceCount;
149         this.desiredInstanceCount = copyConcept.desiredInstanceCount;
150         this.properties = (copyConcept.properties != null ? new LinkedHashMap<>(copyConcept.properties) : null);
151         this.pdpInstances = PfUtils.mapList(copyConcept.pdpInstances, JpaPdp::new, new ArrayList<>(0));
152     }
153
154     /**
155      * Authorative constructor.
156      *
157      * @param authorativeConcept the authorative concept to copy from
158      */
159     public JpaPdpSubGroup(@NonNull final PdpSubGroup authorativeConcept) {
160         this.fromAuthorative(authorativeConcept);
161     }
162
163     @Override
164     public PdpSubGroup toAuthorative() {
165         PdpSubGroup pdpSubgroup = new PdpSubGroup();
166
167         pdpSubgroup.setPdpType(getKey().getLocalName());
168
169         pdpSubgroup.setSupportedPolicyTypes(new ArrayList<>());
170         for (PfSearchableKey supportedPolicyTypeKey : supportedPolicyTypes) {
171             ToscaPolicyTypeIdentifier supportedPolicyTypeIdent = new ToscaPolicyTypeIdentifier(
172                     supportedPolicyTypeKey.getName(), supportedPolicyTypeKey.getVersion());
173             pdpSubgroup.getSupportedPolicyTypes().add(supportedPolicyTypeIdent);
174         }
175
176         pdpSubgroup.setPolicies(new ArrayList<>());
177         for (PfConceptKey policyKey : policies) {
178             ToscaPolicyIdentifier toscaPolicyIdentifier = new ToscaPolicyIdentifier();
179             toscaPolicyIdentifier.setName(policyKey.getName());
180             toscaPolicyIdentifier.setVersion(policyKey.getVersion());
181             pdpSubgroup.getPolicies().add(toscaPolicyIdentifier);
182         }
183
184         pdpSubgroup.setCurrentInstanceCount(currentInstanceCount);
185         pdpSubgroup.setDesiredInstanceCount(desiredInstanceCount);
186         pdpSubgroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
187
188         pdpSubgroup.setPdpInstances(new ArrayList<>());
189         for (JpaPdp jpaPdp : pdpInstances) {
190             pdpSubgroup.getPdpInstances().add(jpaPdp.toAuthorative());
191         }
192
193         return pdpSubgroup;
194     }
195
196     @Override
197     public void fromAuthorative(@NonNull final PdpSubGroup pdpSubgroup) {
198         if (this.key == null || this.getKey().isNullKey()) {
199             this.setKey(new PfReferenceKey());
200             getKey().setLocalName(pdpSubgroup.getPdpType());
201         }
202
203         this.supportedPolicyTypes = new ArrayList<>();
204         if (pdpSubgroup.getSupportedPolicyTypes() != null) {
205             for (ToscaPolicyTypeIdentifier supportedPolicyType : pdpSubgroup.getSupportedPolicyTypes()) {
206                 this.supportedPolicyTypes
207                         .add(new PfSearchableKey(supportedPolicyType.getName(), supportedPolicyType.getVersion()));
208             }
209         }
210
211         this.policies = new ArrayList<>();
212         if (pdpSubgroup.getPolicies() != null) {
213             for (ToscaPolicyIdentifier toscaPolicyIdentifier : pdpSubgroup.getPolicies()) {
214                 this.policies
215                         .add(new PfConceptKey(toscaPolicyIdentifier.getName(), toscaPolicyIdentifier.getVersion()));
216             }
217         }
218         this.currentInstanceCount = pdpSubgroup.getCurrentInstanceCount();
219         this.desiredInstanceCount = pdpSubgroup.getDesiredInstanceCount();
220         this.properties =
221                 (pdpSubgroup.getProperties() == null ? null : new LinkedHashMap<>(pdpSubgroup.getProperties()));
222
223         this.pdpInstances = new ArrayList<>();
224         if (pdpSubgroup.getPdpInstances() != null) {
225             for (Pdp pdp : pdpSubgroup.getPdpInstances()) {
226                 JpaPdp jpaPdp = new JpaPdp();
227                 jpaPdp.setKey(new PfReferenceKey(getKey(), pdp.getInstanceId()));
228                 jpaPdp.fromAuthorative(pdp);
229                 this.pdpInstances.add(jpaPdp);
230             }
231         }
232     }
233
234     @Override
235     public List<PfKey> getKeys() {
236         List<PfKey> keyList = getKey().getKeys();
237
238         for (PfSearchableKey ptkey : supportedPolicyTypes) {
239             keyList.add(new PfKeyUse(ptkey));
240         }
241
242         for (PfConceptKey pkey : policies) {
243             keyList.add(new PfKeyUse(pkey));
244         }
245
246         for (JpaPdp jpaPdp : pdpInstances) {
247             keyList.addAll(jpaPdp.getKeys());
248         }
249
250
251         return keyList;
252     }
253
254     @Override
255     public void clean() {
256         key.clean();
257
258         for (PfSearchableKey ptkey : supportedPolicyTypes) {
259             ptkey.clean();
260         }
261
262         for (PfConceptKey pkey : policies) {
263             pkey.clean();
264         }
265
266         if (properties != null) {
267             Map<String, String> cleanedPropertyMap = new LinkedHashMap<>();
268             for (Entry<String, String> propertyEntry : properties.entrySet()) {
269                 cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim());
270             }
271             properties = cleanedPropertyMap;
272         }
273
274         for (JpaPdp jpaPdp : pdpInstances) {
275             jpaPdp.clean();
276         }
277     }
278
279     @Override
280     public BeanValidationResult validate(@NonNull String fieldName) {
281         BeanValidationResult result = new BeanValidationResult(fieldName, this);
282
283         result.addResult(validateKeyNotNull("key", key));
284         result.addResult(validateKeyNotNull("parent of key", key.getParentConceptKey()));
285
286         if (currentInstanceCount < 0) {
287             addResult(result, "currentInstanceCount", currentInstanceCount, "is negative");
288         }
289
290         if (desiredInstanceCount < 0) {
291             addResult(result, "desiredInstanceCount", desiredInstanceCount, "is negative");
292         }
293
294         validateMap(result, "properties", properties, Validated::validateEntryNotBlankNotBlank);
295
296         if (supportedPolicyTypes == null || supportedPolicyTypes.isEmpty()) {
297             addResult(result, "supportedPolicyTypes", supportedPolicyTypes, "is empty");
298         } else {
299             validateList(result, "supportedPolicyTypes", supportedPolicyTypes, Validated::validateNotNull);
300         }
301
302         result.validateNotNull("policies", policies);
303         validateList(result, "policies", policies, Validated::validateNotNull);
304
305         result.validateNotNull("pdpInstances", pdpInstances);
306         validateList(result, "pdpInstances", pdpInstances, Validated::validateNotNull);
307
308         return result;
309     }
310
311     @Override
312     public int compareTo(final PfConcept otherConcept) {
313         if (otherConcept == null) {
314             return -1;
315         }
316         if (this == otherConcept) {
317             return 0;
318         }
319         if (getClass() != otherConcept.getClass()) {
320             return getClass().getName().compareTo(otherConcept.getClass().getName());
321         }
322
323         final JpaPdpSubGroup other = (JpaPdpSubGroup) otherConcept;
324         if (!key.equals(other.key)) {
325             return key.compareTo(other.key);
326         }
327
328         int result = PfUtils.compareObjects(supportedPolicyTypes, other.supportedPolicyTypes);
329         if (result != 0) {
330             return result;
331         }
332
333         result = PfUtils.compareObjects(policies, other.policies);
334         if (result != 0) {
335             return result;
336         }
337
338         if (currentInstanceCount != other.currentInstanceCount) {
339             return currentInstanceCount - other.currentInstanceCount;
340         }
341
342         if (desiredInstanceCount != other.desiredInstanceCount) {
343             return desiredInstanceCount - other.desiredInstanceCount;
344         }
345
346         result = PfUtils.compareObjects(properties, other.properties);
347         if (result != 0) {
348             return result;
349         }
350
351         return PfUtils.compareObjects(pdpInstances, other.pdpInstances);
352     }
353 }