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