From 09e2bc57b947fb71c4dde9a8c0ded52f695abda1 Mon Sep 17 00:00:00 2001 From: "adheli.tavares" Date: Tue, 11 May 2021 14:35:20 +0100 Subject: Handling Policy deploy/undeploy audit models Added a new Entity to store information when a Pdp Policy is deployed or undeployed and its create/retrieve methods. Change-Id: I35b3608c878bbfbbee0a99a124d100a48fe08131 Issue-ID: POLICY-2899 Signed-off-by: adheli.tavares --- .../policy/models/pap/concepts/PolicyAudit.java | 50 +++++ .../pap/persistence/concepts/JpaPolicyAudit.java | 191 ++++++++++++++++ .../persistence/provider/PolicyAuditProvider.java | 137 ++++++++++++ .../persistence/concepts/JpaPolicyAuditTest.java | 126 +++++++++++ .../provider/PolicyAuditProviderTest.java | 241 +++++++++++++++++++++ .../src/test/resources/META-INF/persistence.xml | 46 ++++ 6 files changed, 791 insertions(+) create mode 100644 models-pap/src/main/java/org/onap/policy/models/pap/concepts/PolicyAudit.java create mode 100644 models-pap/src/main/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAudit.java create mode 100644 models-pap/src/main/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProvider.java create mode 100644 models-pap/src/test/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAuditTest.java create mode 100644 models-pap/src/test/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProviderTest.java create mode 100644 models-pap/src/test/resources/META-INF/persistence.xml (limited to 'models-pap/src') diff --git a/models-pap/src/main/java/org/onap/policy/models/pap/concepts/PolicyAudit.java b/models-pap/src/main/java/org/onap/policy/models/pap/concepts/PolicyAudit.java new file mode 100644 index 000000000..765d246a6 --- /dev/null +++ b/models-pap/src/main/java/org/onap/policy/models/pap/concepts/PolicyAudit.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.pap.concepts; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Audit info on policy actions. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PolicyAudit { + + public enum AuditAction { + DEPLOYMENT, UNDEPLOYMENT + } + + private Long auditId; + private String pdpGroup; + private String pdpType; + private ToscaConceptIdentifier policy; + private AuditAction action; + private Instant timestamp; + private String user; +} diff --git a/models-pap/src/main/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAudit.java b/models-pap/src/main/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAudit.java new file mode 100644 index 000000000..b31af8ea0 --- /dev/null +++ b/models-pap/src/main/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAudit.java @@ -0,0 +1,191 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.pap.persistence.concepts; + +import java.time.Instant; +import java.util.Date; +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 javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.builder.CompareToBuilder; +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.PfGeneratedIdKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.validation.annotations.VerifyKey; +import org.onap.policy.models.pap.concepts.PolicyAudit; +import org.onap.policy.models.pap.concepts.PolicyAudit.AuditAction; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Entity to keep the records on policy actions for audit. + * + * @author Adheli Tavares (adheli.tavares@est.tech) + * + */ +@Entity +@Table(name = "JpaPolicyAudit", indexes = {@Index(name = "JpaPolicyAuditIndex_timestamp", columnList = "timeStamp")}) +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class JpaPolicyAudit extends PfConcept implements PfAuthorative { + private static final long serialVersionUID = -2935734300607322191L; + + @EmbeddedId + @Column + @NotNull + @VerifyKey(versionNotNull = true) + private PfGeneratedIdKey key; + + @Column + private String pdpGroup; + + @Column + private String pdpType; + + @Column + @NotNull + private AuditAction action; + + @Column + @Temporal(TemporalType.TIMESTAMP) + @NotNull + private Date timeStamp; + + @Column + private String user; + + /** + * Default constructor. + */ + public JpaPolicyAudit() { + key = new PfGeneratedIdKey(); + } + + /** + * Constructor from an authorative. + * + * @param audit authorative model + */ + public JpaPolicyAudit(PolicyAudit audit) { + fromAuthorative(audit); + } + + /** + * Constructor as a copy. + * + * @param copyConcept original entity to be copied + */ + public JpaPolicyAudit(JpaPolicyAudit copyConcept) { + this.key = new PfGeneratedIdKey(copyConcept.getKey()); + this.pdpGroup = copyConcept.getPdpGroup(); + this.pdpType = copyConcept.getPdpType(); + this.action = copyConcept.getAction(); + this.timeStamp = copyConcept.getTimeStamp(); + this.user = copyConcept.getUser(); + } + + @Override + public int compareTo(PfConcept o) { + if (o == null) { + return -1; + } + if (this == o) { + return 0; + } + if (getClass() != o.getClass()) { + return getClass().getName().compareTo(o.getClass().getName()); + } + + final JpaPolicyAudit other = (JpaPolicyAudit) o; + + // @formatter:off + return new CompareToBuilder() + .append(key, other.key) + .append(pdpGroup, other.pdpGroup) + .append(pdpType, other.pdpType) + .append(action, other.action) + .append(timeStamp, other.timeStamp) + .append(user, other.user) + .toComparison(); + // @formatter:on + } + + @Override + public PolicyAudit toAuthorative() { + ToscaConceptIdentifier policyIdent = new ToscaConceptIdentifier(key.getName(), key.getVersion()); + + // @formatter:off + return PolicyAudit.builder() + .auditId(key.getGeneratedId()) + .pdpGroup(pdpGroup) + .pdpType(pdpType) + .policy(policyIdent) + .action(action) + .timestamp(timeStamp == null ? null : timeStamp.toInstant()) + .user(user) + .build(); + // @formatter:on + } + + @Override + public void fromAuthorative(PolicyAudit authorativeConcept) { + if (authorativeConcept.getPolicy() != null) { + final ToscaConceptIdentifier policy = authorativeConcept.getPolicy(); + key = new PfGeneratedIdKey(policy.getName(), policy.getVersion(), authorativeConcept.getAuditId()); + } else { + key = new PfGeneratedIdKey(); + } + + pdpGroup = authorativeConcept.getPdpGroup(); + pdpType = authorativeConcept.getPdpType(); + action = authorativeConcept.getAction(); + timeStamp = authorativeConcept.getTimestamp() == null ? Date.from(Instant.now()) + : Date.from(authorativeConcept.getTimestamp()); + user = authorativeConcept.getUser(); + } + + @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); + user = Assertions.validateStringParameter("user", user, PfReferenceKey.LOCAL_NAME_REGEXP); + } +} diff --git a/models-pap/src/main/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProvider.java b/models-pap/src/main/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProvider.java new file mode 100644 index 000000000..c117beefa --- /dev/null +++ b/models-pap/src/main/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProvider.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.pap.persistence.provider; + +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.ws.rs.core.Response; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.dao.PfDao; +import org.onap.policy.models.pap.concepts.PolicyAudit; +import org.onap.policy.models.pap.concepts.PolicyAudit.AuditAction; +import org.onap.policy.models.pap.persistence.concepts.JpaPolicyAudit; + +/** + * Provider for Policy Audit. + * + * @author Adheli Tavares (adheli.tavares@est.tech) + * + */ +public class PolicyAuditProvider { + + private static final Integer DEFAULT_MAX_RECORDS = 100; + private static final String DESCENDING_ORDER = "DESC"; + + /** + * Create audit records. + * + * @param audits list of policy audit + */ + public void createAuditRecords(@NonNull PfDao dao, @NonNull final List audits) { + List jpaAudits = audits.stream().map(JpaPolicyAudit::new).collect(Collectors.toList()); + + BeanValidationResult result = new BeanValidationResult("createAuditRecords", jpaAudits); + + int count = 0; + for (JpaPolicyAudit jpaAudit: jpaAudits) { + result.addResult(jpaAudit.validate(String.valueOf(count++))); + } + + if (!result.isValid()) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, result.getResult()); + } + + dao.createCollection(jpaAudits); + } + + /** + * Collect all audit records. + * + * @param numRecords number of records to be collected + * @return list of {@link PolicyAudit} records + */ + public List getAuditRecords(@NonNull PfDao dao, @NonNull Integer numRecords) { + numRecords = numRecords > DEFAULT_MAX_RECORDS ? DEFAULT_MAX_RECORDS : numRecords; + + // @formatter:off + return dao.getAll(JpaPolicyAudit.class, "timeStamp DESC", numRecords) + .stream() + .map(JpaPolicyAudit::toAuthorative) + .collect(Collectors.toList()); + // @formatter:on + } + + /** + * Collect audit records based on filters at {@link AuditFilter}. + * + * @param auditFilter {@link AuditFilter} object with filters for search + * @param numRecords number of records to be collected + * @return list of {@link PolicyAudit} records + */ + public List getAuditRecords(@NonNull PfDao dao, @NonNull AuditFilter auditFilter, + @NonNull Integer numRecords) { + numRecords = numRecords > DEFAULT_MAX_RECORDS ? DEFAULT_MAX_RECORDS : numRecords; + + Map filter = new HashMap<>(); + if (StringUtils.isNotBlank(auditFilter.getPdpGroup())) { + filter.put("pdpGroup", auditFilter.getPdpGroup()); + } + + if (auditFilter.getAction() != null) { + filter.put("action", auditFilter.getAction()); + } + + // @formatter:off + return dao.getFiltered(JpaPolicyAudit.class, + auditFilter.getName(), auditFilter.getVersion(), + auditFilter.getFromDate(), auditFilter.getToDate(), + filter, DESCENDING_ORDER, numRecords) + .stream().map(JpaPolicyAudit::toAuthorative).collect(Collectors.toList()); + // @formatter:on + } + + /** + * Create a filter for looking for audit records. + * name - policy name + * version - policy version + * pdpGroup - PDP group that policy might be related + * action - type of action/operation realized on policy + * fromDate - start of period in case of time interval search + */ + @Data + @Builder + protected static class AuditFilter { + private String name; + private String version; + private AuditAction action; + private String pdpGroup; + private Instant fromDate; + private Instant toDate; + } +} diff --git a/models-pap/src/test/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAuditTest.java b/models-pap/src/test/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAuditTest.java new file mode 100644 index 000000000..4f8693304 --- /dev/null +++ b/models-pap/src/test/java/org/onap/policy/models/pap/persistence/concepts/JpaPolicyAuditTest.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.pap.persistence.concepts; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.models.pap.concepts.PolicyAudit; +import org.onap.policy.models.pap.concepts.PolicyAudit.AuditAction; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus; +import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State; +import org.onap.policy.models.pdp.persistence.concepts.JpaPdpPolicyStatus; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class JpaPolicyAuditTest { + + private static final ToscaConceptIdentifier MY_POLICY = new ToscaConceptIdentifier("MyPolicy", "1.2.3"); + private static final String PDP_GROUP = "pdpGroupxyz"; + private static final String USER = "user"; + + PolicyAudit audit; + + /** + * Setup an audit for usage on unit tests. + */ + @Before + public void setup() { + audit = PolicyAudit.builder().auditId(1L).pdpGroup(PDP_GROUP).pdpType("pdpType").policy(MY_POLICY) + .action(AuditAction.DEPLOYMENT).timestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS)).build(); + } + + @Test + public void testCompareTo() { + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(audit); + assertEquals(-1, jpaAudit.compareTo(null)); + assertEquals(0, jpaAudit.compareTo(jpaAudit)); + assertEquals(0, jpaAudit.compareTo(new JpaPolicyAudit(jpaAudit))); + + PdpPolicyStatus idw = PdpPolicyStatus.builder().deploy(true).state(State.SUCCESS).pdpGroup(PDP_GROUP) + .pdpId("wId").policy(MY_POLICY).policyType(MY_POLICY).build(); + JpaPdpPolicyStatus jpaStatus = new JpaPdpPolicyStatus(idw); + assertNotEquals(0, jpaAudit.compareTo(jpaStatus)); + } + + @Test + public void testKeys() { + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(); + assertThat(jpaAudit.getKeys()).isNotNull(); + assertTrue(jpaAudit.getKey().isNullKey()); + + jpaAudit = new JpaPolicyAudit(audit); + assertFalse(jpaAudit.getKey().isNullKey()); + } + + @Test + public void testClean() { + audit.setUser(" user"); + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(audit); + assertThatNoException().isThrownBy(() -> jpaAudit.clean()); + assertEquals(USER, jpaAudit.getUser()); + } + + @Test + public void testToAuthorative() { + audit.setUser(USER); + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(audit); + PolicyAudit convertedAudit = jpaAudit.toAuthorative(); + + assertEquals(audit, convertedAudit); + assertEquals(USER, convertedAudit.getUser()); + + JpaPolicyAudit jpaAuditWithNullKey = new JpaPolicyAudit(); + PolicyAudit convertedAudit2 = jpaAuditWithNullKey.toAuthorative(); + assertTrue(convertedAudit2.getPolicy().asConceptKey().isNullKey()); + + } + + @Test + public void testConversionsWithRequiredOnly() { + audit = PolicyAudit.builder().policy(MY_POLICY).action(AuditAction.DEPLOYMENT) + .timestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS)).build(); + + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(audit); + PolicyAudit convertedAudit = jpaAudit.toAuthorative(); + + assertEquals(audit, convertedAudit); + assertTrue(jpaAudit.validate("jpaAudit").isValid()); + } + + @Test + public void testValidation() { + PolicyAudit invalidAudit = PolicyAudit.builder().pdpGroup(PDP_GROUP).user(USER).build(); + + JpaPolicyAudit jpaAudit = new JpaPolicyAudit(invalidAudit); + + BeanValidationResult result = jpaAudit.validate("jpaAudit"); + assertFalse(result.isValid()); + } +} diff --git a/models-pap/src/test/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProviderTest.java b/models-pap/src/test/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProviderTest.java new file mode 100644 index 000000000..da231dc7b --- /dev/null +++ b/models-pap/src/test/java/org/onap/policy/models/pap/persistence/provider/PolicyAuditProviderTest.java @@ -0,0 +1,241 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.pap.persistence.provider; + +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.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.awaitility.Awaitility; +import org.eclipse.persistence.config.PersistenceUnitProperties; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.base.PfModelRuntimeException; +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.pap.concepts.PolicyAudit; +import org.onap.policy.models.pap.concepts.PolicyAudit.AuditAction; +import org.onap.policy.models.pap.persistence.provider.PolicyAuditProvider.AuditFilter; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class for unit testing {@link PolicyAuditProvider}. + * + * @author Adheli Tavares (adheli.tavares@est.tech) + * + */ +public class PolicyAuditProviderTest { + + private static final String FIELD_IS_NULL = "%s is marked .*ull but is null"; + private static final String GROUP_A = "groupA"; + private static final String GROUP_B = "groupB"; + private static final ToscaConceptIdentifier MY_POLICY = new ToscaConceptIdentifier("MyPolicy", "1.2.3"); + private static final ToscaConceptIdentifier MY_POLICY2 = new ToscaConceptIdentifier("MyPolicyB", "2.3.4"); + private static final Integer NUMBER_RECORDS = 10; + + private PfDao pfDao; + + /** + * Set up the DAO towards the database. + * + * @throws Exception on database errors + */ + @Before + public void setupDao() throws Exception { + final DaoParameters daoParameters = new DaoParameters(); + daoParameters.setPluginClass(DefaultPfDao.class.getName()); + + daoParameters.setPersistenceUnit("ToscaConceptTest"); + + Properties jdbcProperties = new Properties(); + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_USER, "policy"); + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_PASSWORD, "P01icY"); + + if (System.getProperty("USE-MARIADB") != null) { + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_DRIVER, "org.mariadb.jdbc.Driver"); + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_URL, "jdbc:mariadb://localhost:3306/policy"); + } else { + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_DRIVER, "org.h2.Driver"); + jdbcProperties.setProperty(PersistenceUnitProperties.JDBC_URL, "jdbc:h2:mem:PolicyAuditProviderTest"); + } + + daoParameters.setJdbcProperties(jdbcProperties); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + pfDao.init(daoParameters); + } + + @After + public void teardown() { + pfDao.close(); + } + + @Test + public void testCreatePolicyAudit() { + PolicyAuditProvider provider = new PolicyAuditProvider(); + + Instant date = Instant.now(); + provider.createAuditRecords(pfDao, generatePolicyAudits(date, GROUP_A, MY_POLICY)); + + List records = provider.getAuditRecords(pfDao, NUMBER_RECORDS); + assertThat(records).hasSize(2); + + // as the start date is 10 min ahead of first record, shouldn't return any records + List emptyList = provider.getAuditRecords(pfDao, + AuditFilter.builder().fromDate(Instant.now().plusSeconds(600)).build(), 600); + assertThat(emptyList).isEmpty(); + } + + @Test + public void testCreatePolicyAuditInvalid() { + PolicyAuditProvider provider = new PolicyAuditProvider(); + + List audits = List.of(PolicyAudit.builder().pdpType("pdpType").action(AuditAction.DEPLOYMENT) + .timestamp(Instant.now()).build()); + + assertThrows(PfModelRuntimeException.class, () -> provider.createAuditRecords(pfDao, audits)); + + List records = provider.getAuditRecords(pfDao, NUMBER_RECORDS); + assertThat(records).isEmpty(); + } + + @Test + public void testFilters() { + PolicyAuditProvider provider = new PolicyAuditProvider(); + + Instant date = Instant.now().truncatedTo(ChronoUnit.SECONDS); + System.out.println(date); + provider.createAuditRecords(pfDao, generatePolicyAudits(date, GROUP_A, MY_POLICY)); + provider.createAuditRecords(pfDao, generatePolicyAudits(date, GROUP_B, MY_POLICY)); + provider.createAuditRecords(pfDao, generatePolicyAudits(date, GROUP_B, MY_POLICY2)); + Awaitility.await().pollDelay(3, TimeUnit.SECONDS).until(() -> { + return true; + }); + + List records = provider.getAuditRecords(pfDao, + AuditFilter.builder().fromDate(date).toDate(Instant.now()).build(), NUMBER_RECORDS); + assertThat(records).hasSize(6); + + List recordsWithGroupB = + provider.getAuditRecords(pfDao, AuditFilter.builder().pdpGroup(GROUP_B).build(), NUMBER_RECORDS); + assertThat(recordsWithGroupB).hasSize(4); + + List recordsWithActionDeploy = provider.getAuditRecords(pfDao, + AuditFilter.builder().action(AuditAction.DEPLOYMENT).build(), NUMBER_RECORDS); + assertThat(recordsWithActionDeploy).hasSize(3); + + List recordsWithMyPolicy = provider.getAuditRecords(pfDao, + AuditFilter.builder().name(MY_POLICY.getName()).version(MY_POLICY.getVersion()).build(), + NUMBER_RECORDS); + assertThat(recordsWithMyPolicy).hasSize(4); + } + + @Test + public void testLoadRecordsForLimit() { + PolicyAuditProvider provider = new PolicyAuditProvider(); + + List loadAudits = new ArrayList<>(); + + // going to create 102 records. + for (int i = 0; i <= 50; i++) { + loadAudits.addAll(generatePolicyAudits(Instant.now().plusSeconds(i), GROUP_A, MY_POLICY)); + } + + provider.createAuditRecords(pfDao, loadAudits); + + List records = provider.getAuditRecords(pfDao, NUMBER_RECORDS); + assertThat(records).hasSize(10); + + // check that is being ordered + assertTrue(records.get(0).getTimestamp().isAfter(records.get(9).getTimestamp())); + assertEquals(loadAudits.get(loadAudits.size() - 1).getTimestamp(), records.get(0).getTimestamp()); + + // try to get 102 records should return 100 + records = provider.getAuditRecords(pfDao, 102); + assertThat(records).hasSize(100); + } + + @Test + public void policyProviderExceptions() { + PolicyAuditProvider provider = new PolicyAuditProvider(); + + assertThatThrownBy(() -> { + provider.createAuditRecords(null, null); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "dao")); + + assertThatThrownBy(() -> { + provider.createAuditRecords(pfDao, null); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "audits")); + + assertThatThrownBy(() -> { + provider.getAuditRecords(null, NUMBER_RECORDS); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "dao")); + + assertThatThrownBy(() -> { + provider.getAuditRecords(pfDao, null); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "numRecords")); + + assertThatThrownBy(() -> { + provider.getAuditRecords(null, AuditFilter.builder().build(), NUMBER_RECORDS); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "dao")); + + assertThatThrownBy(() -> { + provider.getAuditRecords(pfDao, AuditFilter.builder().build(), null); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "numRecords")); + + assertThatThrownBy(() -> { + provider.getAuditRecords(pfDao, null, NUMBER_RECORDS); + }).hasMessageMatching(String.format(FIELD_IS_NULL, "auditFilter")); + } + + private List generatePolicyAudits(Instant date, String group, ToscaConceptIdentifier policy) { + // @formatter:off + PolicyAudit deploy = PolicyAudit.builder() + .pdpGroup(group) + .pdpType("pdpType") + .policy(policy) + .action(AuditAction.DEPLOYMENT) + .timestamp(date.truncatedTo(ChronoUnit.SECONDS)) + .build(); + + PolicyAudit undeploy = PolicyAudit.builder() + .pdpGroup(group) + .pdpType("pdpType") + .policy(policy) + .action(AuditAction.UNDEPLOYMENT) + .timestamp(date.plusSeconds(1).truncatedTo(ChronoUnit.SECONDS)) + .build(); + // @formatter:on + + return List.of(deploy, undeploy); + } +} diff --git a/models-pap/src/test/resources/META-INF/persistence.xml b/models-pap/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..58e2deca3 --- /dev/null +++ b/models-pap/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,46 @@ + + + + + + org.eclipse.persistence.jpa.PersistenceProvider + + org.onap.policy.models.pap.persistence.concepts.JpaPolicyAudit + + + + + + + + + + + + + + + + + + + + -- cgit 1.2.3-korg