2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * SPDX-License-Identifier: Apache-2.0
21 * ============LICENSE_END=========================================================
24 package org.onap.policy.models.pdp.persistence.concepts;
26 import java.util.ArrayList;
27 import java.util.LinkedHashMap;
28 import java.util.List;
30 import java.util.Map.Entry;
32 import javax.persistence.CascadeType;
33 import javax.persistence.Column;
34 import javax.persistence.ElementCollection;
35 import javax.persistence.EmbeddedId;
36 import javax.persistence.Entity;
37 import javax.persistence.FetchType;
38 import javax.persistence.Inheritance;
39 import javax.persistence.InheritanceType;
40 import javax.persistence.JoinColumn;
41 import javax.persistence.JoinTable;
42 import javax.persistence.OneToMany;
43 import javax.persistence.Table;
45 import lombok.EqualsAndHashCode;
46 import lombok.NonNull;
48 import org.onap.policy.common.utils.validation.Assertions;
49 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
50 import org.onap.policy.models.base.PfAuthorative;
51 import org.onap.policy.models.base.PfConcept;
52 import org.onap.policy.models.base.PfConceptKey;
53 import org.onap.policy.models.base.PfKey;
54 import org.onap.policy.models.base.PfKeyUse;
55 import org.onap.policy.models.base.PfReferenceKey;
56 import org.onap.policy.models.base.PfUtils;
57 import org.onap.policy.models.base.PfValidationMessage;
58 import org.onap.policy.models.base.PfValidationResult;
59 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
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.ToscaPolicyIdentifier;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
66 * Class to represent a PDP subgroup in the database.
68 * @author Liam Fallon (liam.fallon@est.tech)
71 @Table(name = "PdpSubGroup")
72 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
74 @EqualsAndHashCode(callSuper = false)
75 public class JpaPdpSubGroup extends PfConcept implements PfAuthorative<PdpSubGroup> {
76 private static final long serialVersionUID = -357224425637789775L;
79 private PfReferenceKey key;
82 private List<PfConceptKey> supportedPolicyTypes;
85 private List<PfConceptKey> policies;
88 private int currentInstanceCount;
91 private int desiredInstanceCount;
94 private Map<String, String> properties;
97 @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
100 @JoinColumn(name = "pdpParentKeyName", referencedColumnName = "parentKeyName"),
101 @JoinColumn(name = "pdpParentKeyVersion", referencedColumnName = "parentKeyVersion"),
102 @JoinColumn(name = "pdpParentLocalName", referencedColumnName = "parentLocalName"),
103 @JoinColumn(name = "pdpLocalName", referencedColumnName = "localName")
107 private List<JpaPdp> pdpInstances;
110 * The Default Constructor creates a {@link JpaPdpSubGroup} object with a null key.
112 public JpaPdpSubGroup() {
113 this(new PfReferenceKey());
117 * The Key Constructor creates a {@link JpaPdpSubGroup} object with the given concept key.
121 public JpaPdpSubGroup(@NonNull final PfReferenceKey key) {
122 this(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
126 * The Key Constructor creates a {@link JpaPdpSubGroup} object with all mandatory fields.
129 * @param supportedPolicyTypes Supported policy types
130 * @param policies policies deployed on this PDP subgroups
131 * @param pdpInstances the PDP instances on this PDP subgroups
133 public JpaPdpSubGroup(@NonNull final PfReferenceKey key, @NonNull final List<PfConceptKey> supportedPolicyTypes,
134 @NonNull List<PfConceptKey> policies, @NonNull final List<JpaPdp> pdpInstances) {
136 this.supportedPolicyTypes = supportedPolicyTypes;
137 this.policies = policies;
138 this.pdpInstances = pdpInstances;
144 * @param copyConcept the concept to copy from
146 public JpaPdpSubGroup(@NonNull final JpaPdpSubGroup copyConcept) {
151 * Authorative constructor.
153 * @param authorativeConcept the authorative concept to copy from
155 public JpaPdpSubGroup(@NonNull final PdpSubGroup authorativeConcept) {
156 this.fromAuthorative(authorativeConcept);
160 public PdpSubGroup toAuthorative() {
161 PdpSubGroup pdpSubgroup = new PdpSubGroup();
163 pdpSubgroup.setPdpType(getKey().getLocalName());
165 pdpSubgroup.setSupportedPolicyTypes(new ArrayList<>());
166 for (PfConceptKey supportedPolicyTypeKey : supportedPolicyTypes) {
167 ToscaPolicyTypeIdentifier supportedPolicyTypeIdent = new ToscaPolicyTypeIdentifier(
168 supportedPolicyTypeKey.getName(), supportedPolicyTypeKey.getVersion());
169 pdpSubgroup.getSupportedPolicyTypes().add(supportedPolicyTypeIdent);
172 pdpSubgroup.setPolicies(new ArrayList<>());
173 for (PfConceptKey policyKey : policies) {
174 ToscaPolicyIdentifier toscaPolicyIdentifier = new ToscaPolicyIdentifier();
175 toscaPolicyIdentifier.setName(policyKey.getName());
176 toscaPolicyIdentifier.setVersion(policyKey.getVersion());
177 pdpSubgroup.getPolicies().add(toscaPolicyIdentifier);
180 pdpSubgroup.setCurrentInstanceCount(currentInstanceCount);
181 pdpSubgroup.setDesiredInstanceCount(desiredInstanceCount);
182 pdpSubgroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
184 pdpSubgroup.setPdpInstances(new ArrayList<>());
185 for (JpaPdp jpaPdp : pdpInstances) {
186 pdpSubgroup.getPdpInstances().add(jpaPdp.toAuthorative());
193 public void fromAuthorative(@NonNull final PdpSubGroup pdpSubgroup) {
194 if (this.key == null || this.getKey().isNullKey()) {
195 this.setKey(new PfReferenceKey());
196 getKey().setLocalName(pdpSubgroup.getPdpType());
199 this.supportedPolicyTypes = new ArrayList<>();
200 if (pdpSubgroup.getSupportedPolicyTypes() != null) {
201 for (ToscaPolicyTypeIdentifier supportedPolicyType : pdpSubgroup.getSupportedPolicyTypes()) {
202 this.supportedPolicyTypes
203 .add(new PfConceptKey(supportedPolicyType.getName(), supportedPolicyType.getVersion()));
207 this.policies = new ArrayList<>();
208 if (pdpSubgroup.getPolicies() != null) {
209 for (ToscaPolicyIdentifier toscaPolicyIdentifier : pdpSubgroup.getPolicies()) {
211 .add(new PfConceptKey(toscaPolicyIdentifier.getName(), toscaPolicyIdentifier.getVersion()));
214 this.currentInstanceCount = pdpSubgroup.getCurrentInstanceCount();
215 this.desiredInstanceCount = pdpSubgroup.getDesiredInstanceCount();
217 (pdpSubgroup.getProperties() == null ? null : new LinkedHashMap<>(pdpSubgroup.getProperties()));
219 this.pdpInstances = new ArrayList<>();
220 if (pdpSubgroup.getPdpInstances() != null) {
221 for (Pdp pdp : pdpSubgroup.getPdpInstances()) {
222 JpaPdp jpaPdp = new JpaPdp();
223 jpaPdp.setKey(new PfReferenceKey(getKey(), pdp.getInstanceId()));
224 jpaPdp.fromAuthorative(pdp);
225 this.pdpInstances.add(jpaPdp);
231 public List<PfKey> getKeys() {
232 List<PfKey> keyList = getKey().getKeys();
234 for (PfConceptKey ptkey : supportedPolicyTypes) {
235 keyList.add(new PfKeyUse(ptkey));
238 for (PfConceptKey pkey : policies) {
239 keyList.add(new PfKeyUse(pkey));
242 for (JpaPdp jpaPdp : pdpInstances) {
243 keyList.addAll(jpaPdp.getKeys());
251 public void clean() {
254 for (PfConceptKey ptkey : supportedPolicyTypes) {
258 for (PfConceptKey pkey : policies) {
262 if (properties != null) {
263 Map<String, String> cleanedPropertyMap = new LinkedHashMap<>();
264 for (Entry<String, String> propertyEntry : properties.entrySet()) {
265 cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim());
267 properties = cleanedPropertyMap;
270 for (JpaPdp jpaPdp : pdpInstances) {
276 public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
277 PfValidationResult result = resultIn;
279 if (key.isNullKey()) {
280 result.addValidationMessage(
281 new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
284 result = key.validate(result);
286 if (key.getParentConceptKey().isNullKey()) {
287 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
288 "parent of key is a null key"));
291 if (currentInstanceCount < 0) {
292 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
293 "the current instance count of a PDP sub group may not be negative"));
296 if (desiredInstanceCount < 0) {
297 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
298 "the desired instance count of a PDP sub group may not be negative"));
301 if (properties != null) {
302 for (Entry<String, String> propertyEntry : properties.entrySet()) {
303 if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
304 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
305 "a property key may not be null or blank"));
307 if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getValue())) {
308 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
309 "a property value may not be null or blank"));
314 return validateSubConcepts(result);
318 * Validate collections of sub concepts.
320 * @param result the result in which to store the validation result
321 * @return the validation result including the results of this method
323 private PfValidationResult validateSubConcepts(PfValidationResult result) {
324 if (supportedPolicyTypes == null || supportedPolicyTypes.isEmpty()) {
325 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
326 "a PDP subgroup must support at least one policy type"));
328 for (PfConceptKey supportedPolicyType : supportedPolicyTypes) {
329 result = supportedPolicyType.validate(result);
333 if (policies == null) {
334 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
335 "a PDP subgroup must have a list of policies"));
337 for (PfConceptKey policyKey : policies) {
338 result = policyKey.validate(result);
342 if (pdpInstances == null) {
343 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
344 "a PDP subgroup must have a list of PDPs"));
346 for (JpaPdp jpaPdp : pdpInstances) {
347 result = jpaPdp.validate(result);
355 public int compareTo(final PfConcept otherConcept) {
356 if (otherConcept == null) {
359 if (this == otherConcept) {
362 if (getClass() != otherConcept.getClass()) {
363 return this.hashCode() - otherConcept.hashCode();
366 final JpaPdpSubGroup other = (JpaPdpSubGroup) otherConcept;
367 if (!key.equals(other.key)) {
368 return key.compareTo(other.key);
371 int result = PfUtils.compareObjects(supportedPolicyTypes, other.supportedPolicyTypes);
376 result = PfUtils.compareObjects(policies, other.policies);
381 if (currentInstanceCount != other.currentInstanceCount) {
382 return currentInstanceCount - other.currentInstanceCount;
385 if (desiredInstanceCount != other.desiredInstanceCount) {
386 return desiredInstanceCount - other.desiredInstanceCount;
389 result = PfUtils.compareObjects(properties, other.properties);
394 return PfUtils.compareObjects(pdpInstances, other.pdpInstances);
398 public PfConcept copyTo(@NonNull final PfConcept target) {
399 Assertions.instanceOf(target, JpaPdpSubGroup.class);
401 final JpaPdpSubGroup copy = ((JpaPdpSubGroup) target);
402 copy.setKey(new PfReferenceKey(key));
404 copy.setSupportedPolicyTypes(PfUtils.mapList(supportedPolicyTypes, PfConceptKey::new));
405 copy.setPolicies(PfUtils.mapList(policies, PfConceptKey::new));
406 copy.setCurrentInstanceCount(currentInstanceCount);
407 copy.setDesiredInstanceCount(desiredInstanceCount);
408 copy.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
409 copy.setPdpInstances(PfUtils.mapList(pdpInstances, JpaPdp::new));