diff options
Diffstat (limited to 'main')
22 files changed, 773 insertions, 816 deletions
diff --git a/main/pom.xml b/main/pom.xml index 790746b2..27fde504 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -81,6 +81,16 @@ <artifactId>policy-models-pdp</artifactId> <version>${policy.models.version}</version> </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/main/src/main/java/org/onap/policy/pdpx/main/XacmlState.java b/main/src/main/java/org/onap/policy/pdpx/main/XacmlState.java new file mode 100644 index 00000000..521413c8 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/XacmlState.java @@ -0,0 +1,142 @@ +/*- + * ============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 java.util.Collections; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.pdp.concepts.PdpMessage; +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.pdpx.main.rest.XacmlPdpApplicationManager; +import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator; + +/** + * Current state of this XACML PDP. + */ +public class XacmlState { + + /** + * The application manager. + */ + private final XacmlPdpApplicationManager appManager; + + /** + * Records the current state of this PDP. + */ + private final PdpStatus status; + + + /** + * Constructs the object, initializing the state. + */ + public XacmlState(XacmlPdpApplicationManager appManager) { + this.appManager = appManager; + + this.status = new PdpStatus(); + this.status.setName(NetworkUtil.getHostname()); + this.status.setPdpType("xacml"); + this.status.setState(PdpState.PASSIVE); + this.status.setSupportedPolicyTypes(appManager.getToscaPolicyTypeIdents()); + this.status.setPolicies(Collections.emptyList()); + } + + /** + * Determines if this PDP should handle the given message. + * + * @param message message of interest + * @return {@code true} if this PDP should handle the message, {@code false} otherwise + */ + public boolean shouldHandle(PdpMessage message) { + return message.appliesTo(status.getName(), status.getPdpGroup(), status.getPdpSubgroup()); + } + + /** + * Generates a new heart beat message. + * + * @return a new heart beat message + */ + public PdpStatus genHeartbeat() { + // first, update status fields + status.setHealthy(XacmlPdpActivator.getCurrent().isAlive() ? PdpHealthStatus.HEALTHY + : PdpHealthStatus.NOT_HEALTHY); + + return new PdpStatus(status); + } + + /** + * Updates the internal state based on the given message. + * + * @param message message from which to update the internal state + * @return a response to the message + */ + public PdpStatus updateInternalState(PdpStateChange message) { + status.setState(message.getState()); + + /* + * NOTE: Do NOT update group & subgroup as state-change requests do not set those + * fields to indicate new values; they only set them to do broadcasts to all PDPs + * within a group/subgroup. + */ + + PdpStatus status2 = makeResponse(message); + + // these fields aren't needed in the response, so clear them out to avoid sending + status2.setPolicies(null); + + return status2; + } + + /** + * Updates the internal state based on the given message. Assumes that the policies + * have already been updated within the application manager. + * + * @param message message from which to update the internal state + * @return a response to the message + */ + public PdpStatus updateInternalState(PdpUpdate message) { + status.setPdpGroup(message.getPdpGroup()); + status.setPdpSubgroup(message.getPdpSubgroup()); + status.setPolicies(appManager.getToscaPolicyIdentifiers()); + + return makeResponse(message); + } + + /** + * Makes a response to the given message, based on the current state. + * + * @param message message for which the response should be made + * @return a new response + */ + private PdpStatus makeResponse(PdpMessage message) { + PdpResponseDetails resp = new PdpResponseDetails(); + resp.setResponseStatus(PdpResponseStatus.SUCCESS); + resp.setResponseTo(message.getRequestId()); + + PdpStatus status2 = new PdpStatus(status); + status2.setResponse(resp); + return status2; + } +} 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 8ffccbef..29044744 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 @@ -23,6 +23,8 @@ package org.onap.policy.pdpx.main.comm; import java.util.Timer; import java.util.TimerTask; 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; @@ -30,45 +32,75 @@ public class XacmlPdpHearbeatPublisher extends TimerTask { private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHearbeatPublisher.class); - private Timer timer; - private XacmlPdpMessage heartbeatMessage; - private static TopicSinkClient topicSinkClient; - private static volatile boolean alive = false; + private final TopicSinkClient topicSinkClient; + + /** + * Tracks the state of this PDP. + */ + private final XacmlState currentState; + + /** + * Current timer interval, in milliseconds. + */ + private long intervalMs = 60000; + + private Timer timer = null; + /** * Constructor for instantiating XacmlPdpPublisher. * - * @param message of the PDP - * @param topicSinkClient used to send heartbeat message + * @param topicSinkClient used to send heart beat message + * @param state tracks the state of this PDP */ - public XacmlPdpHearbeatPublisher(TopicSinkClient topicSinkClient, XacmlPdpMessage message ) { + public XacmlPdpHearbeatPublisher(TopicSinkClient topicSinkClient, XacmlState state) { this.topicSinkClient = topicSinkClient; - this.heartbeatMessage = message; - timer = new Timer(false); - timer.scheduleAtFixedRate(this, 0, 60000); // time interval temp hard coded now but will be parameterized - setAlive(true); + this.currentState = state; } @Override public void run() { - topicSinkClient.send(heartbeatMessage.formatPdpStatusMessage()); - LOGGER.info("Sending Xacml PDP heartbeat to the PAP"); + PdpStatus message = currentState.genHeartbeat(); + LOGGER.info("Sending Xacml PDP heartbeat to the PAP - {}", message); + + topicSinkClient.send(message); } /** - * Method to terminate the heartbeat. + * Method to terminate the heart beat. */ - public void terminate() { - timer.cancel(); - timer.purge(); - setAlive(false); + public synchronized void terminate() { + if (timer != null) { + timer.cancel(); + timer.purge(); + timer = null; + } } - public static boolean isAlive() { - return alive; + /** + * Restarts the timer if the interval has changed. If the timer is not currently + * running, then it updates the interval, but does not start the timer. + * + * @param intervalMs desired interval, or {@code null} to leave it unchanged + */ + public synchronized void restart(Long intervalMs) { + if (intervalMs != null && intervalMs > 0 && intervalMs != this.intervalMs) { + this.intervalMs = intervalMs; + + if (timer != null) { + terminate(); + start(); + } + } } - public void setAlive(boolean alive) { - this.alive = alive; + /** + * Starts the timer. + */ + public synchronized void start() { + if (timer == null) { + timer = new Timer(true); + timer.scheduleAtFixedRate(this, 0, this.intervalMs); + } } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java deleted file mode 100644 index 066e3f23..00000000 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * 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 lombok.Getter; -import org.onap.policy.common.utils.network.NetworkUtil; -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.PdpState; -import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; -import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Getter -public class XacmlPdpMessage { - - // The logger for this class - private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpMessage.class); - private String pdpGroup; - private String pdpSubGroup; - private PdpState pdpState; - private String pdpName = NetworkUtil.getHostname(); - - /** - * Method used to format the initial registration status message. - * - * @param state of the PDP - * @return status message of the PDP - */ - public PdpStatus formatInitialStatusMessage(PdpState state) { - PdpStatus status = new PdpStatus(); - status.setName(pdpName); - - if (XacmlPdpActivator.getCurrent().isAlive()) { - status.setHealthy(PdpHealthStatus.HEALTHY); - } else { - status.setHealthy(PdpHealthStatus.NOT_HEALTHY); - } - - status.setPdpType("xacml"); - status.setState(state); - status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); - - LOGGER.debug("formatStatusMessage state {} status{}", state, status); - - return status; - - } - - /** - * Method used to format the PdpStatus message for heartbeat and PDP Updates. - * - * @return status message of the PDP - */ - public PdpStatus formatPdpStatusMessage() { - PdpStatus status = new PdpStatus(); - status.setName(pdpName); - - if (XacmlPdpActivator.getCurrent() != null && XacmlPdpActivator.getCurrent().isAlive()) { - status.setHealthy(PdpHealthStatus.HEALTHY); - } else { - status.setHealthy(PdpHealthStatus.NOT_HEALTHY); - } - - status.setPdpType("xacml"); - status.setState(pdpState); - status.setPdpGroup(pdpGroup); - status.setPdpSubgroup(pdpSubGroup); - status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); - status.setPolicies(XacmlPdpApplicationManager.getToscaPolicyIdentifiers()); - - return status; - } - - /** - * Method used to update PDP status attributes from PdpStateChange. - */ - public void updateInternalStatus(PdpStateChange message) { - pdpGroup = message.getPdpGroup(); - pdpSubGroup = message.getPdpSubgroup(); - pdpState = message.getState(); - } - - /** - * Method used to update PDP status attributes from PdpUpdate. - */ - public void updateInternalStatus(PdpUpdate message) { - pdpGroup = message.getPdpGroup(); - pdpSubGroup = message.getPdpSubgroup(); - } -} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java index 54d9cf65..a26f4b11 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java @@ -20,12 +20,14 @@ package org.onap.policy.pdpx.main.comm; +import java.util.Collections; import java.util.HashSet; import java.util.Set; 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.pdpx.main.XacmlState; import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,49 +36,54 @@ public class XacmlPdpUpdatePublisher { private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpUpdatePublisher.class); - private XacmlPdpUpdatePublisher() { - throw new IllegalStateException("Please do not create private instance of XacmlPdpUpdatePublisher"); + private final TopicSinkClient client; + private final XacmlState state; + private final XacmlPdpApplicationManager appManager; + + /** + * Constructs the object. + * @param client messages are published to this client + * @param state tracks the state of this PDP + * @param appManager application manager + */ + public XacmlPdpUpdatePublisher(TopicSinkClient client, XacmlState state, XacmlPdpApplicationManager appManager) { + this.client = client; + this.state = state; + this.appManager = appManager; } /** * Handle the PDP Update message. * * @param message Incoming message - * @param client TopicSinkClient */ - public static void handlePdpUpdate(PdpUpdate message, TopicSinkClient client, - XacmlPdpMessage updatePdpMessage) { + public void handlePdpUpdate(PdpUpdate message) { - if (!message.getPolicies().isEmpty() || message.getPolicies() != null) { + Set<ToscaPolicy> incomingPolicies = + new HashSet<>(message.getPolicies() == null ? Collections.emptyList() : message.getPolicies()); + Set<ToscaPolicy> deployedPolicies = + new HashSet<>(appManager.getToscaPolicies().keySet()); - Set<ToscaPolicy> incomingPolicies = - new HashSet<>(message.getPolicies()); - Set<ToscaPolicy> deployedPolicies = - new HashSet<>(XacmlPdpApplicationManager.getToscaPolicies().keySet()); - - // Undeploy a policy - // if incoming policies do not contain the deployed policy then remove it from PDP - for (ToscaPolicy policy : deployedPolicies) { - if (!incomingPolicies.contains(policy)) { - XacmlPdpApplicationManager.removeUndeployedPolicy(policy); - } + // Undeploy a policy + // if incoming policies do not contain the deployed policy then remove it from PDP + for (ToscaPolicy policy : deployedPolicies) { + if (!incomingPolicies.contains(policy)) { + appManager.removeUndeployedPolicy(policy); } + } - // Deploy a policy - // if deployed policies do not contain the incoming policy load it - for (ToscaPolicy policy : incomingPolicies) { - if (!deployedPolicies.contains(policy)) { - XacmlPdpApplicationManager.loadDeployedPolicy(policy); - } + // Deploy a policy + // if deployed policies do not contain the incoming policy load it + for (ToscaPolicy policy : incomingPolicies) { + if (!deployedPolicies.contains(policy)) { + appManager.loadDeployedPolicy(policy); } } - updatePdpMessage.updateInternalStatus(message); - PdpStatus statusMessage = updatePdpMessage.formatPdpStatusMessage(); - sendPdpUpdate(statusMessage, client); + sendPdpUpdate(state.updateInternalState(message)); } - private static void sendPdpUpdate(PdpStatus status, TopicSinkClient client) { + private void sendPdpUpdate(PdpStatus status) { // Send PdpStatus Change to PAP if (!client.send(status)) { LOGGER.error("failed to send to topic sink {}", client.getTopic()); diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java index 3102edb1..98f6d0e1 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java @@ -27,9 +27,7 @@ import org.onap.policy.common.endpoints.listeners.ScoListener; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; -import org.onap.policy.models.pdp.enums.PdpState; -import org.onap.policy.pdpx.main.comm.XacmlPdpHearbeatPublisher; -import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; +import org.onap.policy.pdpx.main.XacmlState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,47 +35,40 @@ public class XacmlPdpStateChangeListener extends ScoListener<PdpStateChange> { private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpStateChangeListener.class); - private TopicSinkClient client; + private final TopicSinkClient client; - private XacmlPdpHearbeatPublisher heartbeat; - private XacmlPdpMessage pdpInternalStatus; + private final XacmlState state; /** * Constructs the object. * * @param client used to send back response after receiving state change message + * @param state tracks the state of this PDP */ - public XacmlPdpStateChangeListener(TopicSinkClient client, XacmlPdpMessage pdpStatusMessage) { + public XacmlPdpStateChangeListener(TopicSinkClient client, XacmlState state) { super(PdpStateChange.class); - PdpStateChange message = new PdpStateChange(); - message.setState(PdpState.PASSIVE); - this.pdpInternalStatus = pdpStatusMessage; this.client = client; - this.heartbeat = new XacmlPdpHearbeatPublisher(client, pdpStatusMessage); + this.state = state; } @Override public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, PdpStateChange message) { try { + if (!state.shouldHandle(message)) { + LOGGER.debug("PDP State Change message discarded - {}", message); + return; + } - if (message.appliesTo(pdpInternalStatus.getPdpName(), pdpInternalStatus.getPdpGroup(), - pdpInternalStatus.getPdpSubGroup())) { - - pdpInternalStatus.updateInternalStatus(message); - PdpStatus newStatus = pdpInternalStatus.formatPdpStatusMessage(); - - // Send State Change Status to PAP - if (!client.send(newStatus)) { - LOGGER.error("failed to send to topic sink {}", client.getTopic()); - throw new TopicSinkClientException("failed to send to topic sink " + client.getTopic()); - } + LOGGER.info("PDP State Change message has been received from the PAP - {}", message); + PdpStatus newStatus = state.updateInternalState(message); - // Starte new heartbeat if publisher is NOT alive - if (!XacmlPdpHearbeatPublisher.isAlive()) { - heartbeat = new XacmlPdpHearbeatPublisher(client, pdpInternalStatus); - } + // Send State Change Status to PAP + if (!client.send(newStatus)) { + LOGGER.error("failed to send to topic sink {}", client.getTopic()); + throw new TopicSinkClientException("failed to send to topic sink " + client.getTopic()); } + } catch (final Exception e) { LOGGER.error("failed to handle the PDP State Change message.", e); } 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 01d19160..2a8ef99f 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 @@ -25,8 +25,10 @@ import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; import org.onap.policy.common.endpoints.listeners.ScoListener; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.models.pdp.concepts.PdpUpdate; -import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; +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.rest.XacmlPdpApplicationManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,33 +36,41 @@ public class XacmlPdpUpdateListener extends ScoListener<PdpUpdate> { private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpStateChangeListener.class); - private TopicSinkClient client; - private XacmlPdpMessage pdpInternalStatus; + private final XacmlState state; + + private final XacmlPdpHearbeatPublisher heartbeat; + + private final XacmlPdpUpdatePublisher publisher; /** * Constructs the object. * * @param client used to send back response after receiving state change message + * @param state tracks the state of this PDP + * @param heartbeat heart beat publisher + * @param appManager application manager */ - public XacmlPdpUpdateListener(TopicSinkClient client, XacmlPdpMessage pdpStatusMessage) { + public XacmlPdpUpdateListener(TopicSinkClient client, XacmlState state, XacmlPdpHearbeatPublisher heartbeat, + XacmlPdpApplicationManager appManager) { super(PdpUpdate.class); - this.client = client; - this.pdpInternalStatus = pdpStatusMessage; + this.state = state; + this.heartbeat = heartbeat; + this.publisher = new XacmlPdpUpdatePublisher(client, state, appManager); } @Override public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, PdpUpdate message) { try { - - LOGGER.info("PDP update message has been received from the PAP - {}", message.toString()); - - if (message.appliesTo(pdpInternalStatus.getPdpName(), pdpInternalStatus.getPdpGroup(), - pdpInternalStatus.getPdpSubGroup())) { - - XacmlPdpUpdatePublisher.handlePdpUpdate(message, client, pdpInternalStatus); + if (!state.shouldHandle(message)) { + LOGGER.debug("PDP update message discarded - {}:{}", message.getName(), message.getRequestId()); + return; } + LOGGER.info("PDP update message has been received from the PAP - {}", message); + publisher.handlePdpUpdate(message); + heartbeat.restart(message.getPdpHeartbeatIntervalMs()); + } catch (final Exception e) { LOGGER.error("failed to handle the PDP Update message.", e); } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java index db2ce553..6a5555be 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; @@ -42,37 +44,24 @@ import org.slf4j.LoggerFactory; public class XacmlPdpApplicationManager { private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpApplicationManager.class); - private static boolean needsInit = true; - private static ServiceLoader<XacmlApplicationServiceProvider> applicationLoader; - private static Map<String, XacmlApplicationServiceProvider> providerActionMap = new HashMap<>(); - private static List<ToscaPolicyTypeIdentifier> toscaPolicyTypeIdents = new ArrayList<>(); - private static Map<ToscaPolicy, XacmlApplicationServiceProvider> mapLoadedPolicies = new HashMap<>(); + @Getter + @Setter + private static XacmlPdpApplicationManager current; + private ServiceLoader<XacmlApplicationServiceProvider> applicationLoader; + private Map<String, XacmlApplicationServiceProvider> providerActionMap = new HashMap<>(); + private List<ToscaPolicyTypeIdentifier> toscaPolicyTypeIdents = new ArrayList<>(); + private Map<ToscaPolicy, XacmlApplicationServiceProvider> mapLoadedPolicies = new HashMap<>(); - private XacmlPdpApplicationManager() { - super(); - } /** * One time to initialize the applications upon startup. */ - public static void initializeApplications(Path applicationPath) { + public XacmlPdpApplicationManager(Path applicationPath) { if (LOGGER.isInfoEnabled()) { LOGGER.info("Initialization applications {}", applicationPath.toAbsolutePath()); } // - // If we have already done this - // - if (! needsInit) { - LOGGER.warn("Already initialized the applications {}", providerActionMap); - // - // I had to remove this because the JUnits kept failing - although I probably can - // add it back. The main() is hanging around during JUnits and initialization will - // fail. - // - // return - } - // // Load service // applicationLoader = ServiceLoader.load(XacmlApplicationServiceProvider.class); @@ -120,12 +109,11 @@ public class XacmlPdpApplicationManager { // // we have initialized // - needsInit = false; LOGGER.info("Finished applications initialization {}", providerActionMap); } - public static XacmlApplicationServiceProvider findApplication(DecisionRequest request) { + public XacmlApplicationServiceProvider findApplication(DecisionRequest request) { return providerActionMap.get(request.getAction()); } @@ -134,7 +122,7 @@ public class XacmlPdpApplicationManager { * * @return the map containing ToscaPolicies */ - public static Map<ToscaPolicy, XacmlApplicationServiceProvider> getToscaPolicies() { + public Map<ToscaPolicy, XacmlApplicationServiceProvider> getToscaPolicies() { return mapLoadedPolicies; } @@ -143,14 +131,14 @@ public class XacmlPdpApplicationManager { * * @return list of ToscaPolicyIdentifier */ - public static List<ToscaPolicyIdentifier> getToscaPolicyIdentifiers() { + public List<ToscaPolicyIdentifier> getToscaPolicyIdentifiers() { // // converting map to return List of ToscaPolicyIdentiers // return mapLoadedPolicies.keySet().stream().map(ToscaPolicy::getIdentifier).collect(Collectors.toList()); } - public static List<ToscaPolicyTypeIdentifier> getToscaPolicyTypeIdents() { + public List<ToscaPolicyTypeIdentifier> getToscaPolicyTypeIdents() { return toscaPolicyTypeIdents; } @@ -159,7 +147,7 @@ public class XacmlPdpApplicationManager { * * @param policy Incoming policy */ - public static void removeUndeployedPolicy(ToscaPolicy policy) { + public void removeUndeployedPolicy(ToscaPolicy policy) { for (XacmlApplicationServiceProvider application : applicationLoader) { try { @@ -184,7 +172,7 @@ public class XacmlPdpApplicationManager { * * @param policy Incoming policy */ - public static void loadDeployedPolicy(ToscaPolicy policy) { + public void loadDeployedPolicy(ToscaPolicy policy) { for (XacmlApplicationServiceProvider application : applicationLoader) { try { @@ -216,7 +204,7 @@ public class XacmlPdpApplicationManager { * * @return Total count added from all applications */ - public static long getPolicyTypeCount() { + public long getPolicyTypeCount() { long types = 0; for (XacmlApplicationServiceProvider application : applicationLoader) { types += application.supportedPolicyTypes().size(); @@ -224,7 +212,7 @@ public class XacmlPdpApplicationManager { return types; } - private static void initializeApplicationPath(Path basePath, XacmlApplicationServiceProvider application) + private void initializeApplicationPath(Path basePath, XacmlApplicationServiceProvider application) throws XacmlApplicationException { // // Making an assumption that all application names are unique, and @@ -255,5 +243,4 @@ public class XacmlPdpApplicationManager { // application.initialize(path); } - } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java index 37bab8ec..265dd686 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java @@ -175,7 +175,7 @@ public class XacmlPdpRestController { return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) .entity(new DecisionProvider().fetchDecision(body)).build(); } catch (DecisionException e) { - XacmlPdpStatisticsManager.updateErrorCount(); + XacmlPdpStatisticsManager.getCurrent().updateErrorCount(); return addLoggingHeaders( addVersionControlHeaders(Response.status((e.getErrorResponse().getResponseCode()))), requestId) .entity(e.getErrorResponse()).build(); 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 index eee9717a..a64953bd 100644 --- 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 @@ -20,11 +20,9 @@ package org.onap.policy.pdpx.main.rest; -import java.nio.file.Paths; 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.gson.GsonMessageBodyHandler; @@ -44,17 +42,15 @@ public class XacmlPdpRestServer implements Startable { private List<HttpServletServer> servers = new ArrayList<>(); - private RestServerParameters restServerParameters; - private String applicationPath; + private final RestServerParameters restServerParameters; /** * Constructor for instantiating XacmlPdpRestServer. * * @param restServerParameters the rest server parameters */ - public XacmlPdpRestServer(final RestServerParameters restServerParameters, final String applicationPath) { + public XacmlPdpRestServer(final RestServerParameters restServerParameters) { this.restServerParameters = restServerParameters; - this.applicationPath = applicationPath; } /** @@ -64,15 +60,6 @@ public class XacmlPdpRestServer implements Startable { public boolean start() { try { LOGGER.info("Starting XacmlPdpRestServer..."); - // - // Initialize the applications - SEND PROPERTIES - // - XacmlPdpApplicationManager.initializeApplications(Paths.get(applicationPath)); - - // - // Update statistics manager on the policy types - // - XacmlPdpStatisticsManager.setTotalPolicyTypesCount(XacmlPdpApplicationManager.getPolicyTypeCount()); // // Get the server properties diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java index d209c09c..6d043052 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java @@ -20,23 +20,25 @@ package org.onap.policy.pdpx.main.rest; +import lombok.Getter; +import lombok.Setter; + /** * Class to hold statistical data for xacmlPdp component. * */ public class XacmlPdpStatisticsManager { - - private static long totalPolicyTypesCount; - private static long totalPoliciesCount; - private static long errorsCount; - private static long permitDecisionsCount; - private static long denyDecisionsCount; - private static long indeterminantDecisionsCount; - private static long notApplicableDecisionsCount; - - private XacmlPdpStatisticsManager() { - throw new IllegalStateException("Instantiation of the class is not allowed"); - } + @Getter + @Setter + private static XacmlPdpStatisticsManager current = null; + + private long totalPolicyTypesCount; + private long totalPoliciesCount; + private long errorsCount; + private long permitDecisionsCount; + private long denyDecisionsCount; + private long indeterminantDecisionsCount; + private long notApplicableDecisionsCount; /** * Method to set the xacml pdp total policy types count. This @@ -45,7 +47,7 @@ public class XacmlPdpStatisticsManager { * * @return the total */ - public static long setTotalPolicyTypesCount(long newCount) { + public long setTotalPolicyTypesCount(long newCount) { totalPolicyTypesCount = newCount; return totalPolicyTypesCount; } @@ -55,7 +57,7 @@ public class XacmlPdpStatisticsManager { * * @return the total */ - public static long updateTotalPoliciesCount() { + public long updateTotalPoliciesCount() { return ++totalPoliciesCount; } @@ -64,7 +66,7 @@ public class XacmlPdpStatisticsManager { * * @return the errorDecisionsCount */ - public static long updateErrorCount() { + public long updateErrorCount() { return ++errorsCount; } @@ -73,7 +75,7 @@ public class XacmlPdpStatisticsManager { * * @return the permitDecisionsCount */ - public static long updatePermitDecisionsCount() { + public long updatePermitDecisionsCount() { return ++permitDecisionsCount; } @@ -82,7 +84,7 @@ public class XacmlPdpStatisticsManager { * * @return the denyDecisionsCount */ - public static long updateDenyDecisionsCount() { + public long updateDenyDecisionsCount() { return ++denyDecisionsCount; } @@ -91,7 +93,7 @@ public class XacmlPdpStatisticsManager { * * @return the indeterminantDecisionsCount */ - public static long updateIndeterminantDecisionsCount() { + public long updateIndeterminantDecisionsCount() { return ++indeterminantDecisionsCount; } @@ -100,7 +102,7 @@ public class XacmlPdpStatisticsManager { * * @return the notApplicableDecisionsCount */ - public static long updateNotApplicableDecisionsCount() { + public long updateNotApplicableDecisionsCount() { return ++notApplicableDecisionsCount; } @@ -109,7 +111,7 @@ public class XacmlPdpStatisticsManager { * @return the totalPolicyTypesCount */ - public static long getTotalPolicyTypesCount() { + public long getTotalPolicyTypesCount() { return totalPolicyTypesCount; } @@ -118,7 +120,7 @@ public class XacmlPdpStatisticsManager { * @return the totalPoliciesCount */ - public static long getTotalPoliciesCount() { + public long getTotalPoliciesCount() { return totalPoliciesCount; } @@ -127,7 +129,7 @@ public class XacmlPdpStatisticsManager { * @return the permitDecisionsCount */ - public static long getErrorCount() { + public long getErrorCount() { return errorsCount; } @@ -136,7 +138,7 @@ public class XacmlPdpStatisticsManager { * @return the permitDecisionsCount */ - public static long getPermitDecisionsCount() { + public long getPermitDecisionsCount() { return permitDecisionsCount; } @@ -145,7 +147,7 @@ public class XacmlPdpStatisticsManager { * @return the denyDecisionsCount */ - public static long getDenyDecisionsCount() { + public long getDenyDecisionsCount() { return denyDecisionsCount; } @@ -154,7 +156,7 @@ public class XacmlPdpStatisticsManager { * @return the indeterminantDecisionsCount */ - public static long getIndeterminantDecisionsCount() { + public long getIndeterminantDecisionsCount() { return indeterminantDecisionsCount; } @@ -163,14 +165,14 @@ public class XacmlPdpStatisticsManager { * @return the notApplicableDecisionsCount */ - public static long getNotApplicableDecisionsCount() { + public long getNotApplicableDecisionsCount() { return notApplicableDecisionsCount; } /** * Reset all the statistics counts to 0. */ - public static void resetAllStatistics() { + public void resetAllStatistics() { totalPolicyTypesCount = 0L; totalPoliciesCount = 0L; errorsCount = 0L; diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java index 9cfb8a47..67e696aa 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java @@ -70,7 +70,7 @@ public class DecisionProvider { } private XacmlApplicationServiceProvider findApplication(DecisionRequest request) { - XacmlApplicationServiceProvider application = XacmlPdpApplicationManager.findApplication(request); + XacmlApplicationServiceProvider application = XacmlPdpApplicationManager.getCurrent().findApplication(request); if (application != null) { return application; } @@ -83,22 +83,22 @@ public class DecisionProvider { for (Result result : xacmlResponse.getResults()) { switch (result.getDecision()) { case PERMIT: - XacmlPdpStatisticsManager.updatePermitDecisionsCount(); + XacmlPdpStatisticsManager.getCurrent().updatePermitDecisionsCount(); break; case DENY: - XacmlPdpStatisticsManager.updateDenyDecisionsCount(); + XacmlPdpStatisticsManager.getCurrent().updateDenyDecisionsCount(); break; case INDETERMINATE: case INDETERMINATE_DENY: case INDETERMINATE_DENYPERMIT: case INDETERMINATE_PERMIT: - XacmlPdpStatisticsManager.updateIndeterminantDecisionsCount(); + XacmlPdpStatisticsManager.getCurrent().updateIndeterminantDecisionsCount(); break; case NOTAPPLICABLE: - XacmlPdpStatisticsManager.updateNotApplicableDecisionsCount(); + XacmlPdpStatisticsManager.getCurrent().updateNotApplicableDecisionsCount(); break; default: diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java index 95d67a67..cf2fd608 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java @@ -38,13 +38,15 @@ public class StatisticsProvider { public StatisticsReport fetchCurrentStatistics() { final StatisticsReport report = new StatisticsReport(); report.setCode(XacmlPdpActivator.getCurrent().isAlive() ? 200 : 500); - report.setTotalPolicyTypesCount(XacmlPdpStatisticsManager.getTotalPolicyTypesCount()); - report.setTotalPoliciesCount(XacmlPdpStatisticsManager.getTotalPoliciesCount()); - report.setTotalErrorCount(XacmlPdpStatisticsManager.getErrorCount()); - report.setPermitDecisionsCount(XacmlPdpStatisticsManager.getPermitDecisionsCount()); - report.setDenyDecisionsCount(XacmlPdpStatisticsManager.getDenyDecisionsCount()); - report.setIndeterminantDecisionsCount(XacmlPdpStatisticsManager.getIndeterminantDecisionsCount()); - report.setNotApplicableDecisionsCount(XacmlPdpStatisticsManager.getNotApplicableDecisionsCount()); + + XacmlPdpStatisticsManager stats = XacmlPdpStatisticsManager.getCurrent(); + report.setTotalPolicyTypesCount(stats.getTotalPolicyTypesCount()); + report.setTotalPoliciesCount(stats.getTotalPoliciesCount()); + report.setTotalErrorCount(stats.getErrorCount()); + report.setPermitDecisionsCount(stats.getPermitDecisionsCount()); + report.setDenyDecisionsCount(stats.getDenyDecisionsCount()); + report.setIndeterminantDecisionsCount(stats.getIndeterminantDecisionsCount()); + report.setNotApplicableDecisionsCount(stats.getNotApplicableDecisionsCount()); return report; } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java index 62cdc34a..020bfcbf 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java @@ -23,7 +23,7 @@ package org.onap.policy.pdpx.main.startstop; import java.io.FileInputStream; import java.util.Arrays; import java.util.Properties; - +import lombok.Getter; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterHandler; @@ -41,45 +41,34 @@ public class Main { // The policy xacml pdp Activator that activates the policy xacml pdp service private XacmlPdpActivator activator; - // The parameters read in from JSON - private XacmlPdpParameterGroup parameterGroup; - - // The argument message for some args that return a message + @Getter private String argumentMessage = null; /** * Instantiates the policy xacml pdp service. * * @param args the command line arguments + * @throws PolicyXacmlPdpException if an error occurs */ - public Main(final String[] args) { + public Main(final String[] args) throws PolicyXacmlPdpException { final String argumentString = Arrays.toString(args); LOGGER.info("Starting policy xacml pdp service with arguments - {}", argumentString); // Check the arguments final XacmlPdpCommandLineArguments arguments = new XacmlPdpCommandLineArguments(); - try { - // The arguments return a string if there is a message to print and we should exit - argumentMessage = arguments.parse(args); - if (argumentMessage != null) { - LOGGER.info(argumentMessage); - return; - } - // Validate that the arguments are sane - arguments.validate(); - } catch (final PolicyXacmlPdpException e) { - LOGGER.error("start of policy xacml pdp service failed", e); + // The arguments return a string if there is a message to print and we should exit + argumentMessage = arguments.parse(args); + if (argumentMessage != null) { + LOGGER.info(argumentMessage); return; } + // Validate that the arguments are sane + arguments.validate(); + // Read the parameters - try { - parameterGroup = new XacmlPdpParameterHandler().getParameters(arguments); - } catch (final Exception e) { - LOGGER.error("start of policy xacml pdp service failed", e); - return; - } + XacmlPdpParameterGroup parameterGroup = new XacmlPdpParameterHandler().getParameters(arguments); // Read the properties Properties props = new Properties(); @@ -89,73 +78,31 @@ public class Main { props.load(stream); } } catch (final Exception e) { - LOGGER.error("start of xacml pdp service failed", e); - return; + throw new PolicyXacmlPdpException("cannot load property file", e); } // Now, create the activator for the policy xacml pdp service activator = new XacmlPdpActivator(parameterGroup, props); + XacmlPdpActivator.setCurrent(activator); // Start the activator - try { - activator.start(); - } catch (final RuntimeException e) { - LOGGER.error("start of policy xacml pdp service failed, used parameters are " + Arrays.toString(args), e); - return; - } + activator.start(); // Add a shutdown hook to shut everything down in an orderly manner - Runtime.getRuntime().addShutdownHook(new PolicyXacmlPdpShutdownHookClass()); + Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown)); LOGGER.info("Started policy xacml pdp service"); } /** - * Get the parameters specified in JSON. - * - * @return the parameters - */ - public XacmlPdpParameterGroup getParameters() { - return parameterGroup; - } - - /** - * Get the argumentMessage string. - * - * @return the argumentMessage - */ - public String getArgumentMessage() { - return argumentMessage; - } - - /** * Shut down Execution. * * @throws PolicyXacmlPdpException on shutdown errors */ - public void shutdown() { - // clear the parameterGroup variable - parameterGroup = null; - + public synchronized void shutdown() { // clear the xacml pdp activator - if (activator != null) { - activator.stop(); - } - } - - /** - * The Class PolicyXacmlPdpShutdownHookClass terminates the policy xacml pdp service when its run - * method is called. - */ - private class PolicyXacmlPdpShutdownHookClass extends Thread { - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - // Shutdown the policy xacml pdp service and wait for everything to stop + if (activator != null && activator.isAlive()) { activator.stop(); + activator = null; } } @@ -165,6 +112,10 @@ public class Main { * @param args the arguments */ public static void main(final String[] args) { - new Main(args); + try { + new Main(args); + } catch (RuntimeException | PolicyXacmlPdpException e) { + LOGGER.error("start of policy xacml pdp service failed", e); + } } } 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 4db11d0f..2a881d45 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 @@ -20,9 +20,11 @@ package org.onap.policy.pdpx.main.startstop; +import java.nio.file.Paths; import java.util.Arrays; import java.util.Properties; - +import lombok.Getter; +import lombok.Setter; import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; import org.onap.policy.common.endpoints.event.comm.TopicSource; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; @@ -31,16 +33,16 @@ import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.common.utils.services.ServiceManagerContainer; import org.onap.policy.models.pdp.concepts.PdpStatus; -import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpMessageType; -import org.onap.policy.models.pdp.enums.PdpState; import org.onap.policy.pdpx.main.PolicyXacmlPdpRuntimeException; -import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; -import org.onap.policy.pdpx.main.comm.XacmlPdpPapRegistration; +import org.onap.policy.pdpx.main.XacmlState; +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.XacmlPdpApplicationManager; import org.onap.policy.pdpx.main.rest.XacmlPdpRestServer; +import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,6 +58,10 @@ public class XacmlPdpActivator extends ServiceManagerContainer { private static final String[] MSG_TYPE_NAMES = {"messageName"}; private static final String TOPIC = "POLICY-PDP-PAP"; + @Getter + @Setter + private static XacmlPdpActivator current = null; + // The parameters of this policy xacml pdp activator private final XacmlPdpParameterGroup xacmlPdpParameterGroup; @@ -71,27 +77,6 @@ public class XacmlPdpActivator extends ServiceManagerContainer { private final MessageTypeDispatcher msgDispatcher; /** - * Listens for {@link PdpStateChange} messages from the PAP. - */ - private final XacmlPdpStateChangeListener pdpStateChangeListener; - - /** - * Listens for {@link PdpUpdate} messages from the PAP. - */ - private final XacmlPdpUpdateListener pdpUpdateListener; - - /** - * The current activator. - */ - private static XacmlPdpActivator current = null; - - private volatile boolean alive = false; - - private XacmlPdpPapRegistration register; - - private XacmlPdpMessage message; - - /** * Instantiate the activator for policy xacml pdp as a complete service. * * @param xacmlPdpParameterGroup the parameters for the xacml pdp service @@ -103,14 +88,34 @@ public class XacmlPdpActivator extends ServiceManagerContainer { TopicEndpoint.manager.addTopicSinks(topicProperties); TopicEndpoint.manager.addTopicSources(topicProperties); + XacmlPdpHearbeatPublisher heartbeat; + try { - final TopicSinkClient sinkClient = new TopicSinkClient(TOPIC); - this.message = new XacmlPdpMessage(); + XacmlPdpApplicationManager appmgr = + new XacmlPdpApplicationManager(Paths.get(xacmlPdpParameterGroup.getApplicationPath())); + XacmlPdpApplicationManager.setCurrent(appmgr); + + XacmlPdpStatisticsManager stats = new XacmlPdpStatisticsManager(); + XacmlPdpStatisticsManager.setCurrent(stats); + stats.setTotalPolicyTypesCount(appmgr.getPolicyTypeCount()); + + XacmlState state = new XacmlState(appmgr); + this.xacmlPdpParameterGroup = xacmlPdpParameterGroup; this.msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); - this.pdpStateChangeListener = new XacmlPdpStateChangeListener(sinkClient, message); - this.pdpUpdateListener = new XacmlPdpUpdateListener(sinkClient, message); - this.register = new XacmlPdpPapRegistration(sinkClient); + + TopicSinkClient sinkClient = new TopicSinkClient(TOPIC); + heartbeat = new XacmlPdpHearbeatPublisher(sinkClient, state); + + /* + * since the dispatcher isn't registered with the topic yet, we can go ahead + * and register the listeners with it. + */ + msgDispatcher.register(PdpMessageType.PDP_STATE_CHANGE.name(), + new XacmlPdpStateChangeListener(sinkClient, state)); + msgDispatcher.register(PdpMessageType.PDP_UPDATE.name(), + new XacmlPdpUpdateListener(sinkClient, state, heartbeat, appmgr)); + } catch (RuntimeException | TopicSinkClientException e) { throw new PolicyXacmlPdpRuntimeException(e.getMessage(), e); } @@ -118,50 +123,31 @@ public class XacmlPdpActivator extends ServiceManagerContainer { xacmlPdpParameterGroup.getRestServerParameters().setName(xacmlPdpParameterGroup.getName()); // @formatter:off - addAction("XACML PDP parameters", () -> ParameterService.register(xacmlPdpParameterGroup), + addAction("XACML PDP parameters", + () -> ParameterService.register(xacmlPdpParameterGroup), () -> ParameterService.deregister(xacmlPdpParameterGroup.getName())); - addAction("PdpStateChange Dispatcher", - () -> msgDispatcher.register(PdpMessageType.PDP_STATE_CHANGE.name(), this.pdpStateChangeListener), - () -> msgDispatcher.unregister(PdpMessageType.PDP_STATE_CHANGE.name())); - - addAction("PdpUpdate Dispatcher", - () -> msgDispatcher.register(PdpMessageType.PDP_UPDATE.name(), this.pdpUpdateListener), - () -> msgDispatcher.unregister(PdpMessageType.PDP_UPDATE.name())); - addAction("Message Dispatcher", - () -> registerMsgDispatcher(), - () -> unregisterMsgDispatcher()); + this::registerMsgDispatcher, + this::unregisterMsgDispatcher); addAction("topics", - () -> TopicEndpoint.manager.start(), - () -> TopicEndpoint.manager.shutdown()); + TopicEndpoint.manager::start, + TopicEndpoint.manager::shutdown); + + // initial heart beats act as registration messages + addAction("Heartbeat Publisher", + heartbeat::start, + heartbeat::terminate); addAction("Create REST server", - () -> { - restServer = new XacmlPdpRestServer(xacmlPdpParameterGroup.getRestServerParameters(), - xacmlPdpParameterGroup.getApplicationPath()); - }, - () -> { - restServer = null; - }); + () -> restServer = new XacmlPdpRestServer(xacmlPdpParameterGroup.getRestServerParameters()), + () -> restServer = null); addAction("REST server", () -> restServer.start(), () -> restServer.stop()); - - addAction("set alive", () -> setAlive(true), () -> setAlive(false)); - - addAction("Initial Registration with PAP", - () -> { - register.pdpRegistration(message.formatInitialStatusMessage(PdpState.PASSIVE)); - }, - () -> { - register.pdpRegistration(message.formatInitialStatusMessage(PdpState.TERMINATED)); - }); // @formatter:on - - current = this; } /** @@ -208,31 +194,4 @@ public class XacmlPdpActivator extends ServiceManagerContainer { source.unregister(msgDispatcher); } } - - /** - * Returns the alive status of xacml pdp service. - * - * @return the alive - */ - @Override - public boolean isAlive() { - return alive; - } - - /** - * Change the alive status of xacml pdp service. - * - * @param status the status - */ - private void setAlive(final boolean status) { - alive = status; - } - - public static XacmlPdpActivator getCurrent() { - return current; - } - - public static void setCurrent(XacmlPdpActivator current) { - XacmlPdpActivator.current = current; - } } diff --git a/main/src/test/java/org/onap/policy/pdpx/main/CommonRest.java b/main/src/test/java/org/onap/policy/pdpx/main/CommonRest.java new file mode 100644 index 00000000..0c84419f --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/CommonRest.java @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * 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 java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.SecureRandom; +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager; +import org.onap.policy.pdpx.main.startstop.Main; +import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator; +import org.powermock.reflect.Whitebox; + +/** + * Common base class for REST service tests. + */ +public class CommonRest { + private static final String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore"; + + /** + * Full path to the config file. + */ + public static final String CONFIG_FILE; + + /** + * Path corresponding to {@link #CONFIG_FILE}. + */ + private static final Path CONFIG_PATH; + + /** + * Contents read from the "standard" config file, which still contains ${xxx} + * place-holders. + */ + private static final String STD_CONFIG; + + /** + * Port that was last allocated for the server. + */ + protected static int port; + + /** + * "Main" that was last started. + */ + private static Main main; + + /** + * Records the "alive" state of the activator while it's temporarily updated by + * various junit tests. The {@link #tearDown()} method restores the "alive" state back + * to this value. + */ + private boolean activatorWasAlive; + + static { + try { + File file = new File(ResourceUtils.getFilePath4Resource("parameters/XacmlPdpConfigParameters_Std.json")); + STD_CONFIG = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + + file = new File(file.getParentFile(), "Test_XacmlPdpConfigParameters.json"); + file.deleteOnExit(); + + CONFIG_FILE = file.getAbsolutePath(); + CONFIG_PATH = new File(CONFIG_FILE).toPath(); + + } catch (IOException e) { + throw new ExceptionInInitializerError(e); + } + } + + /** + * Configures system properties and creates a JSON config file. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("javax.net.ssl.keyStore", KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", "Pol1cy_0nap"); + + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + + writeJsonConfig(); + + final String[] xacmlPdpConfigParameters = {"-c", CommonRest.CONFIG_FILE, "-p", "parameters/topic.properties"}; + main = new Main(xacmlPdpConfigParameters); + + if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) { + throw new IllegalStateException("server is not listening on port " + port); + } + } + + /** + * Stops the "Main". + */ + @AfterClass + public static void tearDownAfterClass() { + stopMain(); + } + + /** + * Resets the statistics. + */ + @Before + public void setUp() { + activatorWasAlive = XacmlPdpActivator.getCurrent().isAlive(); + XacmlPdpStatisticsManager.getCurrent().resetAllStatistics(); + } + + /** + * Restores the "alive" status of the activator. + */ + @After + public void tearDown() { + markActivator(activatorWasAlive); + } + + /** + * Stops the "main". + */ + protected static void stopMain() { + main.shutdown(); + } + + /** + * Writes a JSON config file, substituting an allocated port number for occurrences of + * "${port}". + * + * @return the allocated server port + * @throws IOException if the config file cannot be created + */ + public static int writeJsonConfig() throws IOException { + port = NetworkUtil.allocPort(); + + String config = STD_CONFIG.replace("${port}", String.valueOf(port)); + Files.write(CONFIG_PATH, config.getBytes(StandardCharsets.UTF_8)); + + return port; + } + + /** + * Sends an HTTPS request to an endpoint of the PDP's REST API. + * + * @param endpoint target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendHttpsRequest(final String endpoint) throws Exception { + // always trust the certificate + final SSLContext sc = SSLContext.getInstance("TLSv1.2"); + sc.init(null, NetworkUtil.getAlwaysTrustingManager(), new SecureRandom()); + + // always trust the host name + final ClientBuilder clientBuilder = + ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true); + + final Client client = clientBuilder.build(); + final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"); + client.register(feature); + + final WebTarget webTarget = client.target("https://localhost:" + port + "/policy/pdpx/v1/" + endpoint); + + return webTarget.request(MediaType.APPLICATION_JSON); + } + + /** + * Mark the activator as dead, but leave its REST server running. + */ + protected void markActivatorDead() { + markActivator(false); + } + + /** + * Changes the internal "alive" status of the activator to a new value. + * + * @param newAlive the new "alive" status + */ + private void markActivator(boolean newAlive) { + Object manager = Whitebox.getInternalState(XacmlPdpActivator.getCurrent(), "serviceManager"); + Whitebox.setInternalState(manager, "running", newAlive); + } +} diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java index 3a1e98b1..5f7eb78c 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java @@ -67,6 +67,7 @@ public class TestDecision { private static final Logger LOGGER = LoggerFactory.getLogger(TestDecision.class); + private static int port; private static Main main; private static HttpClient client; @@ -82,6 +83,9 @@ public class TestDecision { public static void beforeClass() throws Exception { System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + + port = NetworkUtil.allocPort(); + // // Copy test directory over of the application directories // @@ -94,7 +98,7 @@ public class TestDecision { // Get the parameters file correct. // RestServerParameters rest = new RestServerParameters(new RestServerBuilder() - .setHost("0.0.0.0").setPort(6969).setUserName("healthcheck").setPassword("zb!XztG34")); + .setHost("0.0.0.0").setPort(port).setUserName("healthcheck").setPassword("zb!XztG34")); XacmlPdpParameterGroup params = new XacmlPdpParameterGroup("XacmlPdpGroup", rest, apps.getAbsolutePath()); final Gson gson = new GsonBuilder().create(); File fileParams = appsFolder.newFile("params.json"); @@ -108,8 +112,8 @@ public class TestDecision { // // Make sure it is running // - if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 20, 1000L)) { - throw new IllegalStateException("Cannot connect to port 6969"); + if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) { + throw new IllegalStateException("Cannot connect to port " + port); } // // Create a client @@ -123,8 +127,7 @@ public class TestDecision { } @Test - public void testDecision_UnsupportedAction() throws KeyManagementException, NoSuchAlgorithmException, - ClassNotFoundException { + public void testDecision_UnsupportedAction() throws Exception { LOGGER.info("Running test testDecision_UnsupportedAction"); @@ -165,7 +168,7 @@ public class TestDecision { assertThat(response.getStatus()).isEqualTo("Permit"); } - private static Main startXacmlPdpService(File params) { + private static Main startXacmlPdpService(File params) throws PolicyXacmlPdpException { final String[] XacmlPdpConfigParameters = {"-c", params.getAbsolutePath(), "-p", "parameters/topic.properties"}; return new Main(XacmlPdpConfigParameters); @@ -200,7 +203,7 @@ public class TestDecision { return HttpClient.factory.build(BusTopicParams.builder() .clientName("testDecisionClient") .serializationProvider(GsonMessageBodyHandler.class.getName()) - .useHttps(false).allowSelfSignedCerts(false).hostname("localhost").port(6969) + .useHttps(false).allowSelfSignedCerts(false).hostname("localhost").port(port) .basePath("policy/pdpx/v1/decision") .userName("healthcheck").password("zb!XztG34").managed(true).build()); } diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java index f9f2abf3..ba8f0044 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java @@ -21,41 +21,12 @@ package org.onap.policy.pdpx.main.rest; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.Properties; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.junit.After; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.FixMethodOrder; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runners.MethodSorters; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; import org.onap.policy.common.endpoints.report.HealthCheckReport; -import org.onap.policy.common.utils.network.NetworkUtil; -import org.onap.policy.pdpx.main.PolicyXacmlPdpException; -import org.onap.policy.pdpx.main.parameters.CommonTestData; -import org.onap.policy.pdpx.main.parameters.RestServerParameters; +import org.onap.policy.pdpx.main.CommonRest; import org.onap.policy.pdpx.main.rest.model.StatisticsReport; -import org.onap.policy.pdpx.main.startstop.Main; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,8 +34,7 @@ import org.slf4j.LoggerFactory; * Class to perform unit test of {@link XacmlPdpRestServer}. * */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestXacmlPdpRestServer { +public class TestXacmlPdpRestServer extends CommonRest { private static final Logger LOGGER = LoggerFactory.getLogger(TestXacmlPdpRestServer.class); private static final String NOT_ALIVE = "not alive"; @@ -73,224 +43,79 @@ public class TestXacmlPdpRestServer { private static final String NAME = "Policy Xacml PDP"; private static final String HEALTHCHECK_ENDPOINT = "healthcheck"; private static final String STATISTICS_ENDPOINT = "statistics"; - private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore"; - private Main main; - private XacmlPdpRestServer restServer; - private static File applicationPath; - - @ClassRule - public static final TemporaryFolder applicationFolder = new TemporaryFolder(); - - /** - * setup. - * - * @throws IOException exception if cannot create temporary folder - */ - @BeforeClass - public static void setUp() throws IOException { - System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); - System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); - applicationPath = applicationFolder.newFolder(); - } - - /** - * Method for cleanup after each test. - */ - @After - public void teardown() { - try { - if (NetworkUtil.isTcpPortOpen("localhost", 6969, 1, 1000L)) { - if (main != null) { - stopXacmlPdpService(main); - main = null; - } - - if (restServer != null) { - restServer.stop(); - restServer = null; - } - } - } catch (IOException | PolicyXacmlPdpException e) { - LOGGER.error("teardown failed", e); - } catch (InterruptedException ie) { - Thread.interrupted(); - LOGGER.error("teardown failed", ie); - } - } @Test - public void test1HealthCheckSuccess() throws IOException, InterruptedException, TopicSinkClientException { - LOGGER.info("***************************** Running test1HealthCheckSuccess *****************************"); - main = startXacmlPdpService(true); - final Invocation.Builder invocationBuilder = sendHttpRequest(HEALTHCHECK_ENDPOINT); + public void testHealthCheckSuccess() throws Exception { + LOGGER.info("***************************** Running testHealthCheckSuccess *****************************"); + final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT); final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class); LOGGER.info("test1HealthCheckSuccess health report {}", report); validateHealthCheckReport(NAME, SELF, true, 200, ALIVE, report); } @Test - public void test7HealthCheckFailure() throws InterruptedException, IOException { - LOGGER.info("***************************** Running test7HealthCheckFailure *****************************"); - final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false); - restServerParams.setName(CommonTestData.PDPX_GROUP_NAME); - restServer = new XacmlPdpRestServer(restServerParams, applicationPath.getAbsolutePath()); - restServer.start(); - final Invocation.Builder invocationBuilder = sendHttpRequest(HEALTHCHECK_ENDPOINT); + public void testHealthCheckFailure() throws Exception { + LOGGER.info("***************************** Running testHealthCheckFailure *****************************"); + + markActivatorDead(); + + final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT); final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class); - LOGGER.info("test7HealthCheckFailure health report {}", report); + LOGGER.info("testHealthCheckFailure health report {}", report); validateHealthCheckReport(NAME, SELF, false, 500, NOT_ALIVE, report); - assertTrue(restServer.isAlive()); - assertTrue(restServer.toString().startsWith("XacmlPdpRestServer [servers=")); } @Test - public void test2HttpsHealthCheckSuccess() throws Exception { - LOGGER.info("**************************** Running test2HttpsHealthCheckSuccess ****************************"); - main = startXacmlPdpService(false); + public void testHttpsHealthCheckSuccess() throws Exception { + LOGGER.info("***************************** Running testHttpsHealthCheckSuccess *****************************"); final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT); final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class); - LOGGER.info("test2HttpsHealthCheckSuccess health report {}", report); + LOGGER.info("testHttpsHealthCheckSuccess health report {}", report); validateHealthCheckReport(NAME, SELF, true, 200, ALIVE, report); } @Test - public void test4Statistics_200() throws IOException, InterruptedException, TopicSinkClientException { - LOGGER.info("***************************** Running test4Statistics_200 *****************************"); - XacmlPdpStatisticsManager.resetAllStatistics(); - main = startXacmlPdpService(true); - Invocation.Builder invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT); + public void testStatistics_200() throws Exception { + LOGGER.info("***************************** Running testStatistics_200 *****************************"); + Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT); StatisticsReport report = invocationBuilder.get(StatisticsReport.class); - LOGGER.info("test4Statistics_200 health report {}", report); + LOGGER.info("testStatistics_200 health report {}", report); validateStatisticsReport(report, 0, 200); updateXacmlPdpStatistics(); - invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT); + invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT); report = invocationBuilder.get(StatisticsReport.class); - LOGGER.info("test4Statistics_200 health report {}", report); + LOGGER.info("testStatistics_200 health report {}", report); validateStatisticsReport(report, 1, 200); - XacmlPdpStatisticsManager.resetAllStatistics(); } @Test - public void test5Statistics_500() throws IOException, InterruptedException { - LOGGER.info("***************************** Running test5Statistics_500 *****************************"); - final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false); - restServerParams.setName(CommonTestData.PDPX_GROUP_NAME); - restServer = new XacmlPdpRestServer(restServerParams, applicationPath.getAbsolutePath()); - restServer.start(); - final Invocation.Builder invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT); + public void testStatistics_500() throws Exception { + LOGGER.info("***************************** Running testStatistics_500 *****************************"); + + markActivatorDead(); + + final Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT); final StatisticsReport report = invocationBuilder.get(StatisticsReport.class); - LOGGER.info("test5Statistics_500 health report {}", report); + LOGGER.info("testStatistics_500 health report {}", report); validateStatisticsReport(report, 0, 500); - XacmlPdpStatisticsManager.resetAllStatistics(); } @Test - public void test6HttpsStatistic() throws Exception { - LOGGER.info("***************************** Running test6HttpsStatistic *****************************"); - main = startXacmlPdpService(false); + public void testHttpsStatistic() throws Exception { + LOGGER.info("***************************** Running testHttpsStatistic *****************************"); final Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT); final StatisticsReport report = invocationBuilder.get(StatisticsReport.class); - LOGGER.info("test6HttpsStatistic health report {}", report); + LOGGER.info("testHttpsStatistic health report {}", report); validateStatisticsReport(report, 0, 200); } - @Test - public void test3StatisticsConstructorIsPrivate() { - LOGGER.info("************************* Running test3StatisticsConstructorIsPrivate *************************"); - try { - final Constructor<XacmlPdpStatisticsManager> constructor = - XacmlPdpStatisticsManager.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - constructor.newInstance(); - fail("Expected an InstantiationException to be thrown"); - } catch (final Exception exp) { - assertTrue(exp.getCause().toString().contains("Instantiation of the class is not allowed")); - } - } - - private Main startXacmlPdpService(final boolean http) throws TopicSinkClientException { - final String[] xacmlPdpConfigParameters = new String[4]; - if (http) { - xacmlPdpConfigParameters[0] = "-c"; - xacmlPdpConfigParameters[1] = "parameters/XacmlPdpConfigParameters.json"; - xacmlPdpConfigParameters[2] = "-p"; - xacmlPdpConfigParameters[3] = "parameters/topic.properties"; - } else { - final Properties systemProps = System.getProperties(); - systemProps.put("javax.net.ssl.keyStore", KEYSTORE); - systemProps.put("javax.net.ssl.keyStorePassword", "Pol1cy_0nap"); - System.setProperties(systemProps); - xacmlPdpConfigParameters[0] = "-c"; - xacmlPdpConfigParameters[1] = "parameters/XacmlPdpConfigParameters_Https.json"; - xacmlPdpConfigParameters[2] = "-p"; - xacmlPdpConfigParameters[3] = "parameters/topic.properties"; - } - return new Main(xacmlPdpConfigParameters); - } - - private void stopXacmlPdpService(final Main main) throws PolicyXacmlPdpException { - main.shutdown(); - } - - private Invocation.Builder sendHttpRequest(final String endpoint) throws IOException, InterruptedException { - final ClientConfig clientConfig = new ClientConfig(); - - final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"); - clientConfig.register(feature); - - final Client client = ClientBuilder.newClient(clientConfig); - final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/" + endpoint); - - final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); - - if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 20, 1000L)) { - throw new IllegalStateException("Cannot connect to port 6969"); - } - - return invocationBuilder; - } - - private Invocation.Builder sendHttpsRequest(final String endpoint) throws Exception { - - final TrustManager[] noopTrustManager = new TrustManager[] {new X509TrustManager() { - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - @Override - public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {} - - @Override - public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {} - } }; - - final SSLContext sc = SSLContext.getInstance("TLSv1.2"); - sc.init(null, noopTrustManager, new SecureRandom()); - final ClientBuilder clientBuilder = - ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true); - final Client client = clientBuilder.build(); - final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"); - client.register(feature); - - final WebTarget webTarget = client.target("https://localhost:6969/policy/pdpx/v1/" + endpoint); - - final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); - - if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 6, 10000L)) { - throw new IllegalStateException("cannot connect to port 6969"); - } - return invocationBuilder; - } - private void updateXacmlPdpStatistics() { - XacmlPdpStatisticsManager.updateTotalPoliciesCount(); - XacmlPdpStatisticsManager.updatePermitDecisionsCount(); - XacmlPdpStatisticsManager.updateDenyDecisionsCount(); - XacmlPdpStatisticsManager.updateIndeterminantDecisionsCount(); - XacmlPdpStatisticsManager.updateNotApplicableDecisionsCount(); + XacmlPdpStatisticsManager stats = XacmlPdpStatisticsManager.getCurrent(); + stats.updateTotalPoliciesCount(); + stats.updatePermitDecisionsCount(); + stats.updateDenyDecisionsCount(); + stats.updateIndeterminantDecisionsCount(); + stats.updateNotApplicableDecisionsCount(); } private void validateStatisticsReport(final StatisticsReport report, final int count, final int code) { @@ -303,7 +128,7 @@ public class TestXacmlPdpRestServer { } private void validateHealthCheckReport(final String name, final String url, final boolean healthy, final int code, - final String message, final HealthCheckReport report) { + final String message, final HealthCheckReport report) { assertEquals(name, report.getName()); assertEquals(url, report.getUrl()); assertEquals(healthy, report.isHealthy()); diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java index 6a762924..250f21e6 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java @@ -21,31 +21,11 @@ package org.onap.policy.pdpx.main.rest; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import java.io.File; -import java.io.IOException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; -import org.onap.policy.common.utils.network.NetworkUtil; -import org.onap.policy.pdpx.main.PolicyXacmlPdpException; -import org.onap.policy.pdpx.main.parameters.CommonTestData; -import org.onap.policy.pdpx.main.parameters.RestServerParameters; -import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager; +import org.onap.policy.pdpx.main.CommonRest; import org.onap.policy.pdpx.main.rest.model.StatisticsReport; -import org.onap.policy.pdpx.main.startstop.Main; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,101 +33,42 @@ import org.slf4j.LoggerFactory; * Class to perform unit test of {@link XacmlPdpRestController}. * */ -public class TestXacmlPdpStatistics { +public class TestXacmlPdpStatistics extends CommonRest { private static final Logger LOGGER = LoggerFactory.getLogger(TestXacmlPdpStatistics.class); - private static File applicationPath; - - @ClassRule - public static final TemporaryFolder applicationFolder = new TemporaryFolder(); - - /** - * Turn off some debugging and create temporary folder for applications. - * - * @throws IOException If temporary folder fails - */ - @BeforeClass - public static void beforeClass() throws IOException { - System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); - System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); - applicationPath = applicationFolder.newFolder(); - } @Test - public void testXacmlPdpStatistics_200() throws PolicyXacmlPdpException, InterruptedException { - try { - LOGGER.info("*************************** Running testXacmlPdpStatistics_200 ***************************"); - final Main main = startXacmlPdpService(); - StatisticsReport report = getXacmlPdpStatistics(); - validateReport(report, 0, 200); - assertThat(report.getTotalPolicyTypesCount()).isGreaterThan(0); - updateXacmlPdpStatistics(); - report = getXacmlPdpStatistics(); - validateReport(report, 1, 200); - stopXacmlPdpService(main); - XacmlPdpStatisticsManager.resetAllStatistics(); - } catch (final Exception e) { - LOGGER.error("testApiStatistics_200 failed", e); - fail("Test should not throw an exception"); - } + public void testXacmlPdpStatistics_200() throws Exception { + LOGGER.info("*************************** Running testXacmlPdpStatistics_200 ***************************"); + StatisticsReport report = getXacmlPdpStatistics(); + validateReport(report, 0, 200); + updateXacmlPdpStatistics(); + report = getXacmlPdpStatistics(); + validateReport(report, 1, 200); } @Test - public void testXacmlPdpStatistics_500() throws InterruptedException { + public void testXacmlPdpStatistics_500() throws Exception { LOGGER.info("***************************** Running testXacmlPdpStatistics_500 *****************************"); - final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false); - restServerParams.setName(CommonTestData.PDPX_GROUP_NAME); - final XacmlPdpRestServer restServer = new XacmlPdpRestServer(restServerParams, - applicationPath.getAbsolutePath()); - try { - restServer.start(); - final StatisticsReport report = getXacmlPdpStatistics(); - validateReport(report, 0, 500); - restServer.shutdown(); - XacmlPdpStatisticsManager.resetAllStatistics(); - } catch (final Exception e) { - LOGGER.error("testApiStatistics_500 failed", e); - fail("Test should not throw an exception"); - } - } - - - private Main startXacmlPdpService() throws TopicSinkClientException { - final String[] XacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json", "-p", - "parameters/topic.properties"}; - return new Main(XacmlPdpConfigParameters); - } + markActivatorDead(); - private void stopXacmlPdpService(final Main main) throws PolicyXacmlPdpException { - main.shutdown(); + final StatisticsReport report = getXacmlPdpStatistics(); + validateReport(report, 0, 500); } - private StatisticsReport getXacmlPdpStatistics() throws InterruptedException, IOException { - - final ClientConfig clientConfig = new ClientConfig(); - - final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"); - clientConfig.register(feature); - - final Client client = ClientBuilder.newClient(clientConfig); - final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/statistics"); - - final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); - - if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 20, 1000L)) { - throw new IllegalStateException("Cannot connect to port 6969"); - } - - return invocationBuilder.get(StatisticsReport.class); + private StatisticsReport getXacmlPdpStatistics() throws Exception { + return sendHttpsRequest("statistics").get(StatisticsReport.class); } private void updateXacmlPdpStatistics() { - XacmlPdpStatisticsManager.updateTotalPoliciesCount(); - XacmlPdpStatisticsManager.updatePermitDecisionsCount(); - XacmlPdpStatisticsManager.updateDenyDecisionsCount(); - XacmlPdpStatisticsManager.updateIndeterminantDecisionsCount(); - XacmlPdpStatisticsManager.updateNotApplicableDecisionsCount(); + XacmlPdpStatisticsManager stats = XacmlPdpStatisticsManager.getCurrent(); + + stats.updateTotalPoliciesCount(); + stats.updatePermitDecisionsCount(); + stats.updateDenyDecisionsCount(); + stats.updateIndeterminantDecisionsCount(); + stats.updateNotApplicableDecisionsCount(); } private void validateReport(final StatisticsReport report, final int count, final int code) { diff --git a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java index 80ee95f6..e8448ab2 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java @@ -20,70 +20,84 @@ package org.onap.policy.pdpx.main.startstop; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; +import org.onap.policy.pdpx.main.CommonRest; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; -import org.onap.policy.pdpx.main.parameters.CommonTestData; /** * Class to perform unit test of Main. * */ -public class TestMain { +public class TestMain extends CommonRest { + + private Main main; /** - * setup. + * Sets up properties and configuration. + * @throws Exception if an error occurs */ @BeforeClass - public static void setUp() { - System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); - System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + public static void setUpBeforeClass() throws Exception { + CommonRest.setUpBeforeClass(); + + // don't want the common "main" running + CommonRest.stopMain(); + } + + @Before + public void setUp() { + main = null; + } + /** + * Shuts "main" down. + */ + @After + public void tearDown() { + if (main != null) { + main.shutdown(); + } } @Test - public void testMain() throws PolicyXacmlPdpException, TopicSinkClientException { - final String[] xacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json"}; - final Main main = new Main(xacmlPdpConfigParameters); - assertTrue(main.getParameters().isValid()); - assertEquals(CommonTestData.PDPX_GROUP_NAME, main.getParameters().getName()); + public void testMain() throws PolicyXacmlPdpException { + final String[] xacmlPdpConfigParameters = {"-c", CONFIG_FILE, "-p", "parameters/topic.properties"}; + main = new Main(xacmlPdpConfigParameters); main.shutdown(); + main = null; } @Test - public void testMain_NoArguments() throws PolicyXacmlPdpException, TopicSinkClientException { + public void testMain_NoArguments() { final String[] xacmlPdpConfigParameters = {}; - final Main main = new Main(xacmlPdpConfigParameters); - assertNull(main.getParameters()); - main.shutdown(); + assertThatThrownBy(() -> new Main(xacmlPdpConfigParameters)).isInstanceOf(PolicyXacmlPdpException.class) + .hasMessage("policy xacml pdp configuration file was not specified as an argument"); } @Test - public void testMain_InvalidArguments() throws TopicSinkClientException { + public void testMain_InvalidArguments() { final String[] xacmlPdpConfigParameters = {"parameters/XacmlPdpConfigParameters.json"}; - final Main main = new Main(xacmlPdpConfigParameters); - assertNull(main.getParameters()); + assertThatThrownBy(() -> new Main(xacmlPdpConfigParameters)).isInstanceOf(PolicyXacmlPdpException.class) + .hasMessage("too many command line arguments specified : [parameters/XacmlPdpConfigParameters.json]"); } @Test - public void testMain_Help() throws TopicSinkClientException { + public void testMain_Help() throws PolicyXacmlPdpException { final String[] xacmlPdpConfigParameters = {"-h"}; - final Main main = new Main(xacmlPdpConfigParameters); - final String message = "-h,--help outputs the usage of this command"; - Assert.assertTrue(main.getArgumentMessage().contains(message)); + Assert.assertTrue(new Main(xacmlPdpConfigParameters).getArgumentMessage().contains("-h,--help")); } @Test - public void testMain_InvalidParameters() throws TopicSinkClientException { + public void testMain_InvalidParameters() { final String[] xacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters_InvalidName.json"}; - final Main main = new Main(xacmlPdpConfigParameters); - assertNull(main.getParameters()); + assertThatThrownBy(() -> new Main(xacmlPdpConfigParameters)).isInstanceOf(PolicyXacmlPdpException.class) + .hasMessageContaining("validation error"); } } diff --git a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestXacmlPdpActivator.java b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestXacmlPdpActivator.java index 5930dd5e..b60f4589 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestXacmlPdpActivator.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestXacmlPdpActivator.java @@ -26,13 +26,12 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.FileInputStream; -import java.net.UnknownHostException; import java.util.Properties; - import org.junit.After; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException; +import org.onap.policy.pdpx.main.CommonRest; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; import org.onap.policy.pdpx.main.parameters.CommonTestData; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; @@ -43,30 +42,44 @@ import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterHandler; * Class to perform unit test of XacmlPdpActivator. * */ -public class TestXacmlPdpActivator { - private static XacmlPdpActivator activator = null; +public class TestXacmlPdpActivator extends CommonRest { + private static XacmlPdpParameterGroup parGroup; + private static Properties props; + + private XacmlPdpActivator activator = null; /** - * Setup the tests. + * Loads properties. */ @BeforeClass - public static void setup() throws Exception { + public static void setUpBeforeClass() throws Exception { + CommonRest.setUpBeforeClass(); + final String[] xacmlPdpConfigParameters = - {"-c", "parameters/XacmlPdpConfigParameters.json", "-p", "parameters/topic.properties"}; + {"-c", CommonRest.CONFIG_FILE, "-p", "parameters/topic.properties"}; final XacmlPdpCommandLineArguments arguments = new XacmlPdpCommandLineArguments(xacmlPdpConfigParameters); - final XacmlPdpParameterGroup parGroup = new XacmlPdpParameterHandler().getParameters(arguments); + parGroup = new XacmlPdpParameterHandler().getParameters(arguments); - Properties props = new Properties(); + props = new Properties(); String propFile = arguments.getFullPropertyFilePath(); try (FileInputStream stream = new FileInputStream(propFile)) { props.load(stream); } + // don't want the common "main" running + CommonRest.stopMain(); + } + + /** + * Creates the activator. + */ + @Before + public void setUp() { activator = new XacmlPdpActivator(parGroup, props); } @Test - public void testXacmlPdpActivator() throws PolicyXacmlPdpException, TopicSinkClientException, UnknownHostException { + public void testXacmlPdpActivator() throws Exception { assertFalse(activator.isAlive()); activator.start(); assertTrue(activator.isAlive()); @@ -77,14 +90,13 @@ public class TestXacmlPdpActivator { @Test public void testGetCurrent_testSetCurrent() { + XacmlPdpActivator.setCurrent(activator); assertSame(activator, XacmlPdpActivator.getCurrent()); } @Test public void testTerminate() throws Exception { - if (!activator.isAlive()) { - activator.start(); - } + activator.start(); activator.stop(); assertFalse(activator.isAlive()); } diff --git a/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Std.json index ae5e1cbd..5b6586a3 100644 --- a/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json +++ b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Std.json @@ -2,7 +2,7 @@ "name":"XacmlPdpGroup", "restServerParameters":{ "host":"0.0.0.0", - "port":6969, + "port":${port}, "userName":"healthcheck", "password":"zb!XztG34", "https":true |