Finish unit test on policy-models
[policy/models.git] / models-pdp / src / main / java / org / onap / policy / models / pdp / persistence / concepts / JpaPdpGroup.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.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
32 import javax.persistence.CascadeType;
33 import javax.persistence.CollectionTable;
34 import javax.persistence.Column;
35 import javax.persistence.ElementCollection;
36 import javax.persistence.EmbeddedId;
37 import javax.persistence.Entity;
38 import javax.persistence.FetchType;
39 import javax.persistence.Inheritance;
40 import javax.persistence.InheritanceType;
41 import javax.persistence.JoinColumn;
42 import javax.persistence.OneToMany;
43 import javax.persistence.Table;
44
45 import lombok.Data;
46 import lombok.EqualsAndHashCode;
47 import lombok.NonNull;
48
49 import org.apache.commons.lang3.ObjectUtils;
50 import org.apache.commons.lang3.StringUtils;
51 import org.onap.policy.common.utils.validation.Assertions;
52 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
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.PfReferenceKey;
58 import org.onap.policy.models.base.PfUtils;
59 import org.onap.policy.models.base.PfValidationMessage;
60 import org.onap.policy.models.base.PfValidationResult;
61 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
62 import org.onap.policy.models.pdp.concepts.PdpGroup;
63 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
64 import org.onap.policy.models.pdp.enums.PdpState;
65
66 /**
67  * Class to represent a PDP group in the database.
68  *
69  * @author Liam Fallon (liam.fallon@est.tech)
70  */
71 @Entity
72 @Table(name = "PdpGroup")
73 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
74 @Data
75 @EqualsAndHashCode(callSuper = false)
76 public class JpaPdpGroup extends PfConcept implements PfAuthorative<PdpGroup> {
77     private static final long serialVersionUID = -357224425637789775L;
78
79     @EmbeddedId
80     private PfConceptKey key;
81
82     @Column
83     private String description;
84
85     @Column
86     private PdpState pdpGroupState;
87
88     @ElementCollection
89     private Map<String, String> properties;
90
91     // @formatter:off
92     @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
93     @CollectionTable(joinColumns = {
94             @JoinColumn(name = "pdpGroupParentKeyName",    referencedColumnName = "parentKeyName"),
95             @JoinColumn(name = "pdpGroupParentKeyVersion", referencedColumnName = "parentKeyVersion"),
96             @JoinColumn(name = "pdpGroupParentLocalName",  referencedColumnName = "parentLocalName"),
97             @JoinColumn(name = "pdpGroupLocalName",        referencedColumnName = "localName")
98         })
99     // @formatter:on
100     private List<JpaPdpSubGroup> pdpSubGroups;
101
102     /**
103      * The Default Constructor creates a {@link JpaPdpGroup} object with a null key.
104      */
105     public JpaPdpGroup() {
106         this(new PfConceptKey());
107     }
108
109     /**
110      * The Key Constructor creates a {@link JpaPdpGroup} object with the given concept key.
111      *
112      * @param key the key
113      */
114     public JpaPdpGroup(@NonNull final PfConceptKey key) {
115         this(key, PdpState.PASSIVE, new ArrayList<>());
116     }
117
118     /**
119      * The Key Constructor creates a {@link JpaPdpGroup} object with all mandatory fields.
120      *
121      * @param key the key
122      * @param pdpGroupState State of the PDP group
123      */
124     public JpaPdpGroup(@NonNull final PfConceptKey key, @NonNull final PdpState pdpGroupState,
125             @NonNull final List<JpaPdpSubGroup> pdpSubGroups) {
126         this.key = key;
127         this.pdpGroupState = pdpGroupState;
128         this.pdpSubGroups = pdpSubGroups;
129     }
130
131     /**
132      * Copy constructor.
133      *
134      * @param copyConcept the concept to copy from
135      */
136     public JpaPdpGroup(@NonNull final JpaPdpGroup copyConcept) {
137         super(copyConcept);
138     }
139
140     /**
141      * Authorative constructor.
142      *
143      * @param authorativeConcept the authorative concept to copy from
144      */
145     public JpaPdpGroup(@NonNull final PdpGroup authorativeConcept) {
146         this.fromAuthorative(authorativeConcept);
147     }
148
149     @Override
150     public PdpGroup toAuthorative() {
151         PdpGroup pdpGroup = new PdpGroup();
152
153         pdpGroup.setName(getKey().getName());
154         pdpGroup.setVersion(getKey().getVersion());
155         pdpGroup.setDescription(description);
156         pdpGroup.setPdpGroupState(pdpGroupState);
157
158         pdpGroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
159
160         pdpGroup.setPdpSubgroups(new ArrayList<>(pdpSubGroups.size()));
161         for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) {
162             pdpGroup.getPdpSubgroups().add(jpaPdpSubgroup.toAuthorative());
163         }
164
165         return pdpGroup;
166     }
167
168     @Override
169     public void fromAuthorative(@NonNull final PdpGroup pdpGroup) {
170         if (this.key == null || this.getKey().isNullKey()) {
171             this.setKey(new PfConceptKey(pdpGroup.getName(), pdpGroup.getVersion()));
172         }
173
174         this.description = pdpGroup.getDescription();
175         this.pdpGroupState = pdpGroup.getPdpGroupState();
176
177         this.properties =
178                 (pdpGroup.getProperties() == null ? null : new LinkedHashMap<>(pdpGroup.getProperties()));
179
180         this.pdpSubGroups = new ArrayList<>();
181         for (PdpSubGroup pdpSubgroup : pdpGroup.getPdpSubgroups()) {
182             JpaPdpSubGroup jpaPdpSubGroup = new JpaPdpSubGroup();
183             jpaPdpSubGroup.setKey(new PfReferenceKey(getKey(), pdpSubgroup.getPdpType()));
184             jpaPdpSubGroup.fromAuthorative(pdpSubgroup);
185             this.pdpSubGroups.add(jpaPdpSubGroup);
186         }
187     }
188
189     @Override
190     public List<PfKey> getKeys() {
191         List<PfKey> keyList = getKey().getKeys();
192
193         for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) {
194             keyList.addAll(jpaPdpSubgroup.getKeys());
195         }
196
197         return keyList;
198     }
199
200     @Override
201     public void clean() {
202         key.clean();
203
204         description = (description == null ? null : description.trim());
205
206         if (properties != null) {
207             Map<String, String> cleanedPropertyMap = new LinkedHashMap<>();
208             for (Entry<String, String> propertyEntry : properties.entrySet()) {
209                 cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim());
210             }
211             properties = cleanedPropertyMap;
212         }
213
214         for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) {
215             jpaPdpSubgroup.clean();
216         }
217     }
218
219     @Override
220     public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
221         PfValidationResult result = resultIn;
222
223         if (key.isNullKey()) {
224             result.addValidationMessage(
225                     new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
226         }
227
228         result = key.validate(result);
229
230         if (description != null && StringUtils.isBlank(description)) {
231             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
232                     "description may not be blank"));
233         }
234
235         if (pdpGroupState == null) {
236             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
237                     "pdpGroupState may not be null"));
238         }
239
240         if (properties != null) {
241             result = validateProperties(result);
242         }
243
244         if (pdpSubGroups == null) {
245             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
246                     "a PDP group must have a list of PDP subgroups"));
247         } else {
248             for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) {
249                 result = jpaPdpSubgroup.validate(result);
250             }
251         }
252
253         return result;
254     }
255
256     /**
257      * Validate the properties.
258      *
259      * @param resultIn the incoming validation results so far
260      * @return the revalidation results including the property validation results
261      */
262     private PfValidationResult validateProperties(PfValidationResult resultIn) {
263         PfValidationResult result = resultIn;
264
265         for (Entry<String, String> propertyEntry : properties.entrySet()) {
266             if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
267                 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
268                         "a property key may not be null or blank"));
269             }
270             if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getValue())) {
271                 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
272                         "a property value may not be null or blank"));
273             }
274         }
275
276         return result;
277     }
278
279     @Override
280     public int compareTo(final PfConcept otherConcept) {
281         if (otherConcept == null) {
282             return -1;
283         }
284         if (this == otherConcept) {
285             return 0;
286         }
287         if (getClass() != otherConcept.getClass()) {
288             return this.getClass().getCanonicalName().compareTo(otherConcept.getClass().getCanonicalName());
289         }
290
291         final JpaPdpGroup other = (JpaPdpGroup) otherConcept;
292         if (!key.equals(other.key)) {
293             return key.compareTo(other.key);
294         }
295
296         int result = ObjectUtils.compare(description, other.description);
297         if (result != 0) {
298             return result;
299         }
300
301         result = ObjectUtils.compare(pdpGroupState, other.pdpGroupState);
302         if (result != 0) {
303             return result;
304         }
305
306         result = PfUtils.compareObjects(properties, other.properties);
307         if (result != 0) {
308             return result;
309         }
310
311         return PfUtils.compareObjects(pdpSubGroups, other.pdpSubGroups);
312     }
313
314     @Override
315     public PfConcept copyTo(@NonNull final PfConcept target) {
316         Assertions.instanceOf(target, JpaPdpGroup.class);
317
318         final JpaPdpGroup copy = ((JpaPdpGroup) target);
319         copy.setKey(new PfConceptKey(key));
320
321         copy.setDescription(description);
322         copy.setPdpGroupState(pdpGroupState);
323         copy.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
324         copy.setPdpSubGroups(PfUtils.mapList(pdpSubGroups, JpaPdpSubGroup::new));
325
326         return copy;
327     }
328 }