From d641bd5f3c4f6333e56ea85d95abb3dc124d4f4b Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 12 Apr 2019 10:00:05 -0400 Subject: Support group-oriented REST API Added code to support PDP group create/update & delete REST API calls. The create/update request can also be used to deploy/undeploy policies. It is assumed that the create/update request specifies a valid list of supported policy types for each subgroup (i.e., PDP type). Updated due to elimination of "version" from group in policy/models. Added/updated junits. Change-Id: I1916d9b17dfd5f12129c6f6a2fcf54e706662c10 Issue-ID: POLICY-1542 Signed-off-by: Jim Hahn --- .../pap/main/rest/depundep/ProviderSuper.java | 50 ++- .../pap/main/rest/depundep/TestGroupData.java | 25 +- .../depundep/TestPdpGroupDeleteControllerV1.java | 26 +- .../rest/depundep/TestPdpGroupDeleteProvider.java | 65 +++- .../rest/depundep/TestPdpGroupDeployProvider.java | 412 ++++++++++++++++++++- .../pap/main/rest/depundep/TestSessionData.java | 235 ++++++++++-- 6 files changed, 751 insertions(+), 62 deletions(-) (limited to 'main/src/test/java') diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java index 65b1234f..256d3af0 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java @@ -1,4 +1,4 @@ -/* +/*- * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ @@ -31,6 +31,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import org.junit.Before; import org.mockito.ArgumentCaptor; import org.mockito.Captor; @@ -43,6 +44,7 @@ import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.common.utils.services.Registry; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpGroups; +import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; @@ -61,7 +63,7 @@ public class ProviderSuper { /** - * Used to capture input to dao.updatePdpGroups(). + * Used to capture input to dao.updatePdpGroups() and dao.createPdpGroups(). */ @Captor private ArgumentCaptor> updateCaptor; @@ -118,7 +120,19 @@ public class ProviderSuper { } /** - * Gets the input to the method. + * Gets the input to the create() method. + * + * @return the input that was passed to the dao.updatePdpGroups() method + * @throws Exception if an error occurred + */ + protected List getGroupCreates() throws Exception { + verify(dao).createPdpGroups(updateCaptor.capture()); + + return copyList(updateCaptor.getValue()); + } + + /** + * Gets the input to the update() method. * * @return the input that was passed to the dao.updatePdpGroups() method * @throws Exception if an error occurred @@ -129,6 +143,20 @@ public class ProviderSuper { return copyList(updateCaptor.getValue()); } + /** + * Gets the state-changes that were added to the request map. + * + * @param count the number of times the method is expected to have been called + * @return the state-changes that were added to the request map + */ + protected List getStateChangeRequests(int count) { + ArgumentCaptor captor = ArgumentCaptor.forClass(PdpStateChange.class); + + verify(reqmap, times(count)).addRequest(any(), captor.capture()); + + return captor.getAllValues().stream().filter(req -> req != null).collect(Collectors.toList()); + } + /** * Gets the updates that were added to the request map. * @@ -138,9 +166,9 @@ public class ProviderSuper { protected List getUpdateRequests(int count) { ArgumentCaptor captor = ArgumentCaptor.forClass(PdpUpdate.class); - verify(reqmap, times(count)).addRequest(captor.capture()); + verify(reqmap, times(count)).addRequest(captor.capture(), any()); - return new ArrayList<>(captor.getAllValues()); + return captor.getAllValues().stream().filter(req -> req != null).collect(Collectors.toList()); } /** @@ -162,7 +190,17 @@ public class ProviderSuper { * @return a list of groups */ protected List loadGroups(String fileName) { - return loadFile(fileName, PdpGroups.class).getGroups(); + return loadPdpGroups(fileName).getGroups(); + } + + /** + * Loads a PdpGroups. + * + * @param fileName name of the file from which to load + * @return a PdpGroups + */ + protected PdpGroups loadPdpGroups(String fileName) { + return loadFile(fileName, PdpGroups.class); } /** diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestGroupData.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestGroupData.java index 8313d193..0c14aa2f 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestGroupData.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestGroupData.java @@ -50,19 +50,42 @@ public class TestGroupData { } @Test - public void test() { + public void testNew() { + data = new GroupData(oldGroup, true); + assertSame(oldGroup, data.getGroup()); + + assertTrue(data.isNew()); + assertFalse(data.isUpdated()); + + data.update(newGroup); + assertTrue(data.isNew()); + assertFalse(data.isUpdated()); + assertSame(newGroup, data.getGroup()); + + // repeat with a new group + newGroup = new PdpGroup(oldGroup); + data.update(newGroup); + assertTrue(data.isNew()); + assertFalse(data.isUpdated()); + assertSame(newGroup, data.getGroup()); + } + + @Test + public void testUpdateOnly() { assertFalse(data.isUpdated()); assertSame(oldGroup, data.getGroup()); data.update(newGroup); assertTrue(data.isUpdated()); + assertFalse(data.isNew()); assertSame(newGroup, data.getGroup()); // repeat newGroup = new PdpGroup(oldGroup); data.update(newGroup); assertTrue(data.isUpdated()); + assertFalse(data.isNew()); assertSame(newGroup, data.getGroup()); // incorrect name diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteControllerV1.java index c3928789..458ca9e7 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteControllerV1.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteControllerV1.java @@ -31,14 +31,13 @@ import org.onap.policy.pap.main.rest.CommonPapRestServer; public class TestPdpGroupDeleteControllerV1 extends CommonPapRestServer { - private static final String NOT_IMPLEMENTED_YET = "not implemented yet"; + private static final String GROUP_NOT_FOUND = "group not found"; private static final String DELETE_GROUP_ENDPOINT = "pdps/groups"; private static final String DELETE_POLICIES_ENDPOINT = "pdps/policies"; @Test public void testSwagger() throws Exception { super.testSwagger(DELETE_GROUP_ENDPOINT + "/{name}"); - super.testSwagger(DELETE_GROUP_ENDPOINT + "/{name}/versions/{version}"); super.testSwagger(DELETE_POLICIES_ENDPOINT + "/{name}"); super.testSwagger(DELETE_POLICIES_ENDPOINT + "/{name}/versions/{version}"); @@ -52,31 +51,12 @@ public class TestPdpGroupDeleteControllerV1 extends CommonPapRestServer { Response rawresp = invocationBuilder.delete(); PdpGroupDeleteResponse resp = rawresp.readEntity(PdpGroupDeleteResponse.class); assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); - assertEquals(NOT_IMPLEMENTED_YET, resp.getErrorDetails()); + assertEquals(GROUP_NOT_FOUND, resp.getErrorDetails()); rawresp = invocationBuilder.delete(); resp = rawresp.readEntity(PdpGroupDeleteResponse.class); assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); - assertEquals(NOT_IMPLEMENTED_YET, resp.getErrorDetails()); - - // verify it fails when no authorization info is included - checkUnauthRequest(uri, req -> req.delete()); - } - - @Test - public void testDeleteGroupVersion() throws Exception { - String uri = DELETE_GROUP_ENDPOINT + "/my-name/versions/1.2.3"; - - Invocation.Builder invocationBuilder = sendRequest(uri); - Response rawresp = invocationBuilder.delete(); - PdpGroupDeleteResponse resp = rawresp.readEntity(PdpGroupDeleteResponse.class); - assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); - assertEquals(NOT_IMPLEMENTED_YET, resp.getErrorDetails()); - - rawresp = invocationBuilder.delete(); - resp = rawresp.readEntity(PdpGroupDeleteResponse.class); - assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); - assertEquals(NOT_IMPLEMENTED_YET, resp.getErrorDetails()); + assertEquals(GROUP_NOT_FOUND, resp.getErrorDetails()); // verify it fails when no authorization info is included checkUnauthRequest(uri, req -> req.delete()); diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteProvider.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteProvider.java index dbb7951e..c0b08644 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteProvider.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeleteProvider.java @@ -1,4 +1,4 @@ -/* +/*- * ============LICENSE_START======================================================= * ONAP PAP * ================================================================================ @@ -29,7 +29,9 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; @@ -57,7 +59,6 @@ public class TestPdpGroupDeleteProvider extends ProviderSuper { private static final String POLICY1_NAME = "policyA"; private static final String POLICY1_VERSION = "1.2.3"; private static final String GROUP1_NAME = "groupA"; - private static final String GROUP1_VERSION = "200.2.3"; private MyProvider prov; private SessionData session; @@ -91,10 +92,62 @@ public class TestPdpGroupDeleteProvider extends ProviderSuper { } @Test - public void testDeleteGroup() { - Pair pair = prov.deleteGroup(GROUP1_NAME, GROUP1_VERSION); - assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); - assertEquals("not implemented yet", pair.getRight().getErrorDetails()); + public void testDeleteGroup_Inctive() throws Exception { + PdpGroup group = loadGroup("deleteGroup.json"); + + when(session.getGroup(GROUP1_NAME)).thenReturn(group); + + prov.deleteGroup(GROUP1_NAME); + + verify(session).deleteGroupFromDb(group); + + // should be no PDP requests + verify(session, never()).addRequests(any(), any()); + } + + @Test + public void testDeleteGroup_Active() throws Exception { + PdpGroup group = loadGroup("deleteGroup.json"); + + group.setPdpGroupState(PdpState.ACTIVE); + + when(session.getGroup(GROUP1_NAME)).thenReturn(group); + + assertThatThrownBy(() -> prov.deleteGroup(GROUP1_NAME)).isInstanceOf(PolicyPapRuntimeException.class) + .hasMessage("group is still ACTIVE"); + } + + @Test + public void testDeleteGroup_NotFound() throws Exception { + assertThatThrownBy(() -> prov.deleteGroup(GROUP1_NAME)).isInstanceOf(PolicyPapRuntimeException.class) + .hasMessage("group not found"); + } + + @Test + public void testDeleteGroup_Inactive() throws Exception { + PdpGroup group = loadGroup("deleteGroup.json"); + + when(session.getGroup(GROUP1_NAME)).thenReturn(group); + + prov.deleteGroup(GROUP1_NAME); + + verify(session).deleteGroupFromDb(group); + + // should done no requests for the PDPs + verify(session, never()).addRequests(any(), any()); + } + + @Test + public void testDeleteGroup_DaoEx() throws Exception { + PdpGroup group = loadGroup("deleteGroup.json"); + + when(session.getGroup(GROUP1_NAME)).thenReturn(group); + + PfModelException ex = new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION); + doThrow(ex).when(session).deleteGroupFromDb(group); + + assertThatThrownBy(() -> prov.deleteGroup(GROUP1_NAME)).isInstanceOf(PolicyPapRuntimeException.class) + .hasMessage(ProviderBase.DB_ERROR_MSG); } @Test diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java index 8ca205cd..cad73d92 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java @@ -22,6 +22,7 @@ package org.onap.policy.pap.main.rest.depundep; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; @@ -29,7 +30,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.onap.policy.pap.main.rest.depundep.ProviderBase.DB_ERROR_MSG; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.TreeMap; +import java.util.stream.Collectors; import javax.ws.rs.core.Response.Status; import org.apache.commons.lang3.tuple.Pair; import org.junit.AfterClass; @@ -39,14 +45,21 @@ import org.onap.policy.common.utils.services.Registry; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.pap.concepts.PdpDeployPolicies; import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse; +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.PdpUpdate; +import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; public class TestPdpGroupDeployProvider extends ProviderSuper { private static final String EXPECTED_EXCEPTION = "expected exception"; private static final Object REQUEST_FAILED_MSG = "request failed"; private static final String POLICY1_NAME = "policyA"; + private static final String POLICY2_NAME = "policyB"; private static final String POLICY1_VERSION = "1.2.3"; private static final String GROUP1_NAME = "groupA"; private static final String PDP1_TYPE = "pdpTypeA"; @@ -79,10 +92,365 @@ public class TestPdpGroupDeployProvider extends ProviderSuper { } @Test - public void testDeployGroup() { - Pair pair = prov.deployGroup(new PdpGroups()); + public void testCreateOrUpdateGroups() throws Exception { + Pair pair = prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json")); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + // no groups, so no action should have been taken + assertNoGroupAction(); + } + + @Test + public void testCreateOrUpdateGroups_InvalidRequest() throws Exception { + Pair pair = prov.createOrUpdateGroups(new PdpGroups()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("is null")); + + assertNoGroupAction(); + } + + @Test + public void testCreateOrUpdate_Invalid() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED); + + Pair pair = prov.createOrUpdateGroups(groups); assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); - assertEquals("not implemented yet", pair.getRight().getErrorDetails()); + assertTrue(pair.getRight().getErrorDetails().contains("pdpGroupState")); + + assertNoGroupAction(); + } + + @Test + public void testAddGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup group = groups.getGroups().get(0); + group.setPdpGroupState(PdpState.PASSIVE); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + // should not have updated the state + assertEquals(PdpState.PASSIVE, group.getPdpGroupState()); + + assertSame(group, getGroupCreates().get(0)); + } + + @Test + public void testAddGroup_Invalid() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("pdpGroupState")); + + assertNoGroupAction(); + } + + @Test + public void testAddGroup_InvalidSubGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + + // policy won't match supported type + groups.getGroups().get(0).getPdpSubgroups().get(0).getSupportedPolicyTypes().get(0).setVersion("99.99.99"); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("supported policy")); + + assertNoGroupAction(); + } + + @Test + public void testValidateGroupOnly_NullState() { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(null); + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + } + + @Test + public void testValidateGroupOnly_Active() { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE); + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + } + + @Test + public void testValidateGroupOnly_Passive() { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE); + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + } + + @Test + public void testValidateGroupOnly_Invalid() { + PdpGroups groups = loadPdpGroups("createGroups.json"); + groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("pdpGroupState")); + } + + @Test + public void testUpdateGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + + // DB group = new group + PdpGroup group = new PdpGroup(groups.getGroups().get(0)); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertNoGroupAction(); + } + + @Test + public void testUpdateGroup_PropertiesChanged() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + + PdpGroup group = new PdpGroup(groups.getGroups().get(0)); + group.setProperties(new TreeMap<>()); + + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("properties")); + + assertNoGroupAction(); + } + + @Test + public void testUpdateGroup_NewDescription() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + group.setDescription("old description"); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertGroupUpdateOnly(group); + + assertEquals(group.getDescription(), "my description"); + assertEquals(newgrp.toString(), group.toString()); + } + + @Test + public void testUpdateGroup_NewSubGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroupsNewSub.json"); + PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + PdpGroup newgrp = groups.getGroups().get(0); + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateGroup_UpdatedSubGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + // something different in this subgroup + group.getPdpSubgroups().get(0).setDesiredInstanceCount(10); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateGroup_MultipleChanges() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0); + subgrp.setDesiredInstanceCount(30); + subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION)); + subgrp.getSupportedPolicyTypes().add(new ToscaPolicyTypeIdentifier("typeX", "9.8.7")); + + when(dao.getPolicyList(POLICY2_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("createGroupNewPolicy.json")); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies()); + Collections.sort(group.getPdpSubgroups().get(0).getPolicies()); + + assertEquals(newgrp.toString(), group.toString()); + + // this requires a PDP UPDATE message + assertGroupUpdate(group, subgrp); + } + + @Test + public void testUpdateField_Unchanged() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertNoGroupAction(); + } + + @Test + public void testUpdateField_WasNull() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + group.setDescription(null); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateField_NowNull() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + newgrp.setDescription(null); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateField_Changed() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + newgrp.setDescription(group.getDescription() + "-changed"); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testAddSubGroup() throws Exception { + PdpGroups groups = loadPdpGroups("createGroupsNewSub.json"); + PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + PdpGroup newgrp = groups.getGroups().get(0); + + PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1); + newsub.setCurrentInstanceCount(0); + newsub.setPdpInstances(new ArrayList<>(0)); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateSubGroup_Invalid() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + // change properties + newgrp.getPdpSubgroups().get(0).setProperties(new TreeMap<>()); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("properties")); + + assertNoGroupAction(); + } + + @Test + public void testUpdateSubGroup_SupportedPolicies() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes().add(new ToscaPolicyTypeIdentifier("typeX", "9.8.7")); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateSubGroup_DesiredCount() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + newgrp.getPdpSubgroups().get(0).setDesiredInstanceCount(20); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + assertEquals(newgrp.toString(), group.toString()); + assertGroupUpdateOnly(group); + } + + @Test + public void testUpdateSubGroup_Policies() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0); + subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION)); + + when(dao.getPolicyList(POLICY2_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("createGroupNewPolicy.json")); + + assertEquals(Status.OK, prov.createOrUpdateGroups(groups).getLeft()); + + Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies()); + Collections.sort(group.getPdpSubgroups().get(0).getPolicies()); + + assertEquals(newgrp.toString(), group.toString()); + + // this requires a PDP UPDATE message + assertGroupUpdate(group, subgrp); + } + + @Test + public void testValidateSubGroup_PropertiesMismatch() throws Exception { + PdpGroups groups = loadPdpGroups("createGroups.json"); + PdpGroup newgrp = groups.getGroups().get(0); + PdpGroup group = new PdpGroup(newgrp); + when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group)); + + newgrp.setProperties(new TreeMap<>()); + + Pair pair = prov.createOrUpdateGroups(groups); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertTrue(pair.getRight().getErrorDetails().contains("properties")); + + assertNoGroupAction(); } @Test @@ -180,6 +548,44 @@ public class TestPdpGroupDeployProvider extends ProviderSuper { assertTrue(update.getPolicies().contains(policy1)); } + private void assertNoGroupAction() throws Exception { + verify(dao, never()).createPdpGroups(any()); + verify(dao, never()).updatePdpGroups(any()); + verify(reqmap, never()).addRequest(any(), any()); + } + + private void assertGroupUpdate(PdpGroup group, PdpSubGroup subgrp) throws Exception { + verify(dao, never()).createPdpGroups(any()); + + assertEquals(0, getStateChangeRequests(1).size()); + + List pdpUpdates = getUpdateRequests(1); + assertEquals(1, pdpUpdates.size()); + + PdpUpdate pdpUpdate = pdpUpdates.get(0); + assertEquals("pdpA", pdpUpdate.getName()); + assertEquals(group.getName(), pdpUpdate.getPdpGroup()); + + assertEquals(subgrp.getPdpType(), pdpUpdate.getPdpSubgroup()); + + List pdpPolicies = + pdpUpdate.getPolicies().stream().map(ToscaPolicy::getIdentifier).collect(Collectors.toList()); + Collections.sort(pdpPolicies); + + assertEquals(subgrp.getPolicies().toString(), pdpPolicies.toString()); + + List updates = getGroupUpdates(); + assertEquals(Arrays.asList(group), updates); + } + + private void assertGroupUpdateOnly(PdpGroup group) throws Exception { + verify(dao, never()).createPdpGroups(any()); + verify(reqmap, never()).addRequest(any(), any()); + + List updates = getGroupUpdates(); + assertEquals(Arrays.asList(group), updates); + } + /** * Loads a standard request. * diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java index fd351c89..2eac4324 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java @@ -20,9 +20,11 @@ package org.onap.policy.pap.main.rest.depundep; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; @@ -35,20 +37,23 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import javax.ws.rs.core.Response.Status; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Before; import org.junit.Test; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pap.main.PolicyPapRuntimeException; public class TestSessionData extends ProviderSuper { private static final String GROUP_NAME = "groupA"; - private static final String GROUP_NAME2 = "groupB"; private static final String PDP1 = "pdp_1"; private static final String PDP2 = "pdp_2"; private static final String PDP3 = "pdp_3"; @@ -58,6 +63,7 @@ public class TestSessionData extends ProviderSuper { private static final String POLICY_VERSION2 = POLICY_VERSION_PREFIX + "4"; private static final String POLICY_TYPE = "myType"; private static final String POLICY_TYPE_VERSION = "10.20.30"; + private static final String EXPECTED_EXCEPTION = "expected exception"; private SessionData session; private ToscaPolicyIdentifier ident; @@ -78,8 +84,8 @@ public class TestSessionData extends ProviderSuper { ident = new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION); type = new ToscaPolicyTypeIdentifier(POLICY_TYPE, POLICY_TYPE_VERSION); type2 = new ToscaPolicyTypeIdentifier(POLICY_TYPE, POLICY_TYPE_VERSION + "0"); - group1 = makeGroup(GROUP_NAME); - group2 = makeGroup(GROUP_NAME2); + group1 = loadGroup("group1.json"); + group2 = loadGroup("group2.json"); session = new SessionData(dao); } @@ -115,14 +121,6 @@ public class TestSessionData extends ProviderSuper { assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("cannot find policy: myPolicy 1.2.3"); } - @Test - public void testGetPolicy_TooMany() throws Exception { - ToscaPolicy policy = new ToscaPolicy(); - when(dao.getPolicyList(any(), any())).thenReturn(Arrays.asList(policy, policy)); - - assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("too many policies match: myPolicy 1.2.3"); - } - @Test public void testGetPolicy_DaoEx() throws Exception { PfModelException ex = new PfModelException(Status.INTERNAL_SERVER_ERROR, "expected exception"); @@ -131,6 +129,71 @@ public class TestSessionData extends ProviderSuper { assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("cannot get policy: myPolicy 1.2.3").hasCause(ex); } + @Test + public void testAddRequests_testGetPdpStateChanges_testGetPdpUpdates() { + // pre-load with a update and state-change for other PDPs + PdpUpdate update2 = makeUpdate(PDP2); + session.addUpdate(update2); + + PdpStateChange change3 = makeStateChange(PDP3); + session.addStateChange(change3); + + // add requests + PdpUpdate update = makeUpdate(PDP1); + PdpStateChange change = makeStateChange(PDP1); + session.addRequests(update, change); + verifyRequests(update, update2, change, change3); + + /* + * repeat with a new pair + */ + update = makeUpdate(PDP1); + change = makeStateChange(PDP1); + session.addRequests(update, change); + verifyRequests(update, update2, change, change3); + + // just make an update this time + update = makeUpdate(PDP1); + session.addUpdate(update); + verifyRequests(update, update2, change, change3); + } + + private void verifyRequests(PdpUpdate update, PdpUpdate update2, PdpStateChange change, PdpStateChange change3) { + List> requests = sort(session.getPdpRequests(), this::compare); + assertEquals(3, requests.size()); + + System.out.println(requests); + System.out.println(update); + + Iterator> reqiter = requests.iterator(); + Pair pair = reqiter.next(); + assertSame(update, pair.getLeft()); + assertSame(change, pair.getRight()); + + pair = reqiter.next(); + assertSame(update2, pair.getLeft()); + assertSame(null, pair.getRight()); + + pair = reqiter.next(); + assertSame(null, pair.getLeft()); + assertSame(change3, pair.getRight()); + + // verify individual lists + List updates = Arrays.asList(update, update2); + assertEquals(sort(updates, this::compare), sort(session.getPdpUpdates(), this::compare)); + + List changes = Arrays.asList(change, change3); + assertEquals(sort(changes, this::compare), sort(session.getPdpStateChanges(), this::compare)); + } + + @Test + public void testAddRequests_MismatchedNames() { + PdpUpdate update = makeUpdate(PDP1); + PdpStateChange change = makeStateChange(PDP2); + assertThatIllegalArgumentException().isThrownBy(() -> session.addRequests(update, change)) + .withMessage("PDP name mismatch pdp_1, pdp_2"); + } + @Test public void testAddUpdate_testGetPdpUpdates() { // several different updates, but one duplicate @@ -143,17 +206,40 @@ public class TestSessionData extends ProviderSuper { PdpUpdate update3 = makeUpdate(PDP3); session.addUpdate(update3); - List lst = sort(session.getPdpUpdates(), this::compare); + List lst = sort(getUpdateRequests(), this::compare); assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString()); // overwrite one update2 = makeUpdate(PDP2); session.addUpdate(update2); - lst = sort(session.getPdpUpdates(), this::compare); + lst = sort(getUpdateRequests(), this::compare); assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString()); } + @Test + public void testAddStateChange_testGetPdpStateChanges() { + // several different changes, but one duplicate + PdpStateChange change1 = makeStateChange(PDP1); + session.addStateChange(change1); + + PdpStateChange change2 = makeStateChange(PDP2); + session.addStateChange(change2); + + PdpStateChange change3 = makeStateChange(PDP3); + session.addStateChange(change3); + + List lst = sort(getStateChangeRequests(), this::compare); + assertEquals(Arrays.asList(change1, change2, change3).toString(), lst.toString()); + + // overwrite one + change2 = makeStateChange(PDP2); + session.addStateChange(change2); + + lst = sort(getStateChangeRequests(), this::compare); + assertEquals(Arrays.asList(change1, change2, change3).toString(), lst.toString()); + } + private ToscaPolicy makePolicy(String name, String version) { ToscaPolicy policy = new ToscaPolicy(); @@ -183,12 +269,19 @@ public class TestSessionData extends ProviderSuper { assertThatThrownBy(() -> session.getPolicyMaxVersion(POLICY_NAME)).hasMessage("cannot find policy: myPolicy"); } - private PdpGroup makeGroup(String name) { - PdpGroup group = new PdpGroup(); - - group.setName(name); - - return group; + @Test + public void testCreate() throws Exception { + session.create(group1); + assertSame(group1, session.getGroup(group1.getName())); + + // can add another + session.create(group2); + assertSame(group1, session.getGroup(group1.getName())); + assertSame(group2, session.getGroup(group2.getName())); + + // cannot overwrite + assertThatIllegalStateException().isThrownBy(() -> session.create(group1)) + .withMessage("group already cached: groupA"); } @Test @@ -228,6 +321,48 @@ public class TestSessionData extends ProviderSuper { .withMessage("group not cached: groupA"); } + @Test + public void testGetGroup() throws Exception { + when(dao.getPdpGroups(GROUP_NAME)).thenReturn(Arrays.asList(group1)); + + assertSame(group1, session.getGroup(GROUP_NAME)); + verify(dao).getPdpGroups(any()); + + // repeat + assertSame(group1, session.getGroup(GROUP_NAME)); + + // should not access dao again + verify(dao, times(1)).getPdpGroups(any()); + } + + @Test + public void testGetGroup_NotFound() throws Exception { + when(dao.getPdpGroups(GROUP_NAME)).thenReturn(Collections.emptyList()); + + assertNull(session.getGroup(GROUP_NAME)); + verify(dao).getPdpGroups(any()); + + // repeat + assertNull(session.getGroup(GROUP_NAME)); + + // SHOULD access dao again + verify(dao, times(2)).getPdpGroups(GROUP_NAME); + + // find it this time + when(dao.getPdpGroups(GROUP_NAME)).thenReturn(Arrays.asList(group1)); + assertSame(group1, session.getGroup(GROUP_NAME)); + verify(dao, times(3)).getPdpGroups(GROUP_NAME); + } + + @Test + public void testGetGroup_DaoEx() throws Exception { + PfModelException ex = new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION); + when(dao.getPdpGroups(GROUP_NAME)).thenThrow(ex); + + assertThatThrownBy(() -> session.getGroup(GROUP_NAME)).isInstanceOf(PolicyPapRuntimeException.class) + .hasCause(ex); + } + @Test public void testGetActivePdpGroupsByPolicyType() throws Exception { List groups = Arrays.asList(group1, group2); @@ -263,10 +398,17 @@ public class TestSessionData extends ProviderSuper { @Test public void testUpdateDb() throws Exception { // force the groups into the cache - PdpGroup group3 = makeGroup("groupC"); + PdpGroup group3 = loadGroup("group3.json"); when(dao.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1, group2, group3)); session.getActivePdpGroupsByPolicyType(type); + // create groups 4 & 5 + PdpGroup group4 = loadGroup("group4.json"); + session.create(group4); + + PdpGroup group5 = loadGroup("group5.json"); + session.create(group5); + // update group 1 when(dao.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group1)); PdpGroup newgrp1 = new PdpGroup(group1); @@ -281,13 +423,25 @@ public class TestSessionData extends ProviderSuper { PdpGroup newgrp3 = new PdpGroup(group3); session.update(newgrp3); + // update group 5 + when(dao.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group5)); + PdpGroup newgrp5 = new PdpGroup(group5); + session.update(newgrp5); + // push the changes to the DB session.updateDb(); + // expect one create for groups 4 & 5 (group5 replaced by newgrp5) + List creates = getGroupCreates(); + assertEquals(2, creates.size()); + assertSame(group4, creates.get(0)); + assertSame(newgrp5, creates.get(1)); + // expect one update for groups 1 & 3 - List changes = getGroupUpdates(); - assertSame(newgrp1, changes.get(0)); - assertSame(newgrp3, changes.get(1)); + List updates = getGroupUpdates(); + assertEquals(2, updates.size()); + assertSame(newgrp1, updates.get(0)); + assertSame(newgrp3, updates.get(1)); } @Test @@ -301,6 +455,13 @@ public class TestSessionData extends ProviderSuper { verify(dao, never()).updatePdpGroups(any()); } + @Test + public void testDeleteGroupFromDb() throws Exception { + session.deleteGroupFromDb(group1); + + verify(dao).deletePdpGroup(group1.getName()); + } + private PdpUpdate makeUpdate(String pdpName) { PdpUpdate update = new PdpUpdate(); @@ -309,6 +470,22 @@ public class TestSessionData extends ProviderSuper { return update; } + private PdpStateChange makeStateChange(String pdpName) { + PdpStateChange change = new PdpStateChange(); + + change.setName(pdpName); + + return change; + } + + private List getUpdateRequests() { + return session.getPdpUpdates(); + } + + private List getStateChangeRequests() { + return session.getPdpStateChanges(); + } + private List sort(Collection collection, Comparator comparator) { List lst = new ArrayList<>(collection); Collections.sort(lst, comparator); @@ -316,7 +493,19 @@ public class TestSessionData extends ProviderSuper { return lst; } + private int compare(Pair left, Pair right) { + return getName(left).compareTo(getName(right)); + } + private int compare(PdpUpdate left, PdpUpdate right) { return left.getName().compareTo(right.getName()); } + + private int compare(PdpStateChange left, PdpStateChange right) { + return left.getName().compareTo(right.getName()); + } + + private String getName(Pair pair) { + return (pair.getKey() != null ? pair.getKey().getName() : pair.getValue().getName()); + } } -- cgit 1.2.3-korg