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.CollectionTable;
33 import javax.persistence.Column;
34 import javax.persistence.ElementCollection;
35 import javax.persistence.EmbeddedId;
36 import javax.persistence.Entity;
37 import javax.persistence.Inheritance;
38 import javax.persistence.InheritanceType;
39 import javax.persistence.JoinColumn;
40 import javax.persistence.OneToMany;
41 import javax.persistence.Table;
44 import lombok.EqualsAndHashCode;
45 import lombok.NonNull;
47 import org.onap.policy.common.utils.validation.Assertions;
48 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
49 import org.onap.policy.models.base.PfAuthorative;
50 import org.onap.policy.models.base.PfConcept;
51 import org.onap.policy.models.base.PfConceptKey;
52 import org.onap.policy.models.base.PfKey;
53 import org.onap.policy.models.base.PfKeyUse;
54 import org.onap.policy.models.base.PfReferenceKey;
55 import org.onap.policy.models.base.PfUtils;
56 import org.onap.policy.models.base.PfValidationMessage;
57 import org.onap.policy.models.base.PfValidationResult;
58 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
59 import org.onap.policy.models.pdp.concepts.Pdp;
60 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
61 import org.onap.policy.models.pdp.concepts.ToscaPolicyIdentifier;
62 import org.onap.policy.models.pdp.concepts.ToscaPolicyTypeIdentifier;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
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;
98 @CollectionTable(joinColumns = {
99 @JoinColumn(name = "pdpSubGroupParentKeyName", referencedColumnName = "parentKeyName"),
100 @JoinColumn(name = "pdpSubGroupParentKeyVersion", referencedColumnName = "parentKeyVersion"),
101 @JoinColumn(name = "pdpSubGroupParentLocalName", referencedColumnName = "parentLocalName"),
102 @JoinColumn(name = "pdpSubGroupLocalName", referencedColumnName = "localName")
105 private List<JpaPdp> pdpInstances;
108 * The Default Constructor creates a {@link JpaPdpSubGroup} object with a null key.
110 public JpaPdpSubGroup() {
111 this(new PfReferenceKey());
115 * The Key Constructor creates a {@link JpaPdpSubGroup} object with the given concept key.
119 public JpaPdpSubGroup(@NonNull final PfReferenceKey key) {
120 this(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
124 * The Key Constructor creates a {@link JpaPdpSubGroup} object with all mandatory fields.
127 * @param supportedPolicyTypes Supported policy types
128 * @param policies policies deployed on this PDP subgroups
129 * @param pdpInstances the PDP instances on this PDP subgroups
131 public JpaPdpSubGroup(@NonNull final PfReferenceKey key, @NonNull final List<PfConceptKey> supportedPolicyTypes,
132 @NonNull List<PfConceptKey> policies, @NonNull final List<JpaPdp> pdpInstances) {
134 this.supportedPolicyTypes = supportedPolicyTypes;
135 this.policies = policies;
136 this.pdpInstances = pdpInstances;
142 * @param copyConcept the concept to copy from
144 public JpaPdpSubGroup(final JpaPdpSubGroup copyConcept) {
149 * Authorative constructor.
151 * @param authorativeConcept the authorative concept to copy from
153 public JpaPdpSubGroup(final PdpSubGroup authorativeConcept) {
154 this.fromAuthorative(authorativeConcept);
158 public PdpSubGroup toAuthorative() {
159 PdpSubGroup pdpSubgroup = new PdpSubGroup();
161 pdpSubgroup.setPdpType(getKey().getLocalName());
163 pdpSubgroup.setSupportedPolicyTypes(new ArrayList<>());
164 for (PfConceptKey supportedPolicyTypeKey : supportedPolicyTypes) {
165 ToscaPolicyTypeIdentifier supportedPolicyTypeIdent = new ToscaPolicyTypeIdentifier(
166 supportedPolicyTypeKey.getName(), supportedPolicyTypeKey.getVersion());
167 pdpSubgroup.getSupportedPolicyTypes().add(supportedPolicyTypeIdent);
170 pdpSubgroup.setPolicies(new ArrayList<>());
171 for (PfConceptKey policyKey : policies) {
172 ToscaPolicyIdentifier toscaPolicyIdentifier = new ToscaPolicyIdentifier();
173 toscaPolicyIdentifier.setName(policyKey.getName());
174 toscaPolicyIdentifier.setVersion(policyKey.getVersion());
175 pdpSubgroup.getPolicies().add(toscaPolicyIdentifier);
178 pdpSubgroup.setCurrentInstanceCount(currentInstanceCount);
179 pdpSubgroup.setDesiredInstanceCount(desiredInstanceCount);
180 pdpSubgroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
182 pdpSubgroup.setPdpInstances(new ArrayList<>());
183 for (JpaPdp jpaPdp : pdpInstances) {
184 pdpSubgroup.getPdpInstances().add(jpaPdp.toAuthorative());
191 public void fromAuthorative(final PdpSubGroup pdpSubgroup) {
192 if (this.getKey().isNullKey()) {
193 this.setKey(new PfReferenceKey());
194 getKey().setLocalName(pdpSubgroup.getPdpType());
197 this.supportedPolicyTypes = new ArrayList<>();
198 for (ToscaPolicyTypeIdentifier supportedPolicyType : pdpSubgroup.getSupportedPolicyTypes()) {
199 this.supportedPolicyTypes
200 .add(new PfConceptKey(supportedPolicyType.getName(), supportedPolicyType.getVersion()));
204 this.policies = new ArrayList<>();
205 for (ToscaPolicyIdentifier toscaPolicyIdentifier : pdpSubgroup.getPolicies()) {
206 this.policies.add(new PfConceptKey(toscaPolicyIdentifier.getName(), toscaPolicyIdentifier.getVersion()));
209 this.currentInstanceCount = pdpSubgroup.getCurrentInstanceCount();
210 this.desiredInstanceCount = pdpSubgroup.getDesiredInstanceCount();
212 (pdpSubgroup.getProperties() == null ? null : new LinkedHashMap<>(pdpSubgroup.getProperties()));
214 this.pdpInstances = new ArrayList<>();
215 for (Pdp pdp : pdpSubgroup.getPdpInstances()) {
216 JpaPdp jpaPdp = new JpaPdp();
217 jpaPdp.setKey(new PfReferenceKey(getKey(), pdp.getInstanceId()));
218 jpaPdp.fromAuthorative(pdp);
219 this.pdpInstances.add(jpaPdp);
224 public List<PfKey> getKeys() {
225 List<PfKey> keyList = getKey().getKeys();
227 for (PfConceptKey ptkey : supportedPolicyTypes) {
228 keyList.add(new PfKeyUse(ptkey));
231 for (PfConceptKey pkey : policies) {
232 keyList.add(new PfKeyUse(pkey));
235 for (JpaPdp jpaPdp : pdpInstances) {
236 keyList.addAll(jpaPdp.getKeys());
244 public void clean() {
247 for (PfConceptKey ptkey : supportedPolicyTypes) {
251 for (PfConceptKey pkey : policies) {
255 if (properties != null) {
256 Map<String, String> cleanedPropertyMap = new LinkedHashMap<>();
257 for (Entry<String, String> propertyEntry : properties.entrySet()) {
258 cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim());
260 properties = cleanedPropertyMap;
263 for (JpaPdp jpaPdp : pdpInstances) {
269 public PfValidationResult validate(final PfValidationResult resultIn) {
270 PfValidationResult result = resultIn;
272 if (key.isNullKey()) {
273 result.addValidationMessage(
274 new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
277 result = key.validate(result);
279 if (key.getParentConceptKey().isNullKey()) {
280 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
281 "parent of key is a null key"));
284 if (currentInstanceCount < 0) {
285 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
286 "the current instance count of a PDP group may not be negative"));
289 if (desiredInstanceCount < 0) {
290 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
291 "the desired instance count of a PDP group may not be negative"));
294 if (properties != null) {
295 for (Entry<String, String> propertyEntry : properties.entrySet()) {
296 if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
297 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
298 "a property key may not be null or blank"));
300 if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getValue())) {
301 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
302 "a property value may not be null or blank"));
308 return validateSubConcepts(result);
312 * Validate collections of sub concepts.
314 * @param result the result in which to store the validation result
315 * @return the validation result including the results of this method
317 private PfValidationResult validateSubConcepts(PfValidationResult result) {
318 if (supportedPolicyTypes == null || supportedPolicyTypes.isEmpty()) {
319 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
320 "a PDP subgroup must support at least one policy type"));
322 for (PfConceptKey supportedPolicyType : supportedPolicyTypes) {
323 result = supportedPolicyType.validate(result);
327 if (policies == null) {
328 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
329 "a PDP subgroup must have a list of policies"));
331 for (PfConceptKey policyKey : policies) {
332 result = policyKey.validate(result);
336 if (pdpInstances == null) {
337 result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
338 "a PDP subgroup must have a list of PDPs"));
340 for (JpaPdp jpaPdp : pdpInstances) {
341 result = jpaPdp.validate(result);
349 public int compareTo(final PfConcept otherConcept) {
350 if (otherConcept == null) {
353 if (this == otherConcept) {
356 if (getClass() != otherConcept.getClass()) {
357 return this.hashCode() - otherConcept.hashCode();
360 final JpaPdpSubGroup other = (JpaPdpSubGroup) otherConcept;
361 if (!key.equals(other.key)) {
362 return key.compareTo(other.key);
365 int result = PfUtils.compareObjects(supportedPolicyTypes, other.supportedPolicyTypes);
370 result = PfUtils.compareObjects(policies, other.policies);
375 if (currentInstanceCount != other.currentInstanceCount) {
376 return currentInstanceCount - other.currentInstanceCount;
379 if (desiredInstanceCount != other.desiredInstanceCount) {
380 return desiredInstanceCount - other.desiredInstanceCount;
383 result = PfUtils.compareObjects(properties, other.properties);
388 return PfUtils.compareObjects(pdpInstances, other.pdpInstances);
392 public PfConcept copyTo(@NonNull final PfConcept target) {
393 Assertions.instanceOf(target, JpaPdpSubGroup.class);
395 final JpaPdpSubGroup copy = ((JpaPdpSubGroup) target);
396 copy.setKey(new PfReferenceKey(key));
398 copy.setSupportedPolicyTypes(PfUtils.mapList(supportedPolicyTypes, PfConceptKey::new));
399 copy.setPolicies(PfUtils.mapList(policies, PfConceptKey::new));
400 copy.setCurrentInstanceCount(currentInstanceCount);
401 copy.setDesiredInstanceCount(desiredInstanceCount);
402 copy.setProperties(properties == null ? null : new LinkedHashMap<>(properties));
403 copy.setPdpInstances(PfUtils.mapList(pdpInstances, JpaPdp::new));