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