summaryrefslogtreecommitdiffstats
path: root/models-pdp
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@est.tech>2019-04-02 23:32:32 +0000
committerliamfallon <liam.fallon@est.tech>2019-04-02 23:32:32 +0000
commit8054d6dcff521c460954b9e9e203faf65924bfee (patch)
treea47a47fc5b91f24f7fb7408c359acce4724ec77b /models-pdp
parent563ba59d9fb967681216eda454b0be9a3f13607d (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')
-rw-r--r--models-pdp/pom.xml10
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java4
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java17
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdp.java246
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java307
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpSubGroup.java406
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java78
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/persistence/provider/PdpProviderTest.java230
-rw-r--r--models-pdp/src/test/resources/META-INF/persistence.xml81
-rw-r--r--models-pdp/src/test/resources/testdata/PdpGroups0.json43
10 files changed, 1404 insertions, 18 deletions
diff --git a/models-pdp/pom.xml b/models-pdp/pom.xml
index 3f423b8c1..aaf9ee48f 100644
--- a/models-pdp/pom.xml
+++ b/models-pdp/pom.xml
@@ -44,5 +44,15 @@
<artifactId>policy-models-tosca</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
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<>();
}
}
diff --git a/models-pdp/src/test/java/org/onap/policy/models/persistence/provider/PdpProviderTest.java b/models-pdp/src/test/java/org/onap/policy/models/persistence/provider/PdpProviderTest.java
new file mode 100644
index 000000000..14990f911
--- /dev/null
+++ b/models-pdp/src/test/java/org/onap/policy/models/persistence/provider/PdpProviderTest.java
@@ -0,0 +1,230 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.persistence.provider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.dao.DaoParameters;
+import org.onap.policy.models.dao.PfDao;
+import org.onap.policy.models.dao.PfDaoFactory;
+import org.onap.policy.models.dao.impl.DefaultPfDao;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.concepts.PolicyTypeIdent;
+import org.onap.policy.models.pdp.enums.PdpHealthStatus;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.pdp.persistence.provider.PdpProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+
+/**
+ * Test the {@link SimpleToscaProvider} class.
+ *
+ * @author Liam Fallon (liam.fallon@est.tech)
+ */
+public class PdpProviderTest {
+ private Connection connection;
+ private PfDao pfDao;
+ private StandardCoder standardCoder;
+
+
+ /**
+ * Set up the DAO towards the database.
+ *
+ * @throws Exception on database errors
+ */
+ @Before
+ public void setupDao() throws Exception {
+ // Use the JDBC UI "jdbc:h2:mem:testdb" to test towards the h2 database
+ // Use the JDBC UI "jdbc:mariadb://localhost:3306/policy" to test towards a locally installed mariadb instance
+ connection = DriverManager.getConnection("jdbc:h2:mem:testdb", "policy", "P01icY");
+
+ final DaoParameters daoParameters = new DaoParameters();
+ daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName());
+
+ // Use the persistence unit ToscaConceptTest to test towards the h2 database
+ // Use the persistence unit ToscaConceptMariaDBTest to test towards a locally installed mariadb instance
+ daoParameters.setPersistenceUnit("ToscaConceptTest");
+
+ pfDao = new PfDaoFactory().createPfDao(daoParameters);
+ pfDao.init(daoParameters);
+ }
+
+ /**
+ * Set up GSON.
+ */
+ @Before
+ public void setupGson() {
+ standardCoder = new StandardCoder();
+ }
+
+ @After
+ public void teardown() throws Exception {
+ pfDao.close();
+ connection.close();
+ }
+
+ @Test
+ public void testPoliciesGet() throws Exception {
+ /*
+ * try { new PdpProvider().gePdpGroupst(null, null); fail("test should throw an exception here"); } catch
+ * (Exception exc) { assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().getPolicies(null, new PfConceptKey());
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().getPolicies(pfDao, null); fail("test should throw an exception here"); }
+ * catch (Exception exc) { assertEquals("policyKey is marked @NonNull but is null", exc.getMessage()); }
+ */
+
+ String originalJson = ResourceUtils.getResourceAsString("testdata/PdpGroups0.json");
+
+ @SuppressWarnings("unchecked")
+ PdpGroups pdpGroups0 = standardCoder.decode(originalJson, PdpGroups.class);
+
+ PdpGroups createdPdpGroups0 = new PdpGroups();
+ createdPdpGroups0.setGroups(new PdpProvider().createPdpGroups(pfDao, pdpGroups0.getGroups()));
+ String createdJson = standardCoder.encode(createdPdpGroups0);
+ assertEquals(originalJson.replaceAll("\\s+", ""), createdJson.replaceAll("\\s+", ""));
+
+ PdpGroups gotPdpGroups0 = new PdpGroups();
+ gotPdpGroups0.setGroups(new PdpProvider().getPdpGroups(pfDao, "PdpGroup0", "1.2.3"));
+
+ String gotJson = standardCoder.encode(gotPdpGroups0);
+
+ assertEquals(originalJson.replaceAll("\\s+", ""), gotJson.replaceAll("\\s+", ""));
+
+ }
+ /*
+ * @Test public void testPolicyCreate() throws Exception { try { new SimpleToscaProvider().createPolicies(null,
+ * null); fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().createPolicies(null, new JpaToscaServiceTemplate());
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().createPolicies(pfDao, null); fail("test should throw an exception here"); } catch
+ * (Exception exc) { assertEquals("serviceTemplate is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * ToscaServiceTemplate toscaServiceTemplate = standardCoder.decode(
+ * ResourceUtils.getResourceAsString("policies/vCPE.policy.monitoring.input.tosca.json"),
+ * ToscaServiceTemplate.class);
+ *
+ * JpaToscaServiceTemplate originalServiceTemplate = new JpaToscaServiceTemplate();
+ * originalServiceTemplate.fromAuthorative(toscaServiceTemplate);
+ *
+ * assertNotNull(originalServiceTemplate); JpaToscaServiceTemplate createdServiceTemplate = new
+ * SimpleToscaProvider().createPolicies(pfDao, originalServiceTemplate);
+ *
+ * assertEquals(originalServiceTemplate, createdServiceTemplate); }
+ *
+ * @Test public void testPolicyUpdate() throws Exception { try { new SimpleToscaProvider().updatePolicies(null,
+ * null); fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().updatePolicies(null, new JpaToscaServiceTemplate());
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().updatePolicies(pfDao, null); fail("test should throw an exception here"); } catch
+ * (Exception exc) { assertEquals("serviceTemplate is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * ToscaServiceTemplate toscaServiceTemplate = standardCoder.decode(
+ * ResourceUtils.getResourceAsString("policies/vCPE.policy.monitoring.input.tosca.json"),
+ * ToscaServiceTemplate.class);
+ *
+ * JpaToscaServiceTemplate originalServiceTemplate = new JpaToscaServiceTemplate();
+ * originalServiceTemplate.fromAuthorative(toscaServiceTemplate);
+ *
+ * assertNotNull(originalServiceTemplate); JpaToscaServiceTemplate updatedServiceTemplate = new
+ * SimpleToscaProvider().updatePolicies(pfDao, originalServiceTemplate);
+ *
+ * assertEquals(originalServiceTemplate, updatedServiceTemplate); }
+ *
+ * @Test public void testPoliciesDelete() throws Exception { try { new SimpleToscaProvider().deletePolicy(null,
+ * null); fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().deletePolicy(null, new PfConceptKey());
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("dao is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * try { new SimpleToscaProvider().deletePolicy(pfDao, null); fail("test should throw an exception here"); } catch
+ * (Exception exc) { assertEquals("policyKey is marked @NonNull but is null", exc.getMessage()); }
+ *
+ * ToscaServiceTemplate toscaServiceTemplate = standardCoder.decode(
+ * ResourceUtils.getResourceAsString("policies/vCPE.policy.monitoring.input.tosca.json"),
+ * ToscaServiceTemplate.class);
+ *
+ * JpaToscaServiceTemplate originalServiceTemplate = new JpaToscaServiceTemplate();
+ * originalServiceTemplate.fromAuthorative(toscaServiceTemplate);
+ *
+ * assertNotNull(originalServiceTemplate); JpaToscaServiceTemplate createdServiceTemplate = new
+ * SimpleToscaProvider().createPolicies(pfDao, originalServiceTemplate);
+ *
+ * assertEquals(originalServiceTemplate, createdServiceTemplate);
+ *
+ * PfConceptKey policyKey = new PfConceptKey("onap.restart.tca:1.0.0");
+ *
+ * JpaToscaServiceTemplate deletedServiceTemplate = new SimpleToscaProvider().deletePolicy(pfDao, new
+ * PfConceptKey(policyKey));
+ *
+ * assertEquals(originalServiceTemplate.getTopologyTemplate().getPolicies().get(policyKey),
+ * deletedServiceTemplate.getTopologyTemplate().getPolicies().get(policyKey));
+ *
+ * try { new SimpleToscaProvider().getPolicies(pfDao, new PfConceptKey(policyKey));
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("policy not found: onap.restart.tca:1.0.0", exc.getMessage()); } }
+ *
+ * @Test public void testAssertPoliciesExist() throws PfModelException { JpaToscaServiceTemplate testServiceTemplate
+ * = new JpaToscaServiceTemplate();
+ *
+ * try { new SimpleToscaProvider().createPolicies(pfDao, testServiceTemplate);
+ * fail("test should throw an exception here"); } catch (Exception exc) {
+ * assertEquals("topology template not specified on service template", exc.getMessage()); }
+ *
+ * testServiceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate()); try { new
+ * SimpleToscaProvider().createPolicies(pfDao, testServiceTemplate); fail("test should throw an exception here"); }
+ * catch (Exception exc) { assertEquals("no policies specified on topology template of service template",
+ * exc.getMessage()); }
+ *
+ * testServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies()); try { new
+ * SimpleToscaProvider().createPolicies(pfDao, testServiceTemplate); fail("test should throw an exception here"); }
+ * catch (Exception exc) {
+ * assertEquals("list of policies specified on topology template of service template is empty", exc.getMessage()); }
+ *
+ * }
+ */
+}
diff --git a/models-pdp/src/test/resources/META-INF/persistence.xml b/models-pdp/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 000000000..079ba4993
--- /dev/null
+++ b/models-pdp/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ 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=========================================================
+-->
+
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
+ <persistence-unit name="ToscaConceptTest" transaction-type="RESOURCE_LOCAL">
+ <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+ <class>org.onap.policy.models.dao.converters.CDataConditioner</class>
+ <class>org.onap.policy.models.dao.converters.Uuid2String</class>
+ <class>org.onap.policy.models.base.PfConceptKey</class>
+ <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType</class>
+ <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdp</class>
+
+ <properties>
+ <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
+ <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:testdb" />
+ <property name="javax.persistence.jdbc.user" value="policy" />
+ <property name="javax.persistence.jdbc.password" value="P01icY" />
+ <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
+ <property name="eclipselink.ddl-generation.output-mode" value="database" />
+ <property name="eclipselink.logging.level" value="INFO" />
+ </properties>
+ </persistence-unit>
+
+ <persistence-unit name="ToscaConceptMariaDBTest" transaction-type="RESOURCE_LOCAL">
+ <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+ <class>org.onap.policy.models.dao.converters.CDataConditioner</class>
+ <class>org.onap.policy.models.dao.converters.Uuid2String</class>
+ <class>org.onap.policy.models.base.PfConceptKey</class>
+ <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType</class>
+ <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup</class>
+ <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdp</class>
+
+ <properties>
+ <property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver" />
+ <property name="javax.persistence.jdbc.url" value="jdbc:mariadb://localhost:3306/policy" />
+ <property name="javax.persistence.jdbc.user" value="policy" />
+ <property name="javax.persistence.jdbc.password" value="P01icY" />
+ <property name="javax.persistence.schema-generation.database.action" value="create" />
+
+ <property name="eclipselink.logging.level" value="ALL" />
+ <property name="eclipselink.logging.level.jpa" value="ALL" />
+ <property name="eclipselink.logging.level.ddl" value="ALL" />
+ <property name="eclipselink.logging.level.connection" value="ALL" />
+ <property name="eclipselink.logging.level.sql" value="ALL" />
+ <property name="eclipselink.logging.level.transaction" value="ALL" />
+ <property name="eclipselink.logging.level.sequencing" value="ALL" />
+ <property name="eclipselink.logging.level.server" value="ALL" />
+ <property name="eclipselink.logging.level.query" value="ALL" />
+ <property name="eclipselink.logging.level.properties" value="ALL" />
+
+ <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
+ <property name="eclipselink.ddl-generation.output-mode" value="database" />
+ <property name="eclipselink.logging.level" value="INFO" />
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/models-pdp/src/test/resources/testdata/PdpGroups0.json b/models-pdp/src/test/resources/testdata/PdpGroups0.json
new file mode 100644
index 000000000..6ebdd6c7a
--- /dev/null
+++ b/models-pdp/src/test/resources/testdata/PdpGroups0.json
@@ -0,0 +1,43 @@
+{
+ "groups": [
+ {
+ "name": "PdpGroup0",
+ "version": "1.2.3",
+ "description": "group description",
+ "pdpGroupState": "PASSIVE",
+ "properties": {
+ "groupProperty0": "Value of Group Property 0"
+ },
+ "pdpSubgroups": [
+ {
+ "pdpType": "APEX",
+ "supportedPolicyTypes": [
+ {
+ "name": "policy.type.0",
+ "version": "1.2.3"
+ }
+ ],
+ "policies": [
+ {
+ "name": "Policy0",
+ "version": "4.5.6"
+ }
+ ],
+ "currentInstanceCount": 123,
+ "desiredInstanceCount": 456,
+ "properties": {
+ "subgroupProperty0": "Value of sub Group Property 0"
+ },
+ "pdpInstances": [
+ {
+ "instanceId": "apex-0",
+ "pdpState": "ACTIVE",
+ "healthy": "NOT_HEALTHY",
+ "message": "message from PDP"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+} \ No newline at end of file