aboutsummaryrefslogtreecommitdiffstats
path: root/gui-pdp-monitoring/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'gui-pdp-monitoring/src/main/java')
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringMain.java170
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServer.java92
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterException.java47
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterParser.java113
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameters.java95
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/package-info.java27
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/EngineStatus.java43
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/PdpMonitoringRestResource.java277
-rw-r--r--gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/StatisticsResponse.java48
9 files changed, 912 insertions, 0 deletions
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringMain.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringMain.java
new file mode 100644
index 0000000..34b2901
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringMain.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import lombok.Getter;
+import lombok.ToString;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The main class for Pdp Statistics Monitoring.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+@ToString
+public class PdpMonitoringMain {
+ // Logger for this class
+ private static final Logger LOGGER = LoggerFactory.getLogger(PdpMonitoringMain.class);
+
+ // Recurring string constants
+ private static final String PDP_MONITORING_PREFIX = "Pdp Monitoring GUI (";
+
+ // Services state
+ public enum ServicesState {
+ STOPPED, READY, INITIALIZING, RUNNING
+ }
+
+ @Getter
+ private ServicesState state = ServicesState.STOPPED;
+
+ // The parameters for the Server
+ private PdpMonitoringServerParameters parameters = null;
+
+ // The Pdp Monitoring services this class is running
+ private PdpMonitoringServer pdpMonitoringServer = null;
+
+ private CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ /**
+ * Constructor, kicks off the GUI service.
+ *
+ * @param args The command line arguments for the RESTful service
+ */
+ public PdpMonitoringMain(final String[] args) {
+
+ // Server parameter parsing
+ final PdpMonitoringServerParameterParser parser = new PdpMonitoringServerParameterParser();
+
+ try {
+ // Get and check the parameters
+ parameters = parser.parse(args);
+ } catch (final PdpMonitoringServerParameterException e) {
+ throw new PdpMonitoringServerParameterException(PDP_MONITORING_PREFIX + this + ") parameter error, "
+ + e.getMessage() + '\n' + parser.getHelp(PdpMonitoringMain.class.getName()), e);
+ }
+
+ if (parameters.isHelpSet()) {
+ throw new PdpMonitoringServerParameterException(parser.getHelp(PdpMonitoringMain.class.getName()));
+ }
+
+ // Validate the parameters
+ final ValidationResult validationResult = parameters.validate();
+ if (!validationResult.isValid()) {
+ throw new PdpMonitoringServerParameterException(
+ PDP_MONITORING_PREFIX + this + ") parameters invalid, " + validationResult.getResult() + '\n'
+ + parser.getHelp(PdpMonitoringMain.class.getName()));
+ }
+
+ state = ServicesState.READY;
+ }
+
+ /**
+ * Initialize the rest service.
+ */
+ public void init() {
+ LOGGER.info(PDP_MONITORING_PREFIX + "{}) starting at {} . . .", this, parameters.getBaseUri());
+
+ try {
+ state = ServicesState.INITIALIZING;
+
+ // Start the Pdp Monitoring service
+ pdpMonitoringServer = new PdpMonitoringServer(parameters);
+
+ // Add a shutdown hook to shut down the servlet services when the process is exiting
+ Runtime.getRuntime().addShutdownHook(new Thread(new PdpServicesShutdownHook()));
+
+ state = ServicesState.RUNNING;
+
+ if (parameters.getTimeToLive() == PdpMonitoringServerParameters.INFINITY_TIME_TO_LIVE) {
+ LOGGER.info(PDP_MONITORING_PREFIX + "{}) starting at {} . . .", this, parameters.getTimeToLive());
+ } else {
+ LOGGER.info(PDP_MONITORING_PREFIX + "{}) started", this);
+ }
+
+ // Find out how long is left to wait
+ long timeRemaining = parameters.getTimeToLive();
+ if (timeRemaining >= 0) {
+ countDownLatch.await(timeRemaining, TimeUnit.SECONDS);
+ } else {
+ countDownLatch.await();
+ }
+ } catch (final Exception e) {
+ LOGGER.warn(this + " failed with error", e);
+ } finally {
+ shutdown();
+ }
+
+ }
+
+ /**
+ * Explicitly shut down the services.
+ */
+ public void shutdown() {
+ if (pdpMonitoringServer != null) {
+ LOGGER.info(PDP_MONITORING_PREFIX + "{}) shutting down", this);
+ pdpMonitoringServer.shutdown(parameters.getPort(), parameters.getDefaultRestPort());
+ }
+ countDownLatch.countDown();
+ state = ServicesState.STOPPED;
+ LOGGER.info(PDP_MONITORING_PREFIX + "{}) shutting down", this);
+ }
+
+ /**
+ * This class is a shutdown hook for the Pdp services command.
+ */
+ private class PdpServicesShutdownHook implements Runnable {
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void run() {
+ shutdown();
+ }
+ }
+
+ /**
+ * Main method, main entry point for command.
+ *
+ * @param args The command line arguments for the GUI
+ */
+ public static void main(final String[] args) {
+ try {
+ final PdpMonitoringMain main = new PdpMonitoringMain(args);
+ main.init();
+ } catch (final Exception e) {
+ LOGGER.error("start failed", e);
+ }
+ }
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServer.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServer.java
new file mode 100644
index 0000000..97d2deb
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServer.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring;
+
+import lombok.NonNull;
+import org.eclipse.jetty.servlets.CrossOriginFilter;
+import org.onap.policy.common.endpoints.http.server.HttpServletServer;
+import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is used to launch the services. It creates a Jetty embedded web server and runs the
+ * services.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+public class PdpMonitoringServer {
+ // Logger for this class
+ private static final Logger LOGGER = LoggerFactory.getLogger(PdpMonitoringServer.class);
+
+ // The HTTP server exposing JAX-RS resources defined in this application.
+ private HttpServletServer jerseyServer;
+
+ // The HTTP server exposing static resources defined in this application.
+ private HttpServletServer staticResourceServer;
+
+ /**
+ * Starts the HTTP server for the Pdp statistics monitoring on the default base URI and with the
+ * default REST packages.
+ */
+ public PdpMonitoringServer() {
+ this(new PdpMonitoringServerParameters());
+ }
+
+ /**
+ * Starts the HTTP server for the Pdp statistics monitoring GUI.
+ *
+ * @param parameters The Pdp parameters to use to start the server.
+ * @return
+ */
+ public PdpMonitoringServer(@NonNull final PdpMonitoringServerParameters parameters) {
+
+ LOGGER.debug("Pdp Monitoring starting . . .");
+
+ jerseyServer = HttpServletServerFactoryInstance.getServerFactory().build("PDP Monitoring Rest Server", false,
+ parameters.getServerHost(), parameters.getDefaultRestPort(), parameters.getContextPath(), false, true);
+ jerseyServer.addServletPackage(parameters.getDefaultRestPath(), parameters.getRestPackage());
+ jerseyServer.addFilterClass(parameters.getDefaultRestPath(), CrossOriginFilter.class.getName());
+ jerseyServer.start();
+
+ staticResourceServer = HttpServletServerFactoryInstance.getServerFactory().buildStaticResourceServer(
+ "PDP Monitoring Html Server", false, parameters.getServerHost(), parameters.getPort(),
+ parameters.getContextPath(), true);
+ staticResourceServer.addServletResource(null,
+ PdpMonitoringServer.class.getClassLoader().getResource("webapp").toExternalForm());
+ staticResourceServer.start();
+
+ LOGGER.debug("Pdp Monitoring started");
+ }
+
+ /**
+ * Shut down the web server.
+ *
+ * @param htmlPort port number of static resource server
+ * @param restPort port number of jersey server
+ */
+ public void shutdown(int htmlPort, int restPort) {
+ LOGGER.debug("Pdp Monitoring . . .");
+ HttpServletServerFactoryInstance.getServerFactory().destroy(htmlPort);
+ HttpServletServerFactoryInstance.getServerFactory().destroy(restPort);
+ LOGGER.debug("Pdp Monitoring shut down");
+ }
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterException.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterException.java
new file mode 100644
index 0000000..8977d33
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterException.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring;
+
+/**
+ * A run time exception used to report parsing and parameter input errors.
+ */
+public class PdpMonitoringServerParameterException extends IllegalArgumentException {
+ private static final long serialVersionUID = 6520231162404452427L;
+
+ /**
+ * Create an PdpMonitoringServerParameterException with a message.
+ *
+ * @param message the message
+ */
+ public PdpMonitoringServerParameterException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Create an PdpMonitoringServerParameterException with a message and an exception.
+ *
+ * @param message the message
+ * @param throwable The exception that caused the exception
+ */
+ public PdpMonitoringServerParameterException(final String message, final Throwable throwable) {
+ super(message, throwable);
+ }
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterParser.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterParser.java
new file mode 100644
index 0000000..5d9d290
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameterParser.java
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * This class reads and handles command line parameters to the Pdp Statistics services.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+public class PdpMonitoringServerParameterParser {
+ // Apache Commons CLI options
+ private final Options options;
+
+ /**
+ * Construct the options for the Pdp monitoring services.
+ */
+ public PdpMonitoringServerParameterParser() {
+ options = new Options();
+ options.addOption("h", "help", false, "outputs the usage of this command");
+ options.addOption(Option.builder("p").longOpt("port").desc("port to use for the Pdp Services REST calls")
+ .hasArg().argName("PORT").required(false).type(Number.class).build());
+ options.addOption(Option.builder("t").longOpt("time-to-live")
+ .desc("the amount of time in seconds that the server will run for before terminating").hasArg()
+ .argName("TIME_TO_LIVE").required(false).type(Number.class).build());
+ }
+
+ /**
+ * Parse the command line options.
+ *
+ * @param args the arguments
+ * @return parsed parameters
+ */
+ public PdpMonitoringServerParameters parse(final String[] args) {
+ CommandLine commandLine = null;
+ try {
+ commandLine = new DefaultParser().parse(options, args);
+ } catch (final ParseException e) {
+ throw new PdpMonitoringServerParameterException("invalid command line arguments specified", e);
+ }
+
+ final PdpMonitoringServerParameters parameters = new PdpMonitoringServerParameters();
+ final String[] remainingArgs = commandLine.getArgs();
+
+ if (commandLine.getArgs().length > 0) {
+ throw new PdpMonitoringServerParameterException(
+ "too many command line arguments specified : " + Arrays.toString(remainingArgs));
+ }
+
+ if (commandLine.hasOption('h')) {
+ parameters.setHelpSet(true);
+ }
+ try {
+ if (commandLine.hasOption('p')) {
+ parameters.setPort(((Number) commandLine.getParsedOptionValue("port")).intValue());
+ }
+ } catch (final ParseException e) {
+ throw new PdpMonitoringServerParameterException("error parsing argument \"port\"", e);
+ }
+ try {
+ if (commandLine.hasOption('t')) {
+ parameters.setTimeToLive(((Number) commandLine.getParsedOptionValue("time-to-live")).longValue());
+ }
+ } catch (final ParseException e) {
+ throw new PdpMonitoringServerParameterException("error parsing argument \"time-to-live\"", e);
+ }
+
+ return parameters;
+ }
+
+ /**
+ * Get help information.
+ *
+ * @param mainClassName the main class name for the help output
+ * @return help string
+ */
+ public String getHelp(final String mainClassName) {
+ final StringWriter stringWriter = new StringWriter();
+ final PrintWriter stringPrintWriter = new PrintWriter(stringWriter);
+
+ final HelpFormatter helpFormatter = new HelpFormatter();
+ helpFormatter.printHelp(stringPrintWriter, 120, mainClassName + " [options...] ", "", options, 0, 0, "");
+
+ return stringWriter.toString();
+ }
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameters.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameters.java
new file mode 100644
index 0000000..614d47d
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/PdpMonitoringServerParameters.java
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring;
+
+import java.net.URI;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.onap.policy.common.parameters.BeanValidator;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.annotations.Max;
+import org.onap.policy.common.parameters.annotations.Min;
+
+/**
+ * This class reads and handles command line parameters to the Pdp Monitoring services.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+@ToString
+@Getter
+@Setter
+public class PdpMonitoringServerParameters {
+ public static final int DEFAULT_PORT = 18999;
+ public static final int INFINITY_TIME_TO_LIVE = -1;
+
+ // Base URI the HTTP server will listen on
+ private static final String DEFAULT_SERVER_URI_ROOT = "http://0.0.0.0:";
+ private static final String DEFAULT_REST_PATH = "/papservices/*";
+ private static final String DEFAULT_CONTEXT_PATH = "/";
+ private static final String SERVER_HOST = "0.0.0.0";
+ private static final int DEFAULT_REST_PORT = 17999;
+ // Package that will field REST requests
+ private static final String DEFAULT_REST_PACKAGE = "org.onap.policy.gui.pdp.monitoring.rest";
+
+ // The services parameters
+ private boolean helpSet = false;
+
+ @Min(1024)
+ @Max(65534)
+ private int port = DEFAULT_PORT;
+
+ @Min(-1)
+ private long timeToLive = INFINITY_TIME_TO_LIVE;
+
+ /**
+ * Validate the parameters.
+ *
+ * @return the result of the validation
+ */
+ public ValidationResult validate() {
+ return new BeanValidator().validateTop(PdpMonitoringServerParameters.class.getSimpleName(), this);
+ }
+
+ public URI getBaseUri() {
+ return URI.create(DEFAULT_SERVER_URI_ROOT + port + DEFAULT_REST_PATH);
+ }
+
+ public String getRestPackage() {
+ return DEFAULT_REST_PACKAGE;
+ }
+
+ public String getContextPath() {
+ return DEFAULT_CONTEXT_PATH;
+ }
+
+ public String getServerHost() {
+ return SERVER_HOST;
+ }
+
+ public String getDefaultRestPath() {
+ return DEFAULT_REST_PATH;
+ }
+
+ public int getDefaultRestPort() {
+ return DEFAULT_REST_PORT;
+ }
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/package-info.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/package-info.java
new file mode 100644
index 0000000..d1595b8
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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=========================================================
+ */
+
+/**
+ * Implements the PDP monitoring GUI.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+
+package org.onap.policy.gui.pdp.monitoring;
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/EngineStatus.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/EngineStatus.java
new file mode 100644
index 0000000..5d2d38a
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/EngineStatus.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring.rest;
+
+import lombok.Setter;
+
+
+/**
+ * A POJO class to record engine worker status.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ *
+ */
+@Setter
+@SuppressWarnings("unused")
+class EngineStatus {
+ private String timestamp;
+ private String id;
+ private String status;
+ private String lastMessage;
+ private long upTime;
+ private long policyExecutions;
+ private String lastPolicyDuration;
+ private String averagePolicyDuration;
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/PdpMonitoringRestResource.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/PdpMonitoringRestResource.java
new file mode 100644
index 0000000..921c68c
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/PdpMonitoringRestResource.java
@@ -0,0 +1,277 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring.rest;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
+import org.onap.policy.common.endpoints.http.client.HttpClient;
+import org.onap.policy.common.endpoints.http.client.HttpClientConfigException;
+import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpEngineWorkerStatistics;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpStatistics;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The class represents the root resource exposed at the base URL<br>
+ * The url to access this resource would be in the form {@code <baseURL>/rest/....} <br>
+ * For example: a GET request to the following URL
+ * {@code http://localhost:18989/papservices/rest/?hostName=localhost&port=12345}
+ *
+ * <b>Note:</b> An allocated {@code hostName} and {@code port} query parameter must be included in
+ * all requests. Datasets for different {@code hostName} are completely isolated from one another.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ */
+@Path("monitoring/")
+@Produces({MediaType.APPLICATION_JSON})
+@Consumes({MediaType.APPLICATION_JSON})
+public class PdpMonitoringRestResource {
+ // Get a reference to the logger
+ private static final Logger LOGGER = LoggerFactory.getLogger(PdpMonitoringRestResource.class);
+ // Set up a map separated by host and engine for the data
+ private static final Map<String, HashMap<String, List<Counter>>> cache = new HashMap<>();
+
+ // Set the maximum number of stored data entries to be stored for each engine
+ private static final int MAX_CACHED_ENTITIES = 50;
+
+ private static Gson gson = new Gson();
+
+ /**
+ * Query Pdps.
+ *
+ * @param useHttps use Http or not
+ * @param hostname hostname the host name of the engine service to connect to.
+ * @param port port the port number of the engine service to connect to.
+ * @param username user name
+ * @param password password
+ * @return a Response object containing Pdps in JSON
+ * @throws HttpClientConfigException exception
+ */
+ @GET
+ public Response getPdps(@QueryParam("useHttps") final String useHttps,
+ @QueryParam("hostname") final String hostname, @QueryParam("port") final int port,
+ @QueryParam("username") final String username, @QueryParam("password") final String password)
+ throws HttpClientConfigException {
+
+ return Response
+ .ok(getHttpClient(useHttps, hostname, port, username, password, "policy/pap/v1/pdps").get().getEntity(),
+ MediaType.APPLICATION_JSON)
+ .build();
+ }
+
+ /**
+ * Query Pdp statistics.
+ *
+ * @param useHttps use Http or not
+ * @param hostname the host name of the engine service to connect to.
+ * @param port the port number of the engine service to connect to.
+ * @param username user name
+ * @param password password
+ * @param id PdpGroupName/PdpSubGroup/PdpIntanceID
+ * @return a Response object containing the Pdp status and context data in JSON
+ * @throws HttpClientConfigException exception
+ * @throws CoderException Coder exception
+ */
+ @GET
+ @Path("statistics/")
+ public Response getStatistics(@QueryParam("useHttps") final String useHttps,
+ @QueryParam("hostname") final String hostname, @QueryParam("port") final int port,
+ @QueryParam("username") final String username, @QueryParam("password") final String password,
+ @QueryParam("id") final String id) throws HttpClientConfigException, CoderException {
+
+ PdpGroups pdpGroups = getHttpClient(useHttps, hostname, port, username, password, "policy/pap/v1/pdps").get()
+ .readEntity(PdpGroups.class);
+ String groupName;
+ String subGroup;
+ String instanceId;
+ String[] idArray = id.split("/");
+ if (idArray.length == 3) {
+ groupName = idArray[0];
+ subGroup = idArray[1];
+ instanceId = idArray[2];
+ } else {
+ throw new IllegalArgumentException("Cannot parse groupName, subGroup and instanceId from " + id);
+ }
+
+ Pdp pdp = pdpGroups.getGroups().stream().filter(group -> group.getName().equals(groupName))
+ .flatMap(group -> group.getPdpSubgroups().stream().filter(sub -> sub.getPdpType().equals(subGroup)))
+ .flatMap(sub -> sub.getPdpInstances().stream()
+ .filter(instance -> instance.getInstanceId().equals(instanceId)))
+ .filter(Objects::nonNull).findFirst().orElseThrow();
+
+ final StatisticsResponse responseObject = new StatisticsResponse();
+
+ // Engine Service data
+ responseObject.setEngineId(pdp.getInstanceId());
+ responseObject.setServer(hostname);
+ responseObject.setPort(Integer.toString(port));
+ responseObject.setHealthStatus(pdp.getHealthy().name());
+ responseObject.setPdpState(pdp.getPdpState().name());
+
+ String statisticsEntity = getHttpClient(useHttps, hostname, port, username, password,
+ "policy/pap/v1/pdps/statistics/" + id + "?recordCount=1").get().readEntity(String.class);
+ Map<String, Map<String, List<PdpStatistics>>> pdpStats = gson.fromJson(statisticsEntity,
+ new TypeToken<Map<String, Map<String, List<PdpStatistics>>>>() {}.getType());
+
+ final List<EngineStatus> engineStatusList = new ArrayList<>();
+
+ if (!pdpStats.isEmpty()) {
+ PdpStatistics pdpStatistics = pdpStats.get(groupName).get(subGroup).get(0);
+ responseObject.setTimeStamp(pdpStatistics.getTimeStamp().toString());
+ responseObject.setPolicyDeployCount(pdpStatistics.getPolicyDeployCount());
+ responseObject.setPolicyDeploySuccessCount(pdpStatistics.getPolicyDeploySuccessCount());
+ responseObject.setPolicyDeployFailCount(pdpStatistics.getPolicyDeployFailCount());
+ responseObject.setPolicyExecutedCount(pdpStatistics.getPolicyExecutedCount());
+ responseObject.setPolicyExecutedSuccessCount(pdpStatistics.getPolicyExecutedSuccessCount());
+ responseObject.setPolicyExecutedFailCount(pdpStatistics.getPolicyExecutedFailCount());
+
+ // Engine Status data
+ for (final PdpEngineWorkerStatistics engineStats : pdpStatistics.getEngineStats()) {
+ try {
+ final EngineStatus engineStatusObject = new EngineStatus();
+ engineStatusObject.setTimestamp(pdpStatistics.getTimeStamp().toString());
+ engineStatusObject.setId(engineStats.getEngineId());
+ engineStatusObject.setStatus(engineStats.getEngineWorkerState().name());
+ engineStatusObject.setLastMessage(new Date(engineStats.getEngineTimeStamp()).toString());
+ engineStatusObject.setUpTime(engineStats.getUpTime());
+ engineStatusObject.setPolicyExecutions(engineStats.getEventCount());
+ engineStatusObject.setLastPolicyDuration(gson.toJson(
+ getValuesFromCache(id, engineStats.getEngineId() + "_last_policy_duration",
+ pdpStatistics.getTimeStamp().getTime(), engineStats.getLastExecutionTime()),
+ List.class));
+ engineStatusObject.setAveragePolicyDuration(
+ gson.toJson(getValuesFromCache(id, engineStats.getEngineId() + "_average_policy_duration",
+ pdpStatistics.getTimeStamp().getTime(),
+ (long) engineStats.getAverageExecutionTime()), List.class));
+ engineStatusList.add(engineStatusObject);
+ } catch (final RuntimeException e) {
+ LOGGER.warn("Error getting status of engine with ID " + engineStats.getEngineId() + "<br>", e);
+ }
+ }
+ } else {
+ responseObject.setTimeStamp("N/A");
+ responseObject.setPolicyDeployCount("N/A");
+ responseObject.setPolicyDeploySuccessCount("N/A");
+ responseObject.setPolicyDeployFailCount("N/A");
+ responseObject.setPolicyExecutedCount("N/A");
+ responseObject.setPolicyExecutedSuccessCount("N/A");
+ responseObject.setPolicyExecutedFailCount("N/A");
+ }
+
+ responseObject.setStatus(engineStatusList);
+ return Response.ok(new StandardCoder().encode(responseObject), MediaType.APPLICATION_JSON).build();
+ }
+
+ private HttpClient getHttpClient(String useHttps, String hostname, int port, String username, String password,
+ String basePath) throws HttpClientConfigException {
+ BusTopicParams busParams = new BusTopicParams();
+ busParams.setClientName("pdp-monitoring");
+ busParams.setHostname(hostname);
+ busParams.setManaged(false);
+ busParams.setPassword(password);
+ busParams.setPort(port);
+ busParams.setUseHttps(useHttps.equals("https"));
+ busParams.setUserName(username);
+ busParams.setBasePath(basePath);
+ return HttpClientFactoryInstance.getClientFactory().build(busParams);
+ }
+
+ /**
+ * This method takes in the latest data entry for an engine, adds it to an existing data set and
+ * returns the full map for that host and engine.
+ *
+ * @param uri the pdp uri
+ * @param id the engines id
+ * @param timestamp the timestamp of the latest data entry
+ * @param latestValue the value of the latest data entry
+ * @return a list of {@code Counter} objects for that engine
+ */
+ private synchronized List<Counter> getValuesFromCache(final String uri, final String id, final long timestamp,
+ final long latestValue) {
+
+ Map<String, List<Counter>> engineStatus = cache.computeIfAbsent(uri, k -> new HashMap<>());
+
+ List<Counter> valueList = engineStatus.computeIfAbsent(id, k -> new SlidingWindowList<>(MAX_CACHED_ENTITIES));
+
+ valueList.add(new Counter(timestamp, latestValue));
+
+ return valueList;
+ }
+
+ /**
+ * A list of values that uses a FIFO sliding window of a fixed size.
+ */
+ @EqualsAndHashCode(callSuper = true)
+ public class SlidingWindowList<V> extends LinkedList<V> {
+ private static final long serialVersionUID = -7187277916025957447L;
+
+ private final int maxEntries;
+
+ public SlidingWindowList(final int maxEntries) {
+ this.maxEntries = maxEntries;
+ }
+
+ @Override
+ public boolean add(final V elm) {
+ if (this.size() > (maxEntries - 1)) {
+ this.removeFirst();
+ }
+ return super.add(elm);
+ }
+ }
+
+ /**
+ * A class used to storing a single data entry for an engine.
+ */
+ @Getter
+ public class Counter {
+ private final long timestamp;
+ private final long value;
+
+ public Counter(final long timestamp, final long value) {
+ this.timestamp = timestamp;
+ this.value = value;
+ }
+ }
+
+}
diff --git a/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/StatisticsResponse.java b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/StatisticsResponse.java
new file mode 100644
index 0000000..ada722f
--- /dev/null
+++ b/gui-pdp-monitoring/src/main/java/org/onap/policy/gui/pdp/monitoring/rest/StatisticsResponse.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 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.gui.pdp.monitoring.rest;
+
+import java.util.List;
+import lombok.Setter;
+
+/**
+ * A POJO class to record Pdp statistics.
+ *
+ * @author Yehui Wang (yehui.wang@est.tech)
+ *
+ */
+@Setter
+@SuppressWarnings("unused")
+class StatisticsResponse {
+ private String engineId;
+ private String server;
+ private String port;
+ private String healthStatus;
+ private String pdpState;
+ private String timeStamp;
+ private Object policyDeployCount;
+ private Object policyDeploySuccessCount;
+ private Object policyDeployFailCount;
+ private Object policyExecutedCount;
+ private Object policyExecutedSuccessCount;
+ private Object policyExecutedFailCount;
+ private List<EngineStatus> status;
+}