aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java41
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java8
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java159
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java21
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/XacmlStateTest.java164
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisherTest.java189
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpPapRegistrationTest.java71
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisherTest.java181
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListenerTest.java98
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListenerTest.java131
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;
+ }
+ }
+}