diff options
author | liamfallon <liam.fallon@est.tech> | 2019-04-02 23:32:32 +0000 |
---|---|---|
committer | liamfallon <liam.fallon@est.tech> | 2019-04-02 23:32:32 +0000 |
commit | 8054d6dcff521c460954b9e9e203faf65924bfee (patch) | |
tree | a47a47fc5b91f24f7fb7408c359acce4724ec77b /models-pdp/src/main | |
parent | 563ba59d9fb967681216eda454b0be9a3f13607d (diff) |
Add persistence for PDP concepts
This review adds the JPA annotations to PDP group/subgroup and PDP for
persisting to the database.
It also updates the Provider API as requested by other team members.
Issue-ID: POLICY-1095
Change-Id: I8188afb763849ede9680f3751b464d9d76c27196
Signed-off-by: liamfallon <liam.fallon@est.tech>
Diffstat (limited to 'models-pdp/src/main')
6 files changed, 1040 insertions, 18 deletions
diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java index c69679416..a59d1af5a 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java @@ -27,6 +27,8 @@ import java.util.Map; import lombok.Data; import lombok.NoArgsConstructor; + +import org.onap.policy.models.base.PfNameVersion; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.pdp.enums.PdpState; @@ -38,7 +40,7 @@ import org.onap.policy.models.pdp.enums.PdpState; */ @Data @NoArgsConstructor -public class PdpGroup { +public class PdpGroup implements PfNameVersion { private String name; private String version; private String description; diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java index ea1c8ff55..32e0b1a29 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java @@ -20,7 +20,11 @@ package org.onap.policy.models.pdp.concepts; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; + import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -34,4 +38,17 @@ import lombok.ToString; @ToString public class PdpGroups { private List<PdpGroup> groups; + + /** + * Get the contents of this class as a list of PDP group maps. + * @return the PDP groups in a list of maps + */ + public List<Map<String, PdpGroup>> toMapList() { + final Map<String, PdpGroup> pdpGroupMap = new LinkedHashMap<>(); + for (PdpGroup pdpGroup : groups) { + pdpGroupMap.put(pdpGroup.getName() + ':' + pdpGroup.getVersion() , pdpGroup); + } + + return Collections.singletonList(pdpGroupMap); + } } diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdp.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdp.java new file mode 100644 index 000000000..0a9aa5874 --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdp.java @@ -0,0 +1,246 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Model + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.persistence.concepts; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.PfValidationMessage; +import org.onap.policy.models.base.PfValidationResult; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; +import org.onap.policy.models.pdp.concepts.Pdp; +import org.onap.policy.models.pdp.enums.PdpHealthStatus; +import org.onap.policy.models.pdp.enums.PdpState; + +/** + * Class to represent a PDP in the database. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +@Entity +@Table(name = "Pdp") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class JpaPdp extends PfConcept implements PfAuthorative<Pdp>, Serializable { + private static final long serialVersionUID = -357224425637789775L; + + @EmbeddedId + private PfReferenceKey key; + + @Column + private PdpState pdpState; + + @Column + private PdpHealthStatus healthy; + + @Column + private String message; + + /** + * The Default Constructor creates a {@link JpaPdp} object with a null key. + */ + public JpaPdp() { + this(new PfReferenceKey()); + } + + /** + * The Key Constructor creates a {@link JpaPdp} object with the given concept key. + * + * @param key the key + */ + public JpaPdp(@NonNull final PfReferenceKey key) { + this(key, PdpState.PASSIVE, PdpHealthStatus.UNKNOWN); + } + + /** + * The Key Constructor creates a {@link JpaPdp} object with all mandatory fields. + * + * @param key the key + * @param pdpState the state of the PDP + * @param healthy the health state of the PDP + */ + public JpaPdp(@NonNull final PfReferenceKey key, @NonNull final PdpState pdpState, + @NonNull PdpHealthStatus healthy) { + this.key = key; + this.pdpState = pdpState; + this.healthy = healthy; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public JpaPdp(final JpaPdp copyConcept) { + super(copyConcept); + } + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public JpaPdp(final Pdp authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + @Override + public Pdp toAuthorative() { + Pdp pdp = new Pdp(); + + pdp.setInstanceId(key.getLocalName()); + pdp.setPdpState(pdpState); + pdp.setHealthy(healthy); + pdp.setMessage(message); + + return pdp; + } + + @Override + public void fromAuthorative(final Pdp pdp) { + if (this.getKey().isNullKey()) { + this.setKey(new PfReferenceKey()); + getKey().setLocalName(pdp.getInstanceId()); + } + + this.setPdpState(pdp.getPdpState()); + this.setHealthy(pdp.getHealthy()); + this.setMessage(pdp.getMessage()); + } + + @Override + public List<PfKey> getKeys() { + return getKey().getKeys(); + } + + @Override + public void clean() { + key.clean(); + + if (message != null) { + message = message.trim(); + } + } + + @Override + public PfValidationResult validate(final PfValidationResult resultIn) { + PfValidationResult result = resultIn; + + if (key.isNullKey()) { + result.addValidationMessage( + new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key")); + } + + result = key.validate(result); + + if (key.getParentConceptKey().isNullKey()) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "parent of key is a null key")); + } + + if (PfKey.NULL_KEY_NAME.equals(key.getParentLocalName())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "local name of parent of key is null")); + } + + if (pdpState == null) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "PDP state may not be null")); + } + + if (healthy == null) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "PDP health status may not be null")); + } + + if (StringUtils.isBlank(message)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "message may not be blank")); + } + + return result; + } + + @Override + public int compareTo(final PfConcept otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return this.hashCode() - otherConcept.hashCode(); + } + + final JpaPdp other = (JpaPdp) otherConcept; + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + + int result = ObjectUtils.compare(pdpState, other.pdpState); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(healthy, other.healthy); + if (result != 0) { + return result; + } + + return ObjectUtils.compare(message, other.message); + } + + @Override + public PfConcept copyTo(@NonNull final PfConcept target) { + Assertions.instanceOf(target, JpaPdp.class); + + final JpaPdp copy = ((JpaPdp) target); + copy.setKey(new PfReferenceKey(key)); + copy.setPdpState(pdpState); + copy.setHealthy(healthy); + copy.setMessage(message); + + return copy; + } +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java new file mode 100644 index 000000000..9c896a31b --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java @@ -0,0 +1,307 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Model + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.persistence.concepts; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.common.utils.validation.ParameterValidationUtils; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.base.PfValidationMessage; +import org.onap.policy.models.base.PfValidationResult; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.enums.PdpState; + +/** + * Class to represent a PDP group in the database. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +@Entity +@Table(name = "PdpGroup") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class JpaPdpGroup extends PfConcept implements PfAuthorative<PdpGroup> { + private static final long serialVersionUID = -357224425637789775L; + + @EmbeddedId + private PfConceptKey key; + + @Column + private String description; + + @Column + private PdpState pdpGroupState; + + @ElementCollection + private Map<String, String> properties; + + // @formatter:off + @OneToMany + @CollectionTable(joinColumns = { + @JoinColumn(name = "pdpGroupParentKeyName", referencedColumnName = "parentKeyName"), + @JoinColumn(name = "pdpGroupParentKeyVersion", referencedColumnName = "parentKeyVersion"), + @JoinColumn(name = "pdpGroupParentLocalName", referencedColumnName = "parentLocalName"), + @JoinColumn(name = "pdpGroupLocalName", referencedColumnName = "localName") + }) + // @formatter:on + private List<JpaPdpSubGroup> pdpSubGroups; + + /** + * The Default Constructor creates a {@link JpaPdpGroup} object with a null key. + */ + public JpaPdpGroup() { + this(new PfConceptKey()); + } + + /** + * The Key Constructor creates a {@link JpaPdpGroup} object with the given concept key. + * + * @param key the key + */ + public JpaPdpGroup(@NonNull final PfConceptKey key) { + this(key, PdpState.PASSIVE, new ArrayList<>()); + } + + /** + * The Key Constructor creates a {@link JpaPdpGroup} object with all mandatory fields. + * + * @param key the key + * @param pdpGroupState State of the PDP group + */ + public JpaPdpGroup(@NonNull final PfConceptKey key, @NonNull final PdpState pdpGroupState, + @NonNull final List<JpaPdpSubGroup> pdpSubGroups) { + this.key = key; + this.pdpGroupState = pdpGroupState; + this.pdpSubGroups = pdpSubGroups; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public JpaPdpGroup(final JpaPdpGroup copyConcept) { + super(copyConcept); + } + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public JpaPdpGroup(final PdpGroup authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + @Override + public PdpGroup toAuthorative() { + PdpGroup pdpGroup = new PdpGroup(); + + pdpGroup.setName(getKey().getName()); + pdpGroup.setVersion(getKey().getVersion()); + pdpGroup.setDescription(description); + pdpGroup.setPdpGroupState(pdpGroupState); + + pdpGroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties)); + + pdpGroup.setPdpSubgroups(new ArrayList<>(pdpSubGroups.size())); + for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) { + pdpGroup.getPdpSubgroups().add(jpaPdpSubgroup.toAuthorative()); + } + + return pdpGroup; + } + + @Override + public void fromAuthorative(final PdpGroup pdpGroup) { + this.setKey(new PfConceptKey(pdpGroup.getName(), pdpGroup.getVersion())); + + this.description = pdpGroup.getDescription(); + this.pdpGroupState = pdpGroup.getPdpGroupState(); + + this.properties = + (pdpGroup.getProperties() == null ? null : new LinkedHashMap<>(pdpGroup.getProperties())); + + this.pdpSubGroups = new ArrayList<>(); + for (PdpSubGroup pdpSubgroup : pdpGroup.getPdpSubgroups()) { + JpaPdpSubGroup jpaPdpSubGroup = new JpaPdpSubGroup(); + jpaPdpSubGroup.setKey(new PfReferenceKey(getKey(), pdpSubgroup.getPdpType())); + jpaPdpSubGroup.fromAuthorative(pdpSubgroup); + this.pdpSubGroups.add(jpaPdpSubGroup); + } + } + + @Override + public List<PfKey> getKeys() { + List<PfKey> keyList = getKey().getKeys(); + + for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) { + keyList.addAll(jpaPdpSubgroup.getKeys()); + } + + + return keyList; + } + + @Override + public void clean() { + key.clean(); + + description = (description == null ? null : description.trim()); + + if (properties != null) { + Map<String, String> cleanedPropertyMap = new LinkedHashMap<>(); + for (Entry<String, String> propertyEntry : properties.entrySet()) { + cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim()); + } + properties = cleanedPropertyMap; + } + + for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) { + jpaPdpSubgroup.clean(); + } + } + + @Override + public PfValidationResult validate(final PfValidationResult resultIn) { + PfValidationResult result = resultIn; + + if (key.isNullKey()) { + result.addValidationMessage( + new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key")); + } + + result = key.validate(result); + + if (StringUtils.isBlank(description)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "description may not be blank")); + } + + if (properties != null) { + for (Entry<String, String> propertyEntry : properties.entrySet()) { + if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a property key may not be null or blank")); + } + if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getValue())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a property value may not be null or blank")); + } + } + } + + + if (pdpSubGroups == null) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a PDP group must have a list of PDP subgroups")); + } else { + for (JpaPdpSubGroup jpaPdpSubgroup : pdpSubGroups) { + result = jpaPdpSubgroup.validate(result); + } + } + + return result; + } + + @Override + public int compareTo(final PfConcept otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return this.getClass().getCanonicalName().compareTo(otherConcept.getClass().getCanonicalName()); + } + + final JpaPdpGroup other = (JpaPdpGroup) otherConcept; + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + + int result = ObjectUtils.compare(description, other.description); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(pdpGroupState, other.pdpGroupState); + if (result != 0) { + return result; + } + + result = PfUtils.compareObjects(properties, other.properties); + if (result != 0) { + return result; + } + + return PfUtils.compareObjects(pdpSubGroups, other.pdpSubGroups); + } + + @Override + public PfConcept copyTo(@NonNull final PfConcept target) { + Assertions.instanceOf(target, JpaPdpGroup.class); + + final JpaPdpGroup copy = ((JpaPdpGroup) target); + copy.setKey(new PfConceptKey(key)); + + copy.setDescription(description); + copy.setPdpGroupState(pdpGroupState); + copy.setProperties(properties == null ? null : new LinkedHashMap<>(properties)); + copy.setPdpSubGroups(PfUtils.mapList(pdpSubGroups, JpaPdpSubGroup::new)); + + return copy; + } +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpSubGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpSubGroup.java new file mode 100644 index 000000000..5164d3418 --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpSubGroup.java @@ -0,0 +1,406 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Model + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.persistence.concepts; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.common.utils.validation.ParameterValidationUtils; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfKeyUse; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.base.PfValidationMessage; +import org.onap.policy.models.base.PfValidationResult; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; +import org.onap.policy.models.pdp.concepts.Pdp; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.PolicyTypeIdent; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; + +/** + * Class to represent a PDP subgroup in the database. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +@Entity +@Table(name = "PdpSubGroup") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class JpaPdpSubGroup extends PfConcept implements PfAuthorative<PdpSubGroup> { + private static final long serialVersionUID = -357224425637789775L; + + @EmbeddedId + private PfReferenceKey key; + + @ElementCollection + private List<PfConceptKey> supportedPolicyTypes; + + @ElementCollection + private List<PfConceptKey> policies; + + @Column + private int currentInstanceCount; + + @Column + private int desiredInstanceCount; + + @ElementCollection + private Map<String, String> properties; + + // @formatter:ofF + @OneToMany + @CollectionTable(joinColumns = { + @JoinColumn(name = "pdpSubGroupParentKeyName", referencedColumnName = "parentKeyName"), + @JoinColumn(name = "pdpSubGroupParentKeyVersion", referencedColumnName = "parentKeyVersion"), + @JoinColumn(name = "pdpSubGroupParentLocalName", referencedColumnName = "parentLocalName"), + @JoinColumn(name = "pdpSubGroupLocalName", referencedColumnName = "localName") + }) + // formatter:on + private List<JpaPdp> pdpInstances; + + /** + * The Default Constructor creates a {@link JpaPdpSubGroup} object with a null key. + */ + public JpaPdpSubGroup() { + this(new PfReferenceKey()); + } + + /** + * The Key Constructor creates a {@link JpaPdpSubGroup} object with the given concept key. + * + * @param key the key + */ + public JpaPdpSubGroup(@NonNull final PfReferenceKey key) { + this(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + } + + /** + * The Key Constructor creates a {@link JpaPdpSubGroup} object with all mandatory fields. + * + * @param key the key + * @param supportedPolicyTypes Supported policy types + * @param policies policies deployed on this PDP subgroups + * @param pdpInstances the PDP instances on this PDP subgroups + */ + public JpaPdpSubGroup(@NonNull final PfReferenceKey key, @NonNull final List<PfConceptKey> supportedPolicyTypes, + @NonNull List<PfConceptKey> policies, @NonNull final List<JpaPdp> pdpInstances) { + this.key = key; + this.supportedPolicyTypes = supportedPolicyTypes; + this.policies = policies; + this.pdpInstances = pdpInstances; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public JpaPdpSubGroup(final JpaPdpSubGroup copyConcept) { + super(copyConcept); + } + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public JpaPdpSubGroup(final PdpSubGroup authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + @Override + public PdpSubGroup toAuthorative() { + PdpSubGroup pdpSubgroup = new PdpSubGroup(); + + pdpSubgroup.setPdpType(getKey().getLocalName()); + + pdpSubgroup.setSupportedPolicyTypes(new ArrayList<>()); + for (PfConceptKey supportedPolicyTypeKey : supportedPolicyTypes) { + PolicyTypeIdent supportedPolicyTypeIdent = + new PolicyTypeIdent(supportedPolicyTypeKey.getName(), supportedPolicyTypeKey.getVersion()); + pdpSubgroup.getSupportedPolicyTypes().add(supportedPolicyTypeIdent); + } + + pdpSubgroup.setPolicies(new ArrayList<>()); + for (PfConceptKey policyKey : policies) { + ToscaPolicy toscaPolicy = new ToscaPolicy(); + toscaPolicy.setName(policyKey.getName()); + toscaPolicy.setVersion(policyKey.getVersion()); + pdpSubgroup.getPolicies().add(toscaPolicy); + } + + pdpSubgroup.setCurrentInstanceCount(currentInstanceCount); + pdpSubgroup.setDesiredInstanceCount(desiredInstanceCount); + pdpSubgroup.setProperties(properties == null ? null : new LinkedHashMap<>(properties)); + + pdpSubgroup.setPdpInstances(new ArrayList<>()); + for (JpaPdp jpaPdp : pdpInstances) { + pdpSubgroup.getPdpInstances().add(jpaPdp.toAuthorative()); + } + + return pdpSubgroup; + } + + @Override + public void fromAuthorative(final PdpSubGroup pdpSubgroup) { + if (this.getKey().isNullKey()) { + this.setKey(new PfReferenceKey()); + getKey().setLocalName(pdpSubgroup.getPdpType()); + } + + this.supportedPolicyTypes = new ArrayList<>(); + for (PolicyTypeIdent supportedPolicyType : pdpSubgroup.getSupportedPolicyTypes()) { + this.supportedPolicyTypes + .add(new PfConceptKey(supportedPolicyType.getName(), supportedPolicyType.getVersion())); + } + + + this.policies = new ArrayList<>(); + for (ToscaPolicy toscaPolicy : pdpSubgroup.getPolicies()) { + this.policies.add(new PfConceptKey(toscaPolicy.getName(), toscaPolicy.getVersion())); + } + + this.currentInstanceCount = pdpSubgroup.getCurrentInstanceCount(); + this.desiredInstanceCount = pdpSubgroup.getDesiredInstanceCount(); + this.properties = + (pdpSubgroup.getProperties() == null ? null : new LinkedHashMap<>(pdpSubgroup.getProperties())); + + this.pdpInstances = new ArrayList<>(); + for (Pdp pdp : pdpSubgroup.getPdpInstances()) { + JpaPdp jpaPdp = new JpaPdp(); + jpaPdp.setKey(new PfReferenceKey(getKey(), pdp.getInstanceId())); + jpaPdp.fromAuthorative(pdp); + this.pdpInstances.add(jpaPdp); + } + } + + @Override + public List<PfKey> getKeys() { + List<PfKey> keyList = getKey().getKeys(); + + for (PfConceptKey ptkey : supportedPolicyTypes) { + keyList.add(new PfKeyUse(ptkey)); + } + + for (PfConceptKey pkey : policies) { + keyList.add(new PfKeyUse(pkey)); + } + + for (JpaPdp jpaPdp : pdpInstances) { + keyList.addAll(jpaPdp.getKeys()); + } + + + return keyList; + } + + @Override + public void clean() { + key.clean(); + + for (PfConceptKey ptkey : supportedPolicyTypes) { + ptkey.clean(); + } + + for (PfConceptKey pkey : policies) { + pkey.clean(); + } + + if (properties != null) { + Map<String, String> cleanedPropertyMap = new LinkedHashMap<>(); + for (Entry<String, String> propertyEntry : properties.entrySet()) { + cleanedPropertyMap.put(propertyEntry.getKey().trim(), propertyEntry.getValue().trim()); + } + properties = cleanedPropertyMap; + } + + for (JpaPdp jpaPdp : pdpInstances) { + jpaPdp.clean(); + } + } + + @Override + public PfValidationResult validate(final PfValidationResult resultIn) { + PfValidationResult result = resultIn; + + if (key.isNullKey()) { + result.addValidationMessage( + new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key")); + } + + result = key.validate(result); + + if (key.getParentConceptKey().isNullKey()) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "parent of key is a null key")); + } + + if (currentInstanceCount < 0) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "the current instance count of a PDP group may not be negative")); + } + + if (desiredInstanceCount < 0) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "the desired instance count of a PDP group may not be negative")); + } + + if (properties != null) { + for (Entry<String, String> propertyEntry : properties.entrySet()) { + if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a property key may not be null or blank")); + } + if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getValue())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a property value may not be null or blank")); + } + } + } + + + return validateSubConcepts(result); + } + + /** + * Validate collections of sub concepts. + * + * @param result the result in which to store the validation result + * @return the validation result including the results of this method + */ + private PfValidationResult validateSubConcepts(PfValidationResult result) { + if (supportedPolicyTypes == null || supportedPolicyTypes.isEmpty()) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a PDP subgroup must support at least one policy type")); + } else { + for (PfConceptKey supportedPolicyType : supportedPolicyTypes) { + result = supportedPolicyType.validate(result); + } + } + + if (policies == null) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a PDP subgroup must have a list of policies")); + } else { + for (PfConceptKey policyKey : policies) { + result = policyKey.validate(result); + } + } + + if (pdpInstances == null) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "a PDP subgroup must have a list of PDPs")); + } else { + for (JpaPdp jpaPdp : pdpInstances) { + result = jpaPdp.validate(result); + } + } + + return result; + } + + @Override + public int compareTo(final PfConcept otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return this.hashCode() - otherConcept.hashCode(); + } + + final JpaPdpSubGroup other = (JpaPdpSubGroup) otherConcept; + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + + int result = PfUtils.compareObjects(supportedPolicyTypes, other.supportedPolicyTypes); + if (result != 0) { + return result; + } + + result = PfUtils.compareObjects(policies, other.policies); + if (result != 0) { + return result; + } + + if (currentInstanceCount != other.currentInstanceCount) { + return currentInstanceCount - other.currentInstanceCount; + } + + if (desiredInstanceCount != other.desiredInstanceCount) { + return desiredInstanceCount - other.desiredInstanceCount; + } + + result = PfUtils.compareObjects(properties, other.properties); + if (result != 0) { + return result; + } + + return PfUtils.compareObjects(pdpInstances, other.pdpInstances); + } + + @Override + public PfConcept copyTo(@NonNull final PfConcept target) { + Assertions.instanceOf(target, JpaPdpSubGroup.class); + + final JpaPdpSubGroup copy = ((JpaPdpSubGroup) target); + copy.setKey(new PfReferenceKey(key)); + + copy.setSupportedPolicyTypes(PfUtils.mapList(supportedPolicyTypes, PfConceptKey::new)); + copy.setPolicies(PfUtils.mapList(policies, PfConceptKey::new)); + copy.setCurrentInstanceCount(currentInstanceCount); + copy.setDesiredInstanceCount(desiredInstanceCount); + copy.setProperties(properties == null ? null : new LinkedHashMap<>(properties)); + copy.setPdpInstances(PfUtils.mapList(pdpInstances, JpaPdp::new)); + + return copy; + } +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java index 6af2d211b..a32f5a4a9 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java @@ -21,20 +21,28 @@ package org.onap.policy.models.pdp.persistence.provider; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import javax.ws.rs.core.Response; + import lombok.NonNull; import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.base.PfValidationResult; import org.onap.policy.models.dao.PfDao; import org.onap.policy.models.pdp.concepts.PdpGroup; -import org.onap.policy.models.pdp.concepts.PdpGroups; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class provides the provision of information on PAP concepts in the database to callers. @@ -42,6 +50,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; * @author Liam Fallon (liam.fallon@est.tech) */ public class PdpProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(PdpProvider.class); + /** * Get PDP groups. * @@ -51,9 +61,19 @@ public class PdpProvider { * @return the PDP groups found * @throws PfModelException on errors getting PDP groups */ - public PdpGroups getPdpGroups(@NonNull final PfDao dao, final String name, final String version) + public List<PdpGroup> getPdpGroups(@NonNull final PfDao dao, final String name, final String version) throws PfModelException { - return new PdpGroups(); + + PfConceptKey jpaPdpGroupKey = new PfConceptKey(name, version); + JpaPdpGroup jpaPdpGroup = dao.get(JpaPdpGroup.class, jpaPdpGroupKey); + + if (jpaPdpGroup != null) { + return Collections.singletonList(jpaPdpGroup.toAuthorative()); + } else { + String errorMessage = "PDP group not found: " + jpaPdpGroupKey.getId(); + LOGGER.warn(errorMessage); + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } } /** @@ -64,21 +84,21 @@ public class PdpProvider { * @return the PDP groups found * @throws PfModelException on errors getting policies */ - public PdpGroups getLatestPdpGroups(@NonNull final PfDao dao, final String name) throws PfModelException { - return new PdpGroups(); + public List<PdpGroup> getLatestPdpGroups(@NonNull final PfDao dao, final String name) throws PfModelException { + return new ArrayList<>(); } /** * Get a filtered list of PDP groups. * * @param dao the DAO to use to access the database - * @param pdpType The PDP type filter for the returned PDP groups + * @param pdpType The PDP type filter for the returned PDP groups, null to get policy types across PDP subgroups * @param supportedPolicyTypes a list of policy type name/version pairs that the PDP groups must support. * @return the PDP groups found */ - public PdpGroups getFilteredPdpGroups(@NonNull final PfDao dao, @NonNull final String pdpType, + public List<PdpGroup> getFilteredPdpGroups(@NonNull final PfDao dao, final String pdpType, @NonNull final List<Pair<String, String>> supportedPolicyTypes) { - return new PdpGroups(); + return new ArrayList<>(); } /** @@ -89,9 +109,33 @@ public class PdpProvider { * @return the PDP groups created * @throws PfModelException on errors creating PDP groups */ - public PdpGroups createPdpGroups(@NonNull final PfDao dao, @NonNull final PdpGroups pdpGroups) + public List<PdpGroup> createPdpGroups(@NonNull final PfDao dao, @NonNull final List<PdpGroup> pdpGroups) throws PfModelException { - return new PdpGroups(); + + for (PdpGroup pdpGroup : pdpGroups) { + JpaPdpGroup jpaPdpGroup = new JpaPdpGroup();; + jpaPdpGroup.fromAuthorative(pdpGroup); + + PfValidationResult validationResult = jpaPdpGroup.validate(new PfValidationResult()); + if (!validationResult.isOk()) { + String errorMessage = "pdp group \"" + jpaPdpGroup.getId() + "\" is not valid \n" + validationResult; + LOGGER.warn(errorMessage); + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + + dao.create(jpaPdpGroup); + } + + // Return the created PDP groups + List<PdpGroup> returnPdpGroups = new ArrayList<>(); + + for (PdpGroup pdpGroup : pdpGroups) { + JpaPdpGroup jpaPdpGroup = + dao.get(JpaPdpGroup.class, new PfConceptKey(pdpGroup.getName(), pdpGroup.getVersion())); + returnPdpGroups.add(jpaPdpGroup.toAuthorative()); + } + + return returnPdpGroups; } /** @@ -102,9 +146,9 @@ public class PdpProvider { * @return the PDP groups updated * @throws PfModelException on errors updating PDP groups */ - public PdpGroups updatePdpGroups(@NonNull final PfDao dao, @NonNull final PdpGroups pdpGroups) + public List<PdpGroup> updatePdpGroups(@NonNull final PfDao dao, @NonNull final List<PdpGroup> pdpGroups) throws PfModelException { - return new PdpGroups(); + return new ArrayList<>(); } @@ -163,7 +207,7 @@ public class PdpProvider { */ public void updatePdpStatistics(@NonNull final PfDao dao, @NonNull final String pdpGroupName, @NonNull final String pdpGroupVersion, @NonNull final String pdpType, @NonNull final String pdpInstanceId, - @NonNull final PdpStatistics pdppStatistics) throws PfModelException { + @NonNull final PdpStatistics pdppStatistics) throws PfModelException { // Not implemented yet } @@ -171,12 +215,12 @@ public class PdpProvider { * Get deployed policies. * * @param dao the DAO to use to access the database - * @param name the name of the policy to get, null to get all policies - * @return the policies deployed as a map of policy lists keyed by PDP group + * @param name the name of the policy to get deployed policies for, null to get all deployed policies + * @return the policies deployed as a map of policy lists keyed by PDP group name and version * @throws PfModelException on errors getting policies */ - public Map<PdpGroup, List<ToscaPolicy>> getDeployedPolicyList(@NonNull final PfDao dao, final String name) - throws PfModelException { + public Map<Pair<String, String>, List<ToscaPolicy>> getDeployedPolicyList(@NonNull final PfDao dao, + final String name) throws PfModelException { return new LinkedHashMap<>(); } } |