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