From e926efbc4d5dde8ade1a5521f5be1294079df057 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Thu, 7 Jan 2021 09:07:05 -0500 Subject: [PATCH] Add PDP-Policy deployment table to DB Added a table to record the PDP policy deployment status, which is required for making PAP stateless. Issue-ID: POLICY-2648 Change-Id: Ibe40ce00aca7a600051edcac49e55651c1c0164f Signed-off-by: Jim Hahn --- .../models/pdp/concepts/PdpPolicyStatus.java | 49 +++++ .../persistence/concepts/JpaPdpPolicyStatus.java | 225 +++++++++++++++++++++ .../pdp/persistence/provider/PdpProvider.java | 75 ++++++- .../concepts/JpaPdpPolicyStatusTest.java | 196 ++++++++++++++++++ .../pdp/persistence/provider/PdpProviderTest.java | 150 +++++++++++++- .../src/test/resources/META-INF/persistence.xml | 2 + .../models/provider/PolicyModelsProvider.java | 24 +++ .../impl/DatabasePolicyModelsProviderImpl.java | 18 +- .../impl/DummyPolicyModelsProviderImpl.java | 16 +- .../impl/DatabasePolicyModelsProviderTest.java | 7 +- .../models/provider/impl/DummyBadProviderImpl.java | 16 +- .../impl/DummyPolicyModelsProviderTest.java | 7 +- .../src/test/resources/META-INF/persistence.xml | 2 + 13 files changed, 780 insertions(+), 7 deletions(-) create mode 100644 models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpPolicyStatus.java create mode 100644 models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatus.java create mode 100644 models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatusTest.java diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpPolicyStatus.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpPolicyStatus.java new file mode 100644 index 000000000..b52173a9d --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpPolicyStatus.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.concepts; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Policy deployment status for a PDP. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PdpPolicyStatus { + + public enum State { + WAITING, SUCCESS, FAILURE + } + + private String pdpGroup; + private String pdpType; + private String pdpId; + private ToscaConceptIdentifier policy; + private ToscaConceptIdentifier policyType; + private boolean deploy; + private State state; +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatus.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatus.java new file mode 100644 index 000000000..2da787b60 --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatus.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.persistence.concepts; + +import java.util.List; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Index; +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.builder.CompareToBuilder; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Pattern; +import org.onap.policy.common.parameters.annotations.Valid; +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.PfConceptKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.VerifyKey; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to represent PDP-Policy deployment status in the database. + */ +@Entity +@Table(name = "JpaPdpPolicyStatus", indexes = {@Index(name = "JpaPdpPolicyStatus_PdpGroup", columnList = "pdpGroup")}) +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class JpaPdpPolicyStatus extends PfConcept implements PfAuthorative { + private static final long serialVersionUID = -357224425637789775L; + + /** + * Parent key & version identifies the policy, while localName identifies the pdpId. + */ + @EmbeddedId + @NotNull + @Valid + private PfReferenceKey key; + + @Column + @NotNull + @Pattern(regexp = PfReferenceKey.LOCAL_NAME_REGEXP) + private String pdpGroup; + + @Column + @NotNull + @Pattern(regexp = PfReferenceKey.LOCAL_NAME_REGEXP) + private String pdpType; + + @Column + @NotNull + @VerifyKey(versionNotNull = true) + private PfConceptKey policyType; + + @Column + private boolean deploy; + + @Column + @NotNull + private State state; + + + /** + * Constructs an empty object. + */ + public JpaPdpPolicyStatus() { + key = new PfReferenceKey(); + pdpGroup = PfKey.NULL_KEY_NAME; + pdpType = PfKey.NULL_KEY_NAME; + policyType = new PfConceptKey(); + deploy = false; + state = State.WAITING; + } + + /** + * Copy constructor. + * + * @param source object from which to copy + */ + public JpaPdpPolicyStatus(JpaPdpPolicyStatus source) { + key = new PfReferenceKey(source.getKey()); + pdpGroup = source.getPdpGroup(); + pdpType = source.getPdpType(); + policyType = new PfConceptKey(source.getPolicyType()); + deploy = source.isDeploy(); + state = source.getState(); + } + + /** + * Authorative constructor. + * + * @param source authorative object from which to copy + */ + public JpaPdpPolicyStatus(PdpPolicyStatus source) { + fromAuthorative(source); + } + + @Override + public int compareTo(PfConcept otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return getClass().getName().compareTo(otherConcept.getClass().getName()); + } + + final JpaPdpPolicyStatus other = (JpaPdpPolicyStatus) otherConcept; + + // @formatter:off + return new CompareToBuilder() + .append(key, other.key) + .append(pdpGroup, other.pdpGroup) + .append(pdpType, other.pdpType) + .append(policyType, other.policyType) + .append(deploy, other.deploy) + .append(state, other.state) + .toComparison(); + // @formatter:on + } + + @Override + public PdpPolicyStatus toAuthorative() { + PfConceptKey policyKey = key.getParentConceptKey(); + ToscaConceptIdentifier policyIdent = new ToscaConceptIdentifier(policyKey.getName(), policyKey.getVersion()); + + ToscaConceptIdentifier policyTypeIdent = + new ToscaConceptIdentifier(policyType.getName(), policyType.getVersion()); + + // @formatter:off + return PdpPolicyStatus.builder() + .pdpGroup(pdpGroup) + .pdpId(key.getLocalName()) + .pdpType(pdpType) + .policyType(policyTypeIdent) + .policy(policyIdent) + .deploy(deploy) + .state(state) + .build(); + // @formatter:on + } + + @Override + public void fromAuthorative(PdpPolicyStatus source) { + final ToscaConceptIdentifier policyIdent = source.getPolicy(); + final ToscaConceptIdentifier policyTypeIdent = source.getPolicyType(); + + key = new PfReferenceKey(policyIdent.getName(), policyIdent.getVersion(), source.getPdpId()); + pdpGroup = source.getPdpGroup(); + pdpType = source.getPdpType(); + policyType = new PfConceptKey(policyTypeIdent.getName(), policyTypeIdent.getVersion()); + deploy = source.isDeploy(); + state = source.getState(); + } + + @Override + public List getKeys() { + return getKey().getKeys(); + } + + @Override + public void clean() { + key.clean(); + + pdpGroup = Assertions.validateStringParameter("pdpGroup", pdpGroup, PfReferenceKey.LOCAL_NAME_REGEXP); + pdpType = Assertions.validateStringParameter("pdpType", pdpType, PfReferenceKey.LOCAL_NAME_REGEXP); + policyType.clean(); + } + + @Override + public BeanValidationResult validate(@NonNull String fieldName) { + BeanValidationResult result = super.validate(fieldName); + + if (PfKey.NULL_KEY_NAME.equals(key.getParentKeyName())) { + addResult(result, "policy name (parent key name of key)", key.getParentKeyName(), Validated.IS_NULL); + } + + if (PfKey.NULL_KEY_VERSION.equals(key.getParentKeyVersion())) { + addResult(result, "policy version (parent key version of key)", key.getParentKeyVersion(), + Validated.IS_NULL); + } + + if (!PfKey.NULL_KEY_NAME.equals(key.getParentLocalName())) { + addResult(result, "parent local name of key", key.getParentLocalName(), "must be " + PfKey.NULL_KEY_NAME); + } + + if (PfKey.NULL_KEY_NAME.equals(key.getLocalName())) { + addResult(result, "pdpId (local name of key)", key.getLocalName(), Validated.IS_NULL); + } + + return result; + } +} 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 e496521b7..ed3551a9e 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 @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. - * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,11 @@ package org.onap.policy.models.pdp.persistence.provider; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import javax.ws.rs.core.Response; import lombok.NonNull; import org.onap.policy.common.parameters.BeanValidationResult; @@ -35,10 +39,12 @@ import org.onap.policy.models.dao.PfDao; import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpGroupFilter; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; import org.onap.policy.models.pdp.persistence.concepts.JpaPdp; import org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup; +import org.onap.policy.models.pdp.persistence.concepts.JpaPdpPolicyStatus; import org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup; /** @@ -47,6 +53,7 @@ import org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup; * @author Liam Fallon (liam.fallon@est.tech) */ public class PdpProvider { + private static final Object statusLock = new Object(); /** * Get PDP groups. @@ -247,6 +254,72 @@ public class PdpProvider { // Not implemented yet } + /** + * Gets the policy deployments for a PDP group. + * + * @param dao the DAO to use to access the database + * @param groupName the name of the PDP group of interest, null to get results for all + * PDP groups + * @return the deployments found + * @throws PfModelException on errors getting PDP groups + */ + public List getGroupPolicyStatus(@NonNull final PfDao dao, @NonNull final String groupName) + throws PfModelException { + + Map filter = Map.of("pdpGroup", groupName); + + return dao.getFiltered(JpaPdpPolicyStatus.class, null, null, null, null, filter, null, 0).stream() + .map(JpaPdpPolicyStatus::toAuthorative).collect(Collectors.toList()); + } + + /** + * Creates, updates, and deletes collections of policy status. + * + * @param dao the DAO to use to access the database + * @param createObjs the objects to create + * @param updateObjs the objects to update + * @param deleteObjs the objects to delete + */ + public void cudPolicyStatus(@NonNull final PfDao dao, Collection createObjs, + Collection updateObjs, Collection deleteObjs) { + + synchronized (statusLock) { + dao.deleteCollection(fromAuthorativeStatus(deleteObjs, "deletePdpPolicyStatusList")); + dao.createCollection(fromAuthorativeStatus(createObjs, "createPdpPolicyStatusList")); + dao.createCollection(fromAuthorativeStatus(updateObjs, "updatePdpPolicyStatusList")); + } + } + + /** + * Converts a collection of authorative policy status to a collection of JPA policy + * status. Validates the resulting list. + * + * @param objs authorative policy status to convert + * @param fieldName name of the field containing the collection + * @return a collection of JPA policy status + */ + private Collection fromAuthorativeStatus(Collection objs, String fieldName) { + if (objs == null) { + return Collections.emptyList(); + } + + List jpas = objs.stream().map(JpaPdpPolicyStatus::new).collect(Collectors.toList()); + + // validate the objects + BeanValidationResult result = new BeanValidationResult(fieldName, jpas); + + int count = 0; + for (JpaPdpPolicyStatus jpa: jpas) { + result.addResult(jpa.validate(String.valueOf(count++))); + } + + if (!result.isValid()) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, result.getResult()); + } + + return jpas; + } + /** * Convert JPA PDP group list to an authorative PDP group list. * diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatusTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatusTest.java new file mode 100644 index 000000000..fdadae768 --- /dev/null +++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpPolicyStatusTest.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.persistence.concepts; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import java.util.List; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; +import org.assertj.core.api.AbstractStringAssert; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.Validated; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.PdpPolicyStatusBuilder; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class JpaPdpPolicyStatusTest { + private static final String MY_PDP = "MyPdp"; + private static final String MY_GROUP = "MyGroup"; + private static final String MY_PDP_TYPE = "MyPdpType"; + private static final ToscaConceptIdentifier POLICY = new ToscaConceptIdentifier("MyPolicy", "1.2.3"); + private static final ToscaConceptIdentifier POLICY_TYPE = new ToscaConceptIdentifier("MyPolicyType", "1.2.4"); + + private PdpPolicyStatusBuilder builder; + + + /** + * Set up Policy Status builder. + */ + @Before + public void setup() { + // @formatter:off + builder = PdpPolicyStatus.builder() + .deploy(true) + .pdpGroup(MY_GROUP) + .pdpId(MY_PDP) + .pdpType(MY_PDP_TYPE) + .policy(POLICY) + .policyType(POLICY_TYPE) + .state(State.SUCCESS); + // @formatter:on + } + + @Test + public void testJpaPdpPolicyStatus() { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(); + + assertThat(jpa.getKey()).isNotNull(); + assertThat(jpa.getKey().isNullKey()).isTrue(); + assertThat(jpa.getPdpGroup()).isEqualTo(PfKey.NULL_KEY_NAME); + assertThat(jpa.getPdpType()).isEqualTo(PfKey.NULL_KEY_NAME); + assertThat(jpa.getPolicyType()).isNotNull(); + assertThat(jpa.getPolicyType().isNullKey()).isTrue(); + assertThat(jpa.isDeploy()).isFalse(); + assertThat(jpa.getState()).isEqualTo(State.WAITING); + } + + @Test + public void testJpaPdpPolicyStatusJpaPdpPolicyStatus() { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(builder.build()); + + assertThat(new JpaPdpPolicyStatus(jpa)).isEqualTo(jpa); + } + + @Test + public void testJpaPdpPolicyStatusPdpPolicyStatus() { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(builder.build()); + + assertThat(jpa.getKey()).isNotNull(); + PfReferenceKey key = jpa.getKey(); + assertThat(key.getParentKeyName()).isEqualTo(POLICY.getName()); + assertThat(key.getParentKeyVersion()).isEqualTo(POLICY.getVersion()); + assertThat(key.getParentLocalName()).isEqualTo(PfKey.NULL_KEY_NAME); + assertThat(key.getLocalName()).isEqualTo(MY_PDP); + + assertThat(jpa.getPdpGroup()).isEqualTo(MY_GROUP); + assertThat(jpa.getPdpType()).isEqualTo(MY_PDP_TYPE); + + assertThat(jpa.getPolicyType()).isNotNull(); + assertThat(jpa.getPolicyType().getName()).isEqualTo(POLICY_TYPE.getName()); + assertThat(jpa.getPolicyType().getVersion()).isEqualTo(POLICY_TYPE.getVersion()); + + assertThat(jpa.isDeploy()).isTrue(); + assertThat(jpa.getState()).isEqualTo(State.SUCCESS); + } + + @Test + public void testGetKeys() { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(builder.build()); + + assertThat(jpa.getKeys()).isEqualTo(List.of(jpa.getKey())); + } + + @Test + public void testClean() { + JpaPdpPolicyStatus jpa = + new JpaPdpPolicyStatus(builder.pdpGroup(MY_GROUP + " ").pdpType(MY_PDP_TYPE + " ").build()); + + jpa.clean(); + + assertThat(jpa.getPdpGroup()).isEqualTo(MY_GROUP); + assertThat(jpa.getPdpType()).isEqualTo(MY_PDP_TYPE); + } + + @Test + @SuppressWarnings("serial") + public void testCompareTo() { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(builder.build()); + + assertNotEquals(0, jpa.compareTo(null)); + assertEquals(0, jpa.compareTo(jpa)); + assertNotEquals(0, jpa.compareTo(new JpaPdpPolicyStatus(builder.build()) {})); + + assertNotEquals(0, checkCompareTo(bldr -> bldr.pdpId("AnotherPdp"))); + assertNotEquals(0, checkCompareTo(bldr -> bldr.pdpGroup("AnotherGroup"))); + assertNotEquals(0, checkCompareTo(bldr -> bldr.pdpType("AnotherType"))); + assertNotEquals(0, checkCompareTo( + bldr -> bldr.policyType(new ToscaConceptIdentifier("AnotherPolicyType", "1.2.4")))); + assertNotEquals(0, checkCompareTo(bldr -> bldr.deploy(false))); + assertNotEquals(0, checkCompareTo(bldr -> bldr.state(State.FAILURE))); + } + + private int checkCompareTo(UnaryOperator fieldModifier) { + JpaPdpPolicyStatus jpa1 = new JpaPdpPolicyStatus(builder.build()); + JpaPdpPolicyStatus jpa2 = new JpaPdpPolicyStatus(fieldModifier.apply(builder).build()); + + return jpa1.compareTo(jpa2); + } + + @Test + public void testToAuthorative() { + PdpPolicyStatus data = builder.build(); + + assertThat(new JpaPdpPolicyStatus(data).toAuthorative()).isEqualTo(data); + } + + @Test + public void testFromAuthorative() { + PdpPolicyStatus data = builder.build(); + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(); + + jpa.fromAuthorative(data); + + assertThat(jpa).isEqualTo(new JpaPdpPolicyStatus(data)); + } + + @Test + public void testValidate() { + assertThat(new JpaPdpPolicyStatus(builder.build()).validate("").getResult()).isNull(); + + assertThatThrownBy(() -> new JpaPdpPolicyStatus(builder.build()).validate(null)) + .hasMessageContaining("fieldName").hasMessageContaining("is null"); + + checkValidate(jpa -> jpa.getKey().setParentKeyName(PfKey.NULL_KEY_NAME)).contains("policy name", + Validated.IS_NULL); + + checkValidate(jpa -> jpa.getKey().setParentKeyVersion(PfKey.NULL_KEY_VERSION)).contains("policy version", + Validated.IS_NULL); + + checkValidate(jpa -> jpa.getKey().setParentLocalName("SomeName")).contains("parent local name", "must be NULL"); + + checkValidate(jpa -> jpa.getKey().setLocalName(PfKey.NULL_KEY_NAME)).contains("pdpId", Validated.IS_NULL); + } + + private AbstractStringAssert checkValidate(Consumer fieldModifier) { + JpaPdpPolicyStatus jpa = new JpaPdpPolicyStatus(builder.build()); + fieldModifier.accept(jpa); + + return assertThat(jpa.validate("").getResult()); + } +} diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/provider/PdpProviderTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/provider/PdpProviderTest.java index d57204adf..2bf942a6a 100644 --- a/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/provider/PdpProviderTest.java +++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/persistence/provider/PdpProviderTest.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2019-2021 Nordix Foundation. - * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,15 @@ package org.onap.policy.models.pdp.persistence.provider; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Properties; import org.eclipse.persistence.config.PersistenceUnitProperties; @@ -36,6 +39,7 @@ 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.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.base.Validated; import org.onap.policy.models.dao.DaoParameters; import org.onap.policy.models.dao.PfDao; @@ -45,6 +49,9 @@ import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpGroupFilter; import org.onap.policy.models.pdp.concepts.PdpGroups; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.PdpPolicyStatusBuilder; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; import org.onap.policy.models.pdp.enums.PdpHealthStatus; @@ -64,8 +71,11 @@ public class PdpProviderTest { private static final String GROUP_IS_NULL = "pdpGroupName is marked .*ull but is null"; private static final String DAO_IS_NULL = "dao is marked .*ull but is null"; private static final String PDP_GROUP0 = "PdpGroup0"; + private static final String GROUP_A = "groupA"; + private static final String GROUP_B = "groupB"; private PfDao pfDao; private StandardCoder standardCoder; + private PdpPolicyStatusBuilder statusBuilder; /** @@ -102,6 +112,18 @@ public class PdpProviderTest { standardCoder = new StandardCoder(); } + /** + * Set up Policy Status builder. + */ + @Before + public void setupBuilder() { + ToscaConceptIdentifier policy = new ToscaConceptIdentifier("MyPolicy", "1.2.3"); + ToscaConceptIdentifier policyType = new ToscaConceptIdentifier("MyPolicyType", "1.2.4"); + + statusBuilder = PdpPolicyStatus.builder().deploy(true).pdpType("MyPdpType").policy(policy) + .policyType(policyType).state(State.SUCCESS); + } + @After public void teardown() { pfDao.close(); @@ -621,4 +643,130 @@ public class PdpProviderTest { new PdpProvider().updatePdpStatistics(pfDao, "name", "TYPE", "inst", new PdpStatistics()); } + + @Test + public void testGetGroupPolicyStatus() throws PfModelException { + assertThatThrownBy(() -> { + new PdpProvider().getGroupPolicyStatus(null, "someGroup"); + }).hasMessageMatching(DAO_IS_NULL); + + assertThatThrownBy(() -> { + new PdpProvider().getGroupPolicyStatus(pfDao, null); + }).hasMessageContaining("group").hasMessageContaining("null"); + + assertThat(new PdpProvider().getGroupPolicyStatus(pfDao, PDP_GROUP0)).isEmpty(); + } + + @Test + public void cudPolicyStatus() throws PfModelException { + PdpProvider prov = new PdpProvider(); + + assertThatThrownBy(() -> prov.cudPolicyStatus(null, List.of(), List.of(), List.of())) + .hasMessageMatching(DAO_IS_NULL); + + // null collections should be OK + assertThatCode(() -> prov.cudPolicyStatus(pfDao, null, null, null)).doesNotThrowAnyException(); + } + + @Test + public void cudPolicyStatus_Create() throws PfModelException { + PdpProvider prov = new PdpProvider(); + + PdpPolicyStatus idx = statusBuilder.pdpGroup(GROUP_A).pdpId("idX").build(); + PdpPolicyStatus idy = statusBuilder.pdpGroup(GROUP_A).pdpId("idY").build(); + PdpPolicyStatus idz = statusBuilder.pdpGroup(GROUP_B).pdpId("idZ").build(); + prov.cudPolicyStatus(pfDao, List.of(idx, idy), null, null); + prov.cudPolicyStatus(pfDao, List.of(idz), null, null); + + List records = prov.getGroupPolicyStatus(pfDao, GROUP_A); + assertThat(records).hasSize(2); + + Collections.sort(records, (rec1, rec2) -> rec1.getPdpId().compareTo(rec2.getPdpId())); + assertThat(records.get(0)).isEqualTo(idx); + assertThat(records.get(1)).isEqualTo(idy); + + records = prov.getGroupPolicyStatus(pfDao, GROUP_B); + assertThat(records).hasSize(1); + assertThat(records.get(0)).isEqualTo(idz); + } + + @Test + public void cudPolicyStatus_Update() throws PfModelException { + PdpProvider prov = new PdpProvider(); + + PdpPolicyStatus idw = statusBuilder.pdpGroup(GROUP_A).pdpId("wId").build(); + PdpPolicyStatus idx = statusBuilder.pdpGroup(GROUP_A).pdpId("xId").build(); + PdpPolicyStatus idy = statusBuilder.pdpGroup(GROUP_A).pdpId("yId").build(); + PdpPolicyStatus idz = statusBuilder.pdpGroup(GROUP_A).pdpId("zId").build(); + prov.cudPolicyStatus(pfDao, List.of(idw, idx, idy, idz), null, null); + + assertThat(prov.getGroupPolicyStatus(pfDao, GROUP_A)).hasSize(4); + + /* + * Now update some records. + */ + idx.setState(State.FAILURE); + idz.setState(State.WAITING); + prov.cudPolicyStatus(pfDao, null, List.of(idx, idz), null); + List records = prov.getGroupPolicyStatus(pfDao, GROUP_A); + assertThat(records).hasSize(4); + + Collections.sort(records, (rec1, rec2) -> rec1.getPdpId().compareTo(rec2.getPdpId())); + assertThat(records.get(0)).isEqualTo(idw); + assertThat(records.get(1)).isEqualTo(idx); + assertThat(records.get(2)).isEqualTo(idy); + assertThat(records.get(3)).isEqualTo(idz); + } + + @Test + public void cudPolicyStatus_Delete() throws PfModelException { + PdpProvider prov = new PdpProvider(); + + PdpPolicyStatus idw = statusBuilder.pdpGroup(GROUP_A).pdpId("idW").build(); + PdpPolicyStatus idx = statusBuilder.pdpGroup(GROUP_A).pdpId("idX").build(); + PdpPolicyStatus idy = statusBuilder.pdpGroup(GROUP_A).pdpId("idY").build(); + PdpPolicyStatus idz = statusBuilder.pdpGroup(GROUP_A).pdpId("idZ").build(); + prov.cudPolicyStatus(pfDao, List.of(idw, idx, idy, idz), null, null); + + assertThat(prov.getGroupPolicyStatus(pfDao, GROUP_A)).hasSize(4); + + /* + * Delete some records and then check again. + */ + prov.cudPolicyStatus(pfDao, null, null, List.of(idw, idy)); + + List records = prov.getGroupPolicyStatus(pfDao, GROUP_A); + assertThat(records).hasSize(2); + + Collections.sort(records, (rec1, rec2) -> rec1.getPdpId().compareTo(rec2.getPdpId())); + assertThat(records.get(0)).isEqualTo(idx); + assertThat(records.get(1)).isEqualTo(idz); + } + + @Test + public void testFromAuthorativeStatus() throws PfModelException { + PdpProvider prov = new PdpProvider(); + + assertThatCode(() -> prov.cudPolicyStatus(pfDao, null, null, null)).doesNotThrowAnyException(); + + PdpPolicyStatus ida = statusBuilder.pdpGroup(GROUP_A).pdpId("idA").build(); + PdpPolicyStatus idb = statusBuilder.pdpGroup(GROUP_A).pdpId("idB").build(); + PdpPolicyStatus idc = statusBuilder.pdpGroup(GROUP_A).pdpId("idC").build(); + PdpPolicyStatus idd = statusBuilder.pdpGroup(GROUP_A).pdpId("idD").build(); + + // make a couple invalid records + idb.setState(null); + idd.setState(null); + + List list = List.of(ida, idb, idc, idd); + + // @formatter:off + assertThatCode(() -> prov.cudPolicyStatus(pfDao, list, null, null)) + .isInstanceOf(PfModelRuntimeException.class) + .hasMessageContaining("1").hasMessageContaining("3") + .hasMessageNotContaining("0").hasMessageNotContaining("2"); + // @formatter:on + + assertThat(prov.getGroupPolicyStatus(pfDao, GROUP_A)).isEmpty(); + } } diff --git a/models-pdp/src/test/resources/META-INF/persistence.xml b/models-pdp/src/test/resources/META-INF/persistence.xml index 5c7caae2c..878998422 100644 --- a/models-pdp/src/test/resources/META-INF/persistence.xml +++ b/models-pdp/src/test/resources/META-INF/persistence.xml @@ -2,6 +2,7 @@