diff options
Diffstat (limited to 'main')
10 files changed, 877 insertions, 186 deletions
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java index 29044744..3177c096 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java @@ -20,15 +20,19 @@ package org.onap.policy.pdpx.main.comm; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import lombok.Getter; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.pdpx.main.XacmlState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XacmlPdpHearbeatPublisher extends TimerTask { +public class XacmlPdpHearbeatPublisher implements Runnable { + public static final int DEFAULT_INTERVAL_MS = 60000; private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHearbeatPublisher.class); @@ -42,9 +46,12 @@ public class XacmlPdpHearbeatPublisher extends TimerTask { /** * Current timer interval, in milliseconds. */ - private long intervalMs = 60000; + @Getter + private long intervalMs = DEFAULT_INTERVAL_MS; - private Timer timer = null; + private ScheduledExecutorService timerThread; + + private ScheduledFuture<?> timer; /** @@ -70,9 +77,9 @@ public class XacmlPdpHearbeatPublisher extends TimerTask { * Method to terminate the heart beat. */ public synchronized void terminate() { - if (timer != null) { - timer.cancel(); - timer.purge(); + if (timerThread != null) { + timerThread.shutdownNow(); + timerThread = null; timer = null; } } @@ -87,9 +94,9 @@ public class XacmlPdpHearbeatPublisher extends TimerTask { if (intervalMs != null && intervalMs > 0 && intervalMs != this.intervalMs) { this.intervalMs = intervalMs; - if (timer != null) { - terminate(); - start(); + if (timerThread != null) { + timer.cancel(false); + timer = timerThread.scheduleWithFixedDelay(this, 0, this.intervalMs, TimeUnit.MILLISECONDS); } } } @@ -98,9 +105,15 @@ public class XacmlPdpHearbeatPublisher extends TimerTask { * Starts the timer. */ public synchronized void start() { - if (timer == null) { - timer = new Timer(true); - timer.scheduleAtFixedRate(this, 0, this.intervalMs); + if (timerThread == null) { + timerThread = makeTimerThread(); + timer = timerThread.scheduleWithFixedDelay(this, 0, this.intervalMs, TimeUnit.MILLISECONDS); } } + + // these may be overridden by junit tests + + protected ScheduledExecutorService makeTimerThread() { + return Executors.newScheduledThreadPool(1); + } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java index 2a8ef99f..64ffdeda 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java @@ -55,7 +55,7 @@ public class XacmlPdpUpdateListener extends ScoListener<PdpUpdate> { super(PdpUpdate.class); this.state = state; this.heartbeat = heartbeat; - this.publisher = new XacmlPdpUpdatePublisher(client, state, appManager); + this.publisher = makePublisher(client, state, appManager); } @Override @@ -77,4 +77,10 @@ public class XacmlPdpUpdateListener extends ScoListener<PdpUpdate> { } + // these may be overridden by junit tests + protected XacmlPdpUpdatePublisher makePublisher(TopicSinkClient client, XacmlState state, + XacmlPdpApplicationManager appManager) { + + return new XacmlPdpUpdatePublisher(client, state, appManager); + } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java deleted file mode 100644 index a6213da2..00000000 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.pdpx.main.rest; - -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.capabilities.Startable; -import org.onap.policy.common.endpoints.http.server.HttpServletServer; -import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; -import org.onap.policy.common.gson.GsonMessageBodyHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class to manage life cycle of xacml pdp rest server. - * - */ -public class XacmlPdpRestServer implements Startable { - - private static final String SEPARATOR = "."; - private static final String HTTP_SERVER_SERVICES = "http.server.services"; - private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpRestServer.class); - - private List<HttpServletServer> servers = new ArrayList<>(); - - private final RestServerParameters restServerParameters; - - /** - * Constructor for instantiating XacmlPdpRestServer. - * - * @param restServerParameters the rest server parameters - */ - public XacmlPdpRestServer(final RestServerParameters restServerParameters) { - this.restServerParameters = restServerParameters; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean start() { - try { - LOGGER.info("Starting XacmlPdpRestServer..."); - - // - // Get the server properties - // - servers = HttpServletServerFactoryInstance.getServerFactory().build(getServerProperties()); - // - // Start all the servers - // - for (final HttpServletServer server : servers) { - if (server.isAaf()) { - server.addFilterClass(null, XacmlPdpAafFilter.class.getName()); - } - server.start(); - } - LOGGER.info("servers are started"); - } catch (final Exception exp) { - LOGGER.error("Failed to start xacml pdp http server", exp); - return false; - } - return true; - } - - /** - * Creates the server properties object using restServerParameters. - * - * @return the properties object - */ - private Properties getServerProperties() { - final Properties props = new Properties(); - props.setProperty(HTTP_SERVER_SERVICES, restServerParameters.getName()); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".host", - restServerParameters.getHost()); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".port", - Integer.toString(restServerParameters.getPort())); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".restClasses", - XacmlPdpRestController.class.getName()); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".managed", "false"); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".swagger", "true"); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".userName", - restServerParameters.getUserName()); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".password", - restServerParameters.getPassword()); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".https", - String.valueOf(restServerParameters.isHttps())); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".aaf", - String.valueOf(restServerParameters.isAaf())); - props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".serialization.provider", - GsonMessageBodyHandler.class.getName()); - return props; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean stop() { - for (final HttpServletServer server : servers) { - try { - server.shutdown(); - } catch (final Exception exp) { - LOGGER.error("Failed to stop xacml pdp http server", exp); - } - } - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public void shutdown() { - stop(); - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean isAlive() { - return !servers.isEmpty(); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("XacmlPdpRestServer [servers="); - builder.append(servers); - builder.append("]"); - return builder.toString(); - } - -} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java index eb3ac230..70253c09 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java @@ -29,6 +29,7 @@ import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; import org.onap.policy.common.endpoints.event.comm.TopicSource; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; +import org.onap.policy.common.endpoints.http.server.RestServer; import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.common.utils.services.ServiceManagerContainer; @@ -40,8 +41,9 @@ import org.onap.policy.pdpx.main.comm.XacmlPdpHearbeatPublisher; import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpStateChangeListener; import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpUpdateListener; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; +import org.onap.policy.pdpx.main.rest.XacmlPdpAafFilter; import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; -import org.onap.policy.pdpx.main.rest.XacmlPdpRestServer; +import org.onap.policy.pdpx.main.rest.XacmlPdpRestController; import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,11 +68,6 @@ public class XacmlPdpActivator extends ServiceManagerContainer { private final XacmlPdpParameterGroup xacmlPdpParameterGroup; /** - * The XACML PDP REST API server. - */ - private XacmlPdpRestServer restServer; - - /** * Listens for messages on the topic, decodes them into a {@link PdpStatus} message, and then * dispatches them to appropriate listener. */ @@ -91,6 +88,7 @@ public class XacmlPdpActivator extends ServiceManagerContainer { final XacmlPdpHearbeatPublisher heartbeat; final TopicSinkClient sinkClient; final XacmlState state; + final RestServer restServer; try { XacmlPdpApplicationManager appmgr = @@ -119,6 +117,9 @@ public class XacmlPdpActivator extends ServiceManagerContainer { msgDispatcher.register(PdpMessageType.PDP_UPDATE.name(), new XacmlPdpUpdateListener(sinkClient, state, heartbeat, appmgr)); + restServer = new RestServer(xacmlPdpParameterGroup.getRestServerParameters(), XacmlPdpAafFilter.class, + XacmlPdpRestController.class); + } catch (RuntimeException | TopicSinkClientException e) { throw new PolicyXacmlPdpRuntimeException(e.getMessage(), e); } @@ -146,13 +147,9 @@ public class XacmlPdpActivator extends ServiceManagerContainer { heartbeat::start, heartbeat::terminate); - addAction("Create REST server", - () -> restServer = new XacmlPdpRestServer(xacmlPdpParameterGroup.getRestServerParameters()), - () -> restServer = null); - addAction("REST server", - () -> restServer.start(), - () -> restServer.stop()); + restServer::start, + restServer::stop); // @formatter:on } diff --git a/main/src/test/java/org/onap/policy/pdpx/main/XacmlStateTest.java b/main/src/test/java/org/onap/policy/pdpx/main/XacmlStateTest.java new file mode 100644 index 00000000..20136bf0 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/XacmlStateTest.java @@ -0,0 +1,164 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.pdp.concepts.PdpResponseDetails; +import org.onap.policy.models.pdp.concepts.PdpStateChange; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.pdp.enums.PdpHealthStatus; +import org.onap.policy.models.pdp.enums.PdpResponseStatus; +import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator; + +public class XacmlStateTest { + private static final String PDP_TYPE = "xacml"; + private static final String GROUP = "my-group"; + private static final String SUBGROUP = "my-subgroup"; + private static final PdpState STATE = PdpState.SAFE; + + @Mock + private XacmlPdpApplicationManager appmgr; + + @Mock + private XacmlPdpActivator act; + + private ToscaPolicyTypeIdentifier ident1; + private ToscaPolicyTypeIdentifier ident2; + + private String hostName; + + private XacmlState state; + + /** + * Initializes objects, including the state. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + hostName = NetworkUtil.getHostname(); + + ident1 = new ToscaPolicyTypeIdentifier("nameA", "typeA"); + ident2 = new ToscaPolicyTypeIdentifier("nameB", "typeB"); + + when(appmgr.getToscaPolicyTypeIdents()).thenReturn(Arrays.asList(ident1, ident2)); + + XacmlPdpActivator.setCurrent(act); + + state = new XacmlState(appmgr); + } + + @AfterClass + public static void tearDownAfterClass() { + XacmlPdpActivator.setCurrent(null); + } + + @Test + public void testShouldHandle() { + PdpUpdate msg = new PdpUpdate(); + assertFalse(state.shouldHandle(msg)); + + msg.setName(NetworkUtil.getHostname()); + assertTrue(state.shouldHandle(msg)); + } + + @Test + public void testGenHeartbeat() { + // not healthy + PdpStatus status = state.genHeartbeat(); + assertEquals(PdpHealthStatus.NOT_HEALTHY, status.getHealthy()); + assertEquals(hostName, status.getName()); + assertEquals(PDP_TYPE, status.getPdpType()); + assertEquals(PdpState.PASSIVE, status.getState()); + assertEquals("[ToscaPolicyTypeIdentifier(name=nameA, version=typeA), " + + "ToscaPolicyTypeIdentifier(name=nameB, version=typeB)]", + status.getSupportedPolicyTypes().toString()); + assertTrue(status.getPolicies().isEmpty()); + + // healthy + when(act.isAlive()).thenReturn(true); + + status = state.genHeartbeat(); + assertEquals(PdpHealthStatus.HEALTHY, status.getHealthy()); + } + + @Test + public void testUpdateInternalStatePdpStateChange() { + PdpStateChange req = new PdpStateChange(); + req.setName(hostName); + req.setPdpGroup(GROUP); + req.setPdpSubgroup(SUBGROUP); + req.setState(STATE); + + PdpStatus status = state.updateInternalState(req); + assertEquals(PdpState.SAFE, status.getState()); + + PdpResponseDetails resp = status.getResponse(); + assertNotNull(resp); + assertEquals(req.getRequestId(), resp.getResponseTo()); + assertEquals(PdpResponseStatus.SUCCESS, resp.getResponseStatus()); + + // ensure info was saved + status = state.genHeartbeat(); + assertEquals(PdpState.SAFE, status.getState()); + } + + @Test + public void testUpdateInternalStatePdpUpdate() { + PdpUpdate req = new PdpUpdate(); + req.setPdpGroup(GROUP); + req.setPdpSubgroup(SUBGROUP); + + PdpStatus status = state.updateInternalState(req); + + PdpResponseDetails resp = status.getResponse(); + assertNotNull(resp); + assertEquals(req.getRequestId(), resp.getResponseTo()); + assertEquals(PdpResponseStatus.SUCCESS, resp.getResponseStatus()); + + // ensure info was saved + status = state.genHeartbeat(); + assertEquals(GROUP, status.getPdpGroup()); + assertEquals(SUBGROUP, status.getPdpSubgroup()); + } + + @Test + public void testTerminatePdpMessage() { + PdpStatus status = state.terminatePdpMessage(); + assertEquals(PdpState.TERMINATED, status.getState()); + } +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisherTest.java b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisherTest.java new file mode 100644 index 00000000..a1f50771 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisherTest.java @@ -0,0 +1,189 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.pdpx.main.XacmlState; + +public class XacmlPdpHearbeatPublisherTest { + + private static final long INTERVAL1 = 1000L; + private static final long INTERVAL2 = 2000L; + private static final long INTERVAL_INVALID = 0; + + @Mock + private TopicSinkClient client; + + @Mock + private XacmlState state; + + @Mock + private ScheduledExecutorService executor; + + @Mock + private ScheduledFuture<?> timer1; + + @Mock + private ScheduledFuture<?> timer2; + + @Mock + private PdpStatus status; + + private Queue<ScheduledFuture<?>> timers; + + private XacmlPdpHearbeatPublisher publisher; + + + /** + * Initializes objects, including the publisher. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + when(state.genHeartbeat()).thenReturn(status); + + timers = new LinkedList<>(Arrays.asList(timer1, timer2)); + + when(executor.scheduleWithFixedDelay(any(), anyLong(), anyLong(), any())).thenAnswer(args -> timers.remove()); + + publisher = new MyPublisher(client, state); + } + + @Test + public void testRun() { + publisher.run(); + + verify(state).genHeartbeat(); + verify(client).send(status); + } + + @Test + public void testTerminate() { + // not yet started + publisher.terminate(); + + + // now start it and then try again + publisher.start(); + publisher.terminate(); + + // timer2 should still be in the queue + assertSame(timer2, timers.peek()); + + + // repeat - nothing more should happen + publisher.terminate(); + + // timer2 should still be in the queue + assertSame(timer2, timers.peek()); + } + + @Test + public void testRestart() { + // not started yet - should only update the interval + publisher.restart(INTERVAL1); + + assertEquals(INTERVAL1, publisher.getIntervalMs()); + assertSame(timer1, timers.peek()); + + // now start it + publisher.start(); + verify(executor).scheduleWithFixedDelay(publisher, 0, INTERVAL1, TimeUnit.MILLISECONDS); + + // null interval - no changes + publisher.restart(null); + verify(executor, times(1)).scheduleWithFixedDelay(any(), anyInt(), anyLong(), any()); + assertSame(timer2, timers.peek()); + + // same interval - no changes + publisher.restart(INTERVAL1); + verify(executor, times(1)).scheduleWithFixedDelay(any(), anyInt(), anyLong(), any()); + assertSame(timer2, timers.peek()); + + // invalid interval - no changes + publisher.restart(INTERVAL_INVALID); + verify(executor, times(1)).scheduleWithFixedDelay(any(), anyInt(), anyLong(), any()); + assertSame(timer2, timers.peek()); + + // new interval - old timer should be cancelled and new started + publisher.restart(INTERVAL2); + verify(timer1).cancel(anyBoolean()); + verify(executor).scheduleWithFixedDelay(publisher, 0, INTERVAL2, TimeUnit.MILLISECONDS); + } + + @Test + public void testStart() { + publisher.start(); + + verify(executor).scheduleWithFixedDelay(publisher, 0, XacmlPdpHearbeatPublisher.DEFAULT_INTERVAL_MS, + TimeUnit.MILLISECONDS); + + // repeat - nothing more should happen + publisher.start(); + verify(executor, times(1)).scheduleWithFixedDelay(any(), anyInt(), anyLong(), any()); + verify(timer1, never()).cancel(anyBoolean()); + } + + @Test + public void testMakeTimerThread() { + // create a plain listener to test the "real" makeTimer() method + publisher = new XacmlPdpHearbeatPublisher(client, state); + + publisher.start(); + publisher.restart(100L); + publisher.terminate(); + } + + private class MyPublisher extends XacmlPdpHearbeatPublisher { + + public MyPublisher(TopicSinkClient topicSinkClient, XacmlState state) { + super(topicSinkClient, state); + } + + @Override + protected ScheduledExecutorService makeTimerThread() { + return executor; + } + } +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpPapRegistrationTest.java b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpPapRegistrationTest.java new file mode 100644 index 00000000..c05e0999 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpPapRegistrationTest.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; +import org.onap.policy.models.pdp.concepts.PdpStatus; + +public class XacmlPdpPapRegistrationTest { + + @Mock + private TopicSinkClient client; + + @Mock + private PdpStatus status; + + private XacmlPdpPapRegistration reg; + + /** + * Initializes objects, including the registration object. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + when(client.send(status)).thenReturn(true); + + reg = new XacmlPdpPapRegistration(client); + } + + @Test + public void testPdpRegistration_SendOk() throws TopicSinkClientException { + reg.pdpRegistration(status); + } + + @Test + public void testPdpRegistration_SendFail() throws TopicSinkClientException { + when(client.send(status)).thenReturn(false); + reg.pdpRegistration(status); + } + + @Test + public void testPdpRegistration_SendEx() throws TopicSinkClientException { + when(client.send(status)).thenThrow(new IllegalStateException()); + reg.pdpRegistration(status); + } +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisherTest.java b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisherTest.java new file mode 100644 index 00000000..31bec51e --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisherTest.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.pdpx.main.XacmlState; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager; + + +/** + * Initializes objects, including the publisher. + */ +public class XacmlPdpUpdatePublisherTest { + + private static final int NEW_COUNT = 4; + + @Mock + private TopicSinkClient client; + + @Mock + private XacmlState state; + + @Mock + private PdpStatus status; + + @Mock + private XacmlPdpApplicationManager appmgr; + + @Mock + private ToscaPolicy deployed1; + + @Mock + private ToscaPolicy deployed2; + + @Mock + private ToscaPolicy deployed3; + + @Mock + private ToscaPolicy deployed4; + + @Mock + private ToscaPolicy added1; + + @Mock + private ToscaPolicy added2; + + @Mock + private PdpUpdate update; + + private XacmlPdpUpdatePublisher publisher; + + + /** + * Initializes objects, including the publisher. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + Map<ToscaPolicy, XacmlApplicationServiceProvider> deployedPolicies = new HashMap<>(); + deployedPolicies.put(deployed1, null); + deployedPolicies.put(deployed2, null); + deployedPolicies.put(deployed3, null); + deployedPolicies.put(deployed4, null); + when(appmgr.getToscaPolicies()).thenReturn(deployedPolicies); + + // update includes two overlaps + List<ToscaPolicy> updatePolicies = Arrays.asList(added1, deployed2, deployed3, added2); + when(update.getPolicies()).thenReturn(updatePolicies); + + when(appmgr.getPolicyCount()).thenReturn(NEW_COUNT); + + when(state.updateInternalState(update)).thenReturn(status); + + when(client.send(any())).thenReturn(true); + + publisher = new XacmlPdpUpdatePublisher(client, state, appmgr); + } + + @Test + public void testHandlePdpUpdate() { + XacmlPdpStatisticsManager statmgr = new XacmlPdpStatisticsManager(); + XacmlPdpStatisticsManager.setCurrent(statmgr); + + publisher.handlePdpUpdate(update); + + // two removed + verify(appmgr).removeUndeployedPolicy(deployed1); + verify(appmgr).removeUndeployedPolicy(deployed4); + + // two added + verify(appmgr).loadDeployedPolicy(added1); + verify(appmgr).loadDeployedPolicy(added2); + + // two untouched + verify(appmgr, never()).removeUndeployedPolicy(deployed2); + verify(appmgr, never()).removeUndeployedPolicy(deployed3); + verify(appmgr, never()).loadDeployedPolicy(deployed2); + verify(appmgr, never()).loadDeployedPolicy(deployed3); + + assertEquals(NEW_COUNT, statmgr.getTotalPoliciesCount()); + + verify(client).send(status); + } + + @Test + public void testHandlePdpUpdate_NullPolicies() { + when(update.getPolicies()).thenReturn(null); + + publisher.handlePdpUpdate(update); + + // all removed + verify(appmgr).removeUndeployedPolicy(deployed1); + verify(appmgr).removeUndeployedPolicy(deployed2); + verify(appmgr).removeUndeployedPolicy(deployed3); + verify(appmgr).removeUndeployedPolicy(deployed4); + + // none added + verify(appmgr, never()).loadDeployedPolicy(any()); + + verify(client).send(status); + } + + @Test + public void testHandlePdpUpdate_NullStats() { + XacmlPdpStatisticsManager.setCurrent(null); + + // should work without throwing an exception + publisher.handlePdpUpdate(update); + + verify(client).send(status); + } + + @Test + public void testHandlePdpUpdate_SendFail() { + + when(client.send(any())).thenReturn(false); + + publisher.handlePdpUpdate(update); + + verify(client).send(status); + } + +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListenerTest.java b/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListenerTest.java new file mode 100644 index 00000000..b49f4e29 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListenerTest.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm.listeners; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStateChange; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.pdpx.main.XacmlState; +import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpStateChangeListener; + +public class XacmlPdpStateChangeListenerTest { + private static final String TOPIC = "my-topic"; + + @Mock + private TopicSinkClient client; + + @Mock + private XacmlState state; + + @Mock + private PdpStatus status; + + @Mock + private PdpStateChange change; + + private XacmlPdpStateChangeListener listener; + + /** + * Initializes objects, including the listener. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + listener = new XacmlPdpStateChangeListener(client, state); + + when(state.shouldHandle(change)).thenReturn(true); + when(state.updateInternalState(change)).thenReturn(status); + + when(client.send(status)).thenReturn(true); + } + + @Test + public void testOnTopicEvent_Unhandled() { + when(state.shouldHandle(change)).thenReturn(false); + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, change); + + verify(state, never()).updateInternalState(any(PdpStateChange.class)); + verify(client, never()).send(any()); + } + + @Test + public void testOnTopicEvent_SendFailed() { + when(client.send(status)).thenReturn(false); + + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, change); + + verify(state).updateInternalState(change); + verify(client).send(status); + } + + @Test + public void testOnTopicEvent_SendOk() { + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, change); + + verify(state).updateInternalState(change); + verify(client).send(status); + } + +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListenerTest.java b/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListenerTest.java new file mode 100644 index 00000000..73870d05 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListenerTest.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm.listeners; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.pdpx.main.XacmlState; +import org.onap.policy.pdpx.main.comm.XacmlPdpHearbeatPublisher; +import org.onap.policy.pdpx.main.comm.XacmlPdpUpdatePublisher; +import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpUpdateListener; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.powermock.reflect.Whitebox; + +public class XacmlPdpUpdateListenerTest { + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final String TOPIC = "my-topic"; + private static final long HB_INTERVAL = 100L; + + @Mock + private TopicSinkClient client; + + @Mock + private XacmlState state; + + @Mock + private XacmlPdpHearbeatPublisher heartbeat; + + @Mock + private XacmlPdpApplicationManager appmgr; + + @Mock + private XacmlPdpUpdatePublisher publisher; + + private PdpUpdate update; + + private XacmlPdpUpdateListener listener; + + /** + * Initializes objects, including the listener. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + listener = new MyListener(client, state, heartbeat, appmgr); + update = new PdpUpdate(); + + when(state.shouldHandle(update)).thenReturn(true); + + update.setPdpHeartbeatIntervalMs(HB_INTERVAL); + } + + @Test + public void testOnTopicEvent_Unhandled() { + when(state.shouldHandle(update)).thenReturn(false); + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, update); + + verify(publisher, never()).handlePdpUpdate(any()); + verify(heartbeat, never()).restart(anyLong()); + } + + @Test + public void testOnTopicEvent_SendOk() { + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, update); + + verify(publisher).handlePdpUpdate(update); + verify(heartbeat).restart(HB_INTERVAL); + } + + @Test + public void testOnTopicEvent_SendEx() { + doThrow(new RuntimeException(EXPECTED_EXCEPTION)).when(publisher).handlePdpUpdate(update); + + listener.onTopicEvent(CommInfrastructure.NOOP, TOPIC, null, update); + + verify(publisher).handlePdpUpdate(update); + verify(heartbeat, never()).restart(anyLong()); + } + + @Test + public void testMakePublisher() { + // create a plain listener to test the "real" makePublisher() method + listener = new XacmlPdpUpdateListener(client, state, heartbeat, appmgr); + assertNotNull(Whitebox.getInternalState(listener, "publisher")); + } + + private class MyListener extends XacmlPdpUpdateListener { + + public MyListener(TopicSinkClient client, XacmlState state, XacmlPdpHearbeatPublisher heartbeat, + XacmlPdpApplicationManager appManager) { + super(client, state, heartbeat, appManager); + } + + @Override + protected XacmlPdpUpdatePublisher makePublisher(TopicSinkClient client, XacmlState state, + XacmlPdpApplicationManager appManager) { + return publisher; + } + } +} |