summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Hernandez <jh1730@att.com>2017-05-25 16:44:15 -0500
committerJorge Hernandez <jh1730@att.com>2017-05-25 16:44:15 -0500
commit881c32ec109f0fff6f5661940ad035c3dfc0c7d9 (patch)
tree79070ad7386cc9b62cf504ebf62ec8702792be4d
parentf354096969e91aa2b3dcdc52adcc2bde1b3b0b74 (diff)
[POLICY-16] generic introduction of swagger
On a per-server basis append /swagger.json or /swagger.yaml ie: HTTP GET :6969/swagger.json HTTP GET :9696/swagger.json Resulting specification can be used by swagger clients. Change-Id: I4b1a8b53d50b1528664150934b04e92447e4d4d7 Signed-off-by: Jorge Hernandez <jh1730@att.com>
-rw-r--r--policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java1
-rw-r--r--policy-endpoints/pom.xml12
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java16
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java75
-rw-r--r--policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java195
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java6
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java44
-rw-r--r--policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java7
-rw-r--r--policy-healthcheck/pom.xml7
-rw-r--r--policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java39
-rw-r--r--policy-management/config/policy-engine.properties6
-rw-r--r--policy-management/pom.xml8
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java3
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java2152
-rw-r--r--policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java19
-rw-r--r--policy-management/src/main/server/config/IntegrityMonitor.properties1
-rw-r--r--policy-management/src/main/server/config/policy-engine.properties1
-rw-r--r--policy-management/src/main/server/config/policy-healthcheck.properties1
-rw-r--r--policy-persistence/pom.xml2
-rw-r--r--pom.xml56
20 files changed, 1849 insertions, 802 deletions
diff --git a/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java b/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java
index 1274e08c..5e7a351c 100644
--- a/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java
+++ b/policy-core/src/main/java/org/openecomp/policy/drools/properties/PolicyProperties.java
@@ -90,6 +90,7 @@ public interface PolicyProperties {
public static final String PROPERTY_HTTP_REST_URIPATH_SUFFIX = ".restUriPath";
public static final String PROPERTY_HTTP_HTTPS_SUFFIX = ".https";
+ public static final String PROPERTY_HTTP_SWAGGER_SUFFIX = ".swagger";
/* HTTP Client Properties */
diff --git a/policy-endpoints/pom.xml b/policy-endpoints/pom.xml
index cd79f6a7..dba7349f 100644
--- a/policy-endpoints/pom.xml
+++ b/policy-endpoints/pom.xml
@@ -89,7 +89,6 @@
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
@@ -127,6 +126,17 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-jersey2-jaxrs</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java
index 5f5dd787..106602bc 100644
--- a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServer.java
@@ -44,10 +44,10 @@ public interface HttpServletServer extends Startable {
/**
* adds a JAX-RS servlet class to serve REST requests
*
- * @param servletPath
- * @param restClass
- * @throws IllegalArgumentException
- * @throws IllegalStateException
+ * @param servletPath servlet path
+ * @param restClass JAX-RS API Class
+ * @throws IllegalArgumentException unable to process because of invalid input
+ * @throws IllegalStateException unable to process because of invalid state
*/
public void addServletClass(String servletPath, String restClass)
throws IllegalArgumentException, IllegalStateException;
@@ -55,10 +55,10 @@ public interface HttpServletServer extends Startable {
/**
* adds a package containing JAX-RS classes to serve REST requests
*
- * @param servletPath
- * @param restPackage
- * @throws IllegalArgumentException
- * @throws IllegalStateException
+ * @param servletPath servlet path
+ * @param restPackage JAX-RS package to scan
+ * @throws IllegalArgumentException unable to process because of invalid input
+ * @throws IllegalStateException unable to process because of invalid state
*/
public void addServletPackage(String servletPath, String restPackage)
throws IllegalArgumentException, IllegalStateException;
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java
index bd5ae242..40f5c9ad 100644
--- a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/HttpServletServerFactory.java
@@ -31,36 +31,87 @@ import org.openecomp.policy.drools.http.server.internal.JettyJerseyServer;
import org.openecomp.policy.drools.properties.PolicyProperties;
/**
- * Jetty Server Factory
+ * Factory of HTTP Servlet-Enabled Servlets
*/
public interface HttpServletServerFactory {
- public HttpServletServer build(String name, String host, int port, String contextPath, boolean managed)
- throws IllegalArgumentException;
+ /**
+ * builds an http server with support for servlets
+ *
+ * @param name name
+ * @param host binding host
+ * @param port port
+ * @param contextPath server base path
+ * @param swagger enable swagger documentation
+ * @param managed is it managed by infrastructure
+ * @return http server
+ * @throws IllegalArgumentException when invalid parameters are provided
+ */
+ public HttpServletServer build(String name, String host, int port, String contextPath,
+ boolean swagger, boolean managed)
+ throws IllegalArgumentException;
+ /**
+ * list of http servers per properties
+ *
+ * @param properties properties based configuration
+ * @return list of http servers
+ * @throws IllegalArgumentException when invalid parameters are provided
+ */
public ArrayList<HttpServletServer> build(Properties properties) throws IllegalArgumentException;
+ /**
+ * gets a server based on the port
+ *
+ * @param port port
+ * @return http server
+ */
public HttpServletServer get(int port);
+
+ /**
+ * provides an inventory of servers
+ *
+ * @return inventory of servers
+ */
public List<HttpServletServer> inventory();
+
+ /**
+ * destroys server bound to a port
+ * @param port
+ */
public void destroy(int port);
+
+ /**
+ * destroys the factory and therefore all servers
+ */
public void destroy();
}
+/**
+ * Indexed factory implementation
+ */
class IndexedHttpServletServerFactory implements HttpServletServerFactory {
- protected static Logger logger = FlexLogger.getLogger(IndexedHttpServletServerFactory.class);
+ /**
+ * logger
+ */
+ protected static Logger logger = FlexLogger.getLogger(IndexedHttpServletServerFactory.class);
- protected HashMap<Integer, JettyJerseyServer> servers = new HashMap<Integer, JettyJerseyServer>();
+ /**
+ * servers index
+ */
+ protected HashMap<Integer, HttpServletServer> servers = new HashMap<Integer, HttpServletServer>();
@Override
public synchronized HttpServletServer build(String name, String host, int port,
- String contextPath, boolean managed)
+ String contextPath, boolean swagger,
+ boolean managed)
throws IllegalArgumentException {
if (servers.containsKey(port))
return servers.get(port);
- JettyJerseyServer server = new JettyJerseyServer(name, host, port, contextPath);
+ JettyJerseyServer server = new JettyJerseyServer(name, host, port, contextPath, swagger);
if (managed)
servers.put(port, server);
@@ -140,7 +191,15 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
managed = Boolean.parseBoolean(managedString);
}
- HttpServletServer service = build(serviceName, hostName, servicePort, contextUriPath, managed);
+ String swaggerString = properties.getProperty(PolicyProperties.PROPERTY_HTTP_SERVER_SERVICES + "." +
+ serviceName +
+ PolicyProperties.PROPERTY_HTTP_SWAGGER_SUFFIX);
+ boolean swagger = false;
+ if (swaggerString != null && !swaggerString.isEmpty()) {
+ swagger = Boolean.parseBoolean(swaggerString);
+ }
+
+ HttpServletServer service = build(serviceName, hostName, servicePort, contextUriPath, swagger, managed);
if (userName != null && !userName.isEmpty() && password != null && !password.isEmpty()) {
service.setBasicAuthentication(userName, password, authUriPath);
}
diff --git a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java
index 4914a4cb..5bc320e5 100644
--- a/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java
+++ b/policy-endpoints/src/main/java/org/openecomp/policy/drools/http/server/internal/JettyJerseyServer.java
@@ -19,52 +19,132 @@
*/
package org.openecomp.policy.drools.http.server.internal;
-import java.util.ArrayList;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.HashMap;
import org.eclipse.jetty.servlet.ServletHolder;
-
import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
import org.openecomp.policy.common.logging.flexlogger.Logger;
+import io.swagger.jersey.config.JerseyJaxrsConfig;
+
/**
- * REST Jetty Server using Jersey
+ * REST Jetty Server that uses Jersey Servlets to support JAX-RS Web Services
*/
public class JettyJerseyServer extends JettyServletServer {
- protected static final String JERSEY_PACKAGES_PARAM = "jersey.config.server.provider.packages";
- protected static final String JERSEY_CLASSNAMES_PARAM = "jersey.config.server.provider.classnames";
+ /**
+ * Jersey Packages Init Param Name
+ */
+ protected static final String JERSEY_INIT_PACKAGES_PARAM_NAME = "jersey.config.server.provider.packages";
+
+ /**
+ * Jersey Packages Init Param Value
+ */
+ protected static final String JERSEY_INIT_PACKAGES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json";
+
+ /**
+ * Swagger Packages
+ */
+ protected static final String SWAGGER_INIT_PACKAGES_PARAM_VALUE = "io.swagger.jaxrs.listing";
+ /**
+ * Jersey Classes Init Param Name
+ */
+ protected static final String JERSEY_INIT_CLASSNAMES_PARAM_NAME = "jersey.config.server.provider.classnames";
+
+ /**
+ * Jersey Jackson Classes Init Param Value
+ */
+ protected static final String JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider";
+
+ /**
+ * Jersey Swagger Classes Init Param Value
+ */
+ protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE = "io.swagger.jaxrs.listing.ApiListingResource," +
+ "io.swagger.jaxrs.listing.SwaggerSerializers";
+ /**
+ * Logger
+ */
protected static Logger logger = FlexLogger.getLogger(JettyJerseyServer.class);
- protected ArrayList<String> packages = new ArrayList<String>();
- protected HashMap<String, ServletHolder> servlets =
- new HashMap<String, ServletHolder>();
+ /**
+ * Container for servlets
+ */
+ protected HashMap<String, ServletHolder> servlets = new HashMap<String, ServletHolder>();
+
+ /**
+ * Swagger ID
+ */
+ protected String swaggerId = null;
- public JettyJerseyServer(String name, String host, int port, String contextPath)
- throws IllegalArgumentException {
+ /**
+ * Constructor
+ *
+ * @param name name
+ * @param host host server host
+ * @param port port server port
+ * @param swagger support swagger?
+ * @param contextPath context path
+ *
+ * @throws IllegalArgumentException in invalid arguments are provided
+ */
+ public JettyJerseyServer(String name, String host, int port, String contextPath, boolean swagger)
+ throws IllegalArgumentException {
+
super(name, host, port, contextPath);
+ if (swagger) {
+ this.swaggerId = "swagger-" + this.port;
+ attachSwaggerServlet();
+ }
}
- protected synchronized ServletHolder getServlet(String servletPath)
- throws IllegalArgumentException {
+ /**
+ * attaches a swagger initialization servlet
+ */
+ protected void attachSwaggerServlet() {
+
+ ServletHolder swaggerServlet = context.addServlet(JerseyJaxrsConfig.class, "/");
+
+ String hostname = this.connector.getHost();
+ if (hostname == null || hostname.isEmpty() || hostname.equals("0.0.0.0")) {
+ try {
+ hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ logger.warn("can't resolve connector's hostname: " + this);
+ hostname = "localhost";
+ }
+ }
+
+ swaggerServlet.setInitParameter("swagger.api.basepath",
+ "http://" + hostname + ":" + this.connector.getPort() + "/");
+ swaggerServlet.setInitParameter("swagger.context.id", swaggerId);
+ swaggerServlet.setInitParameter("swagger.scanner.id", swaggerId);
+ swaggerServlet.setInitParameter("swagger.pretty.print", "true");
+ swaggerServlet.setInitOrder(2);
- if (servletPath == null || servletPath.isEmpty())
- servletPath = "/*";
+ if (logger.isDebugEnabled())
+ logger.debug(this + "Swagger Servlet has been attached: " + swaggerServlet.dump());
+ }
+
+ /**
+ * retrieves cached server based on servlet path
+ *
+ * @param servletPath servlet path
+ * @return the jetty servlet holder
+ *
+ * @throws IllegalArgumentException if invalid arguments are provided
+ */
+ protected synchronized ServletHolder getServlet(String servletPath)
+ throws IllegalArgumentException {
ServletHolder jerseyServlet = servlets.get(servletPath);
if (jerseyServlet == null) {
jerseyServlet = context.addServlet
(org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
jerseyServlet.setInitOrder(0);
- String initPackages =
- jerseyServlet.getInitParameter(JERSEY_PACKAGES_PARAM);
- if (initPackages == null) {
- jerseyServlet.setInitParameter(
- JERSEY_PACKAGES_PARAM,
- "com.jersey.jaxb,com.fasterxml.jackson.jaxrs.json");
- }
- this.servlets.put(servletPath, jerseyServlet);
+ servlets.put(servletPath, jerseyServlet);
}
return jerseyServlet;
@@ -76,19 +156,36 @@ public class JettyJerseyServer extends JettyServletServer {
if (restPackage == null || restPackage.isEmpty())
throw new IllegalArgumentException("No discoverable REST package provided");
+
+ if (servletPath == null || servletPath.isEmpty())
+ servletPath = "/*";
ServletHolder jerseyServlet = this.getServlet(servletPath);
- if (jerseyServlet == null)
- throw new IllegalStateException("Unexpected, no Jersey Servlet class");
+
+ String initClasses =
+ jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
+ if (initClasses != null && !initClasses.isEmpty())
+ logger.warn("Both packages and classes are used in Jetty+Jersey Configuration: " + restPackage);
String initPackages =
- jerseyServlet.getInitParameter(JERSEY_PACKAGES_PARAM);
- if (initPackages == null)
- throw new IllegalStateException("Unexpected, no Init Parameters loaded");
+ jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
+ if (initPackages == null) {
+ if (this.swaggerId != null) {
+ initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," +
+ SWAGGER_INIT_PACKAGES_PARAM_VALUE + "," +
+ restPackage;
+
+ jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
+ jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
+ } else {
+ initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," +
+ restPackage;
+ }
+ } else {
+ initPackages = initPackages + "," + restPackage;
+ }
- jerseyServlet.setInitParameter(
- JERSEY_PACKAGES_PARAM,
- initPackages + "," + restPackage);
+ jerseyServlet.setInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME, initPackages);
if (logger.isDebugEnabled())
logger.debug(this + "Added REST Package: " + jerseyServlet.dump());
@@ -100,31 +197,45 @@ public class JettyJerseyServer extends JettyServletServer {
if (restClass == null || restClass.isEmpty())
throw new IllegalArgumentException("No discoverable REST class provided");
+
+ if (servletPath == null || servletPath.isEmpty())
+ servletPath = "/*";
ServletHolder jerseyServlet = this.getServlet(servletPath);
- if (jerseyServlet == null)
- throw new IllegalStateException("Unexpected, no Jersey Servlet class");
+
+ String initPackages =
+ jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
+ if (initPackages != null && !initPackages.isEmpty())
+ logger.warn("Both classes and packages are used in Jetty+Jersey Configuration: " + restClass);
String initClasses =
- jerseyServlet.getInitParameter(JERSEY_CLASSNAMES_PARAM);
- if (initClasses == null)
- initClasses = restClass;
- else
+ jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
+ if (initClasses == null) {
+ if (this.swaggerId != null) {
+ initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," +
+ SWAGGER_INIT_CLASSNAMES_PARAM_VALUE + "," +
+ restClass;
+
+ jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
+ jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
+ } else {
+ initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + restClass;
+ }
+ } else {
initClasses = initClasses + "," + restClass;
+ }
- jerseyServlet.setInitParameter(
- JERSEY_CLASSNAMES_PARAM,
- initClasses);
+ jerseyServlet.setInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME, initClasses);
if (logger.isDebugEnabled())
logger.debug(this + "Added REST Class: " + jerseyServlet.dump());
}
-
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("JerseyJettyServer [packages=").append(packages).append(", servlets=").append(servlets)
- .append(", toString()=").append(super.toString()).append("]");
+ builder.append("JettyJerseyServer [servlets=").append(servlets).append(", swaggerId=").append(swaggerId)
+ .append(", toString()=").append(super.toString()).append("]");
return builder.toString();
}
}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java
index 47774b1f..cd149f7a 100644
--- a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpClientTest.java
@@ -38,7 +38,7 @@ public class HttpClientTest {
public void testHttpNoAuthClient() throws Exception {
System.out.println("-- testHttpNoAuthClient() --");
- HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", false, true);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
@@ -59,7 +59,7 @@ public class HttpClientTest {
public void testHttpAuthClient() throws Exception {
System.out.println("-- testHttpAuthClient() --");
- HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", false, true);
server.setBasicAuthentication("x", "y", null);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
@@ -81,7 +81,7 @@ public class HttpClientTest {
public void testHttpAuthClient401() throws Exception {
System.out.println("-- testHttpAuthClient401() --");
- HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 6666, "/", false, true);
server.setBasicAuthentication("x", "y", null);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java
index 94f29804..6a369814 100644
--- a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/HttpServerTest.java
@@ -31,7 +31,7 @@ import org.junit.Test;
import org.openecomp.policy.drools.http.server.HttpServletServer;
/**
- *
+ * HttpServletServer JUNIT tests
*/
public class HttpServerTest {
@@ -39,7 +39,7 @@ public class HttpServerTest {
public void testSingleServer() throws Exception {
System.out.println("-- testSingleServer() --");
- HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 5678, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 5678, "/", false, true);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
@@ -50,6 +50,16 @@ public class HttpServerTest {
String response = response(url);
System.out.println("Received .. " + response);
assertTrue(response.equals(echo));
+
+ String responseSwagger = null;
+ try {
+ URL urlSwagger = new URL("http://localhost:5678/swagger.json" + echo);
+ responseSwagger = response(urlSwagger);
+ } catch(IOException ioe) {
+ // Expected
+ }
+
+ assertTrue(responseSwagger == null);
HttpServletServer.factory.destroy();
assertTrue(HttpServletServer.factory.inventory().size() == 0);
@@ -59,11 +69,11 @@ public class HttpServerTest {
public void testMultipleServers() throws Exception {
System.out.println("-- testMultipleServers() --");
- HttpServletServer server1 = HttpServletServer.factory.build("echo-1", "localhost", 5678, "/", true);
+ HttpServletServer server1 = HttpServletServer.factory.build("echo-1", "localhost", 5678, "/", true, true);
server1.addServletPackage("/*", this.getClass().getPackage().getName());
server1.waitedStart(5000);
- HttpServletServer server2 = HttpServletServer.factory.build("echo-2", "localhost", 5679, "/", true);
+ HttpServletServer server2 = HttpServletServer.factory.build("echo-2", "localhost", 5679, "/", false, true);
server2.addServletPackage("/*", this.getClass().getPackage().getName());
server2.waitedStart(5000);
@@ -77,11 +87,28 @@ public class HttpServerTest {
System.out.println("Received .. " + response1);
assertTrue(response1.equals(echo));
+ URL urlSwagger = new URL("http://localhost:5678/swagger.json");
+ String responseSwagger = response(urlSwagger);
+
+ System.out.println("Received .. " + responseSwagger);
+ assertTrue(responseSwagger != null);
+
URL url2 = new URL("http://localhost:5679/junit/echo/" + echo);
String response2 = response(url2);
System.out.println("Received .. " + response2);
assertTrue(response2.equals(echo));
+ String responseSwagger2 = null;
+ try {
+ URL urlSwagger2 = new URL("http://localhost:5679/swagger.json");
+ responseSwagger2 = response(urlSwagger2);
+ } catch(IOException ioe) {
+ // Expected
+ }
+
+ System.out.println("Received .. " + responseSwagger2);
+ assertTrue(responseSwagger2 == null);
+
HttpServletServer.factory.destroy();
assertTrue(HttpServletServer.factory.inventory().size() == 0);
}
@@ -92,7 +119,7 @@ public class HttpServerTest {
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", false, true);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
@@ -118,7 +145,7 @@ public class HttpServerTest {
System.out.println("-- testServiceClass() --");
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", false, true);
server.addServletClass("/*", RestEchoService.class.getCanonicalName());
server.waitedStart(5000);
@@ -140,7 +167,7 @@ public class HttpServerTest {
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5678, "/", false, true);
server.addServletClass("/*", RestEchoService.class.getCanonicalName());
server.addServletClass("/*", RestEndpoints.class.getCanonicalName());
server.waitedStart(5000);
@@ -173,6 +200,9 @@ public class HttpServerTest {
while ((line = ioReader.readLine()) != null) {
response += line;
}
+
+ System.out.println("R is " + response);
+ ioReader.close();
return response;
}
diff --git a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java
index a0320a09..b714925f 100644
--- a/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java
+++ b/policy-endpoints/src/test/java/org/openecomp/policy/drools/http/server/test/RestEchoService.java
@@ -6,12 +6,19 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value="echo")
@Path("/junit/echo")
public class RestEchoService {
@GET
@Path("{word}")
@Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(
+ value="echoes back whatever received"
+ )
public String echo(@PathParam("word") String word) {
return word;
}
diff --git a/policy-healthcheck/pom.xml b/policy-healthcheck/pom.xml
index 5a409d4a..913a944c 100644
--- a/policy-healthcheck/pom.xml
+++ b/policy-healthcheck/pom.xml
@@ -32,7 +32,7 @@
<artifactId>policy-healthcheck</artifactId>
<name>policy-healthcheck</name>
- <description>Separately loadable module with healthcheck code</description>
+ <description>Separately loadable module to perform healthchecks of the system</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
@@ -92,6 +92,11 @@
</build>
<dependencies>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-jersey2-jaxrs</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.openecomp.policy.drools-pdp</groupId>
<artifactId>policy-core</artifactId>
diff --git a/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java
index e37e758a..06854042 100644
--- a/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java
+++ b/policy-healthcheck/src/main/java/org/openecomp/policy/drools/healthcheck/RestHealthCheck.java
@@ -4,23 +4,54 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import org.openecomp.policy.drools.healthcheck.HealthCheck.Reports;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Info;
+import io.swagger.annotations.SwaggerDefinition;
+import io.swagger.annotations.Tag;
+
@Path("/")
+@Api
+@Produces(MediaType.APPLICATION_JSON)
+@SwaggerDefinition(
+ info = @Info(
+ description = "PDP-D Healthcheck Service",
+ version = "v1.0",
+ title = "PDP-D Healthcheck"
+ ),
+ consumes = {MediaType.APPLICATION_JSON},
+ produces = {MediaType.APPLICATION_JSON},
+ schemes = {SwaggerDefinition.Scheme.HTTP},
+ tags = {
+ @Tag(name = "pdp-d-healthcheck", description = "Drools PDP Healthcheck Operations")
+ }
+)
public class RestHealthCheck {
@GET
- @Path("{a:healthcheck|test}")
+ @Path("healthcheck")
@Produces(MediaType.APPLICATION_JSON)
- public Reports healthcheck() {
- Reports reports = HealthCheck.monitor.healthCheck();
- return reports;
+ @ApiOperation(
+ value="Perform a system healthcheck",
+ notes="Provides healthy status of the PDP-D plus the components defined in its configuration by using a REST interface",
+ response=Reports.class
+ )
+ public Response healthcheck() {
+ return Response.status(Response.Status.OK).entity(HealthCheck.monitor.healthCheck()).build();
}
@GET
@Path("healthcheck/configuration")
@Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(
+ value="Configuration",
+ notes="Provides the Healthcheck server configuration and monitored REST clients",
+ response=HealthCheck.class
+ )
public HealthCheck configuration() {
return HealthCheck.monitor;
}
diff --git a/policy-management/config/policy-engine.properties b/policy-management/config/policy-engine.properties
index 41456c27..27bd7651 100644
--- a/policy-management/config/policy-engine.properties
+++ b/policy-management/config/policy-engine.properties
@@ -18,9 +18,13 @@ ueb.sink.topics.PDPD_CONFIGURATION.partitionKey=
ueb.sink.topics.PDPD_CONFIGURATION.managed=false
http.server.services=CONFIG
-http.server.services.CONFIG.host=localhost
+http.server.services.CONFIG.host=0.0.0.0
http.server.services.CONFIG.port=9696
http.server.services.CONFIG.userName=x
http.server.services.CONFIG.password=y
http.server.services.CONFIG.restPackages=org.openecomp.policy.drools.server.restful
+#http.server.services.CONFIG.restPackages=org.openecomp.policy.drools.server.restful,org.openecomp.policy.drools.healthcheck
+#http.server.services.CONFIG.restClasses=org.openecomp.policy.drools.server.restful.RestManager,org.openecomp.policy.drools.healthcheck.RestHealthCheck
+#http.server.services.CONFIG.restClasses=org.openecomp.policy.drools.server.restful.RestManager
http.server.services.CONFIG.managed=false
+http.server.services.CONFIG.swagger=true
diff --git a/policy-management/pom.xml b/policy-management/pom.xml
index 8b791e47..7feef7a8 100644
--- a/policy-management/pom.xml
+++ b/policy-management/pom.xml
@@ -174,7 +174,6 @@
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
@@ -196,6 +195,11 @@
</dependency>
<dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-jersey2-jaxrs</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
@@ -211,7 +215,7 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java
index 4396a0ce..e404a092 100644
--- a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java
@@ -49,6 +49,7 @@ import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration
import org.openecomp.policy.drools.utils.ReflectionUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Maven-based Drools Controller that interacts with the
@@ -667,6 +668,7 @@ public class MavenDroolsController implements DroolsController {
/**
* {@inheritDoc}
*/
+ @JsonProperty("sessions")
@Override
public List<String> getSessionNames() {
return getSessionNames(true);
@@ -675,6 +677,7 @@ public class MavenDroolsController implements DroolsController {
/**
* {@inheritDoc}
*/
+ @JsonProperty("sessionCoordinates")
@Override
public List<String> getCanonicalSessionNames() {
return getSessionNames(false);
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java
index a4aaa856..de666165 100644
--- a/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java
@@ -20,8 +20,10 @@
package org.openecomp.policy.drools.server.restful;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.regex.Pattern;
@@ -64,69 +66,112 @@ import org.openecomp.policy.drools.protocol.configuration.PdpdConfiguration;
import org.openecomp.policy.drools.system.PolicyController;
import org.openecomp.policy.drools.system.PolicyEngine;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Info;
+import io.swagger.annotations.SwaggerDefinition;
+import io.swagger.annotations.Tag;
+
/**
- * REST Endpoint for management of the Drools PDP
+ * Telemetry JAX-RS Interface to the PDP-D
*/
+
@Path("/policy/pdp")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@Api
+@SwaggerDefinition(
+ info = @Info(
+ description = "PDP-D Telemetry Services",
+ version = "v1.0",
+ title = "PDP-D Telemetry"
+ ),
+ consumes = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN},
+ produces = {MediaType.APPLICATION_JSON},
+ schemes = {SwaggerDefinition.Scheme.HTTP},
+ tags = {
+ @Tag(name = "pdp-d-telemetry", description = "Drools PDP Telemetry Operations")
+ }
+)
public class RestManager {
/**
* Logger
*/
private static Logger logger = FlexLogger.getLogger(RestManager.class);
- /**
- * gets the Policy Engine
- *
- * @return the Policy Engine
- */
@GET
@Path("engine")
- @Produces(MediaType.APPLICATION_JSON)
- public PolicyEngine engine() {
- return PolicyEngine.manager;
+ @ApiOperation(
+ value="Retrieves the Engine Operational Status",
+ notes="Top-level abstraction. Provides a global view of resources",
+ response=PolicyEngine.class
+ )
+ public Response engine() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
}
-
- /**
- * Updates the Policy Engine
- *
- * @param configuration configuration
- * @return Policy Engine
- */
- @PUT
+ @DELETE
@Path("engine")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response updateEngine(PdpdConfiguration configuration) {
- PolicyController controller = null;
- boolean success = true;
- try {
- success = PolicyEngine.manager.configure(configuration);
- } catch (Exception e) {
- success = false;
+ @ApiOperation(
+ value="Shuts down the Engine",
+ notes="Deleting the engine, the top-level abstraction, equivalenty shuts it down",
+ response=PolicyEngine.class
+ )
+ public Response engineShutdown() {
+ try {
+ PolicyEngine.manager.shutdown();
+ } catch (IllegalStateException e) {
logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- "PolicyEngine", this.toString());
+ "shutdown: " + PolicyEngine.manager);
+ return Response.status(Response.Status.BAD_REQUEST).
+ entity(PolicyEngine.manager).
+ build();
}
- if (!success)
- return Response.status(Response.Status.NOT_ACCEPTABLE).
- entity(new Error("cannot perform operation")).build();
- else
- return Response.status(Response.Status.OK).entity(controller).build();
+ return Response.status(Response.Status.OK).
+ entity(PolicyEngine.manager).
+ build();
}
-
+
@GET
@Path("engine/features")
- @Produces(MediaType.APPLICATION_JSON)
- public List<PolicyEngineFeatureAPI> engineFeatures() {
- return PolicyEngine.manager.getFeatureProviders();
+ @ApiOperation(
+ value="Engine Features",
+ notes="Provides the list of loaded features using the PolicyEngineFeatureAPI",
+ responseContainer="List"
+ )
+ public Response engineFeatures() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatures()).build();
}
@GET
+ @Path("engine/features/inventory")
+ @ApiOperation(
+ value="Engine Detailed Feature Inventory",
+ notes="Provides detailed list of loaded features using the PolicyEngineFeatureAPI",
+ responseContainer="List",
+ response=PolicyEngineFeatureAPI.class
+ )
+ public Response engineFeaturesInventory() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatureProviders()).build();
+ }
+
+ @GET
@Path("engine/features/{featureName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response engineFeature(@PathParam("featureName") String featureName) {
+ @ApiOperation(
+ value="Engine Feature",
+ notes="Provides Details for a given feature Engine Provider",
+ response=PolicyEngineFeatureAPI.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message = "The feature cannot be found")
+ })
+ public Response engineFeature(@ApiParam(value="Feature Name", required=true)
+ @PathParam("featureName") String featureName) {
try {
return Response.status(Response.Status.OK).
entity(PolicyEngine.manager.getFeatureProvider(featureName)).build();
@@ -137,25 +182,33 @@ public class RestManager {
}
@GET
- @Path("engine/properties")
- @Produces(MediaType.APPLICATION_JSON)
- public Properties engineProperties() {
- return PolicyEngine.manager.getProperties();
+ @Path("engine/inputs")
+ @ApiOperation(
+ value="Engine Input Ports",
+ notes="List of input ports",
+ responseContainer="List"
+ )
+ public Response engineInputs() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Inputs.values())).
+ build();
}
- /**
- * Activates the Policy Engine
- *
- * @param configuration configuration
- * @return Policy Engine
- */
- @PUT
- @Path("engine/activation")
- @Produces(MediaType.APPLICATION_JSON)
- public Response activateEngine() {
+ @POST
+ @Path("engine/inputs/configuration")
+ @ApiOperation(
+ value="Engine Input Configuration Requests",
+ notes="Feeds a configuration request input into the Engine"
+ )
+ @ApiResponses(value={
+ @ApiResponse(code=406, message = "The configuration request cannot be honored")
+ })
+ public Response engineUpdate(
+ @ApiParam(value="Configuration to apply", required=true) PdpdConfiguration configuration) {
+ PolicyController controller = null;
boolean success = true;
try {
- PolicyEngine.manager.activate();
+ success = PolicyEngine.manager.configure(configuration);
} catch (Exception e) {
success = false;
logger.warn(MessageCodes.EXCEPTION_ERROR, e,
@@ -166,22 +219,45 @@ public class RestManager {
return Response.status(Response.Status.NOT_ACCEPTABLE).
entity(new Error("cannot perform operation")).build();
else
- return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
+ return Response.status(Response.Status.OK).entity(controller).build();
+ }
+
+ @GET
+ @Path("engine/properties")
+ @ApiOperation(
+ value="Engine Configuration Properties",
+ notes="Used for booststrapping the engine",
+ response=Properties.class
+ )
+ public Response engineProperties() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getProperties()).build();
+ }
+
+ @GET
+ @Path("engine/switches")
+ @ApiOperation(
+ value="Engine Control Switches",
+ notes="List of the Engine Control Switches",
+ responseContainer="List"
+ )
+ public Response engineSwitches() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Switches.values())).
+ build();
}
- /**
- * Activates the Policy Engine
- *
- * @param configuration configuration
- * @return Policy Engine
- */
@PUT
- @Path("engine/deactivation")
- @Produces(MediaType.APPLICATION_JSON)
- public Response deactivateEngine() {
+ @Path("engine/switches/activation")
+ @ApiOperation(
+ value="Switches on the Engine Activation Switch",
+ notes="Turns on Activation Switch on the Engine. This order entails that the engine " +
+ "and controllers are unlocked and started",
+ response=PolicyEngine.class
+ )
+ public Response engineActivation() {
boolean success = true;
try {
- PolicyEngine.manager.deactivate();
+ PolicyEngine.manager.activate();
} catch (Exception e) {
success = false;
logger.warn(MessageCodes.EXCEPTION_ERROR, e,
@@ -196,68 +272,117 @@ public class RestManager {
}
@DELETE
- @Path("engine")
- @Produces(MediaType.APPLICATION_JSON)
- public Response engineShutdown() {
- try {
- PolicyEngine.manager.shutdown();
- } catch (IllegalStateException e) {
+ @Path("engine/switches/activation")
+ @ApiOperation(
+ value="Switches off Engine Activation Switch",
+ notes="Turns off the Activation Switch on the Engine. This order entails that the engine " +
+ "and controllers are locked (with the exception of those resources defined as unmanaged)",
+ response=PolicyEngine.class
+ )
+ public Response engineDeactivation() {
+ boolean success = true;
+ try {
+ PolicyEngine.manager.deactivate();
+ } catch (Exception e) {
+ success = false;
logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- "shutdown: " + PolicyEngine.manager);
- return Response.status(Response.Status.BAD_REQUEST).
- entity(PolicyEngine.manager).
- build();
+ "PolicyEngine", this.toString());
}
- return Response.status(Response.Status.OK).
- entity(PolicyEngine.manager).
- build();
- }
+ if (!success)
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation")).build();
+ else
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
+ }
@PUT
- @Path("engine/lock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response lockEngine() {
+ @Path("engine/switches/lock")
+ @ApiOperation(
+ value="Switches on the Engine Lock Control",
+ notes="This switch locks all the engine resources as a whole, except those that are defined unmanaged",
+ response=PolicyEngine.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response engineLock() {
boolean success = PolicyEngine.manager.lock();
if (success)
return Response.status(Status.OK).
- entity("Policy Engine is locked").
+ entity(PolicyEngine.manager).
build();
else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Policy Engine cannot be locked").
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation")).
build();
}
@DELETE
- @Path("engine/unlock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response unlockEngine() {
+ @Path("engine/switches/lock")
+ @ApiOperation(
+ value="Switches off the Lock control",
+ notes="This switch locks all the engine resources as a whole, except those that are defined unmanaged",
+ response=PolicyEngine.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response engineUnlock() {
boolean success = PolicyEngine.manager.unlock();
if (success)
return Response.status(Status.OK).
- entity("Policy Engine is unlocked").
+ entity(PolicyEngine.manager).
build();
else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Policy Engine cannot be unlocked").
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation")).
build();
}
@GET
@Path("engine/controllers")
- @Produces(MediaType.APPLICATION_JSON)
- public List<PolicyController> controllers() {
- return PolicyEngine.manager.getPolicyControllers();
+ @ApiOperation(
+ value="Lists the Policy Controllers Names",
+ notes="Unique Policy Controller Identifiers",
+ responseContainer="List"
+ )
+ public Response controllers() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getPolicyControllerIds()).build();
+ }
+
+ @GET
+ @Path("engine/controllers/inventory")
+ @ApiOperation(
+ value="Lists the Policy Controllers",
+ notes="Detailed list of Policy Controllers",
+ responseContainer="List",
+ response=PolicyController.class
+ )
+ public Response controllerInventory() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getPolicyControllers()).build();
}
@POST
@Path("engine/controllers")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response addController(Properties config) {
+ @ApiOperation(
+ value="Creates and starts a new Policy Controller",
+ notes="Controller creation based on properties",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=400, message = "Invalid configuration information has been provided"),
+ @ApiResponse(code=304, message = "The controller already exists"),
+ @ApiResponse(code=406, message = "The administrative state of the system prevents it " +
+ "from processing this request"),
+ @ApiResponse(code=206, message = "The controller has been created " +
+ "but cannot be started"),
+ @ApiResponse(code=201, message = "The controller has been succesfully created and started")
+ })
+ public Response controllerAdd(@ApiParam(value="Configuration Properties to apply", required = true)
+ Properties config) {
if (config == null)
return Response.status(Response.Status.BAD_REQUEST).
entity(new Error("A configuration must be provided")).
@@ -315,20 +440,45 @@ public class RestManager {
return Response.status(Response.Status.CREATED).
entity(controller).
build();
- }
+ }
@GET
@Path("engine/controllers/features")
- @Produces(MediaType.APPLICATION_JSON)
- public List<PolicyControllerFeatureAPI> controllerFeatures() {
- return PolicyController.factory.getFeatureProviders();
+ @ApiOperation(
+ value="Lists of Feature Providers Identifiers",
+ notes="Unique Policy Controller Identifiers",
+ responseContainer="List"
+ )
+ public Response controllerFeatures() {
+ return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatures()).build();
+ }
+
+ @GET
+ @Path("engine/controllers/features/inventory")
+ @ApiOperation(
+ value="Detailed Controllers Feature Inventory",
+ notes="Provides detailed list of loaded features using the PolicyControllerFeatureAPI",
+ responseContainer="List",
+ response=PolicyControllerFeatureAPI.class
+ )
+ public Response controllerFeaturesInventory() {
+ return Response.status(Response.Status.OK).
+ entity(PolicyController.factory.getFeatureProviders()).
+ build();
}
@GET
@Path("engine/controllers/features/{featureName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response controllerFeature(@PathParam("controllerName") String controllerName,
- @PathParam("featureName") String featureName) {
+ @ApiOperation(
+ value="Controller Feature",
+ notes="Provides Details for a given Policy Controller feature provider",
+ response=PolicyControllerFeatureAPI.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message = "The feature cannot be found")
+ })
+ public Response controllerFeature(@ApiParam(value="Feature Name", required=true)
+ @PathParam("featureName") String featureName) {
try {
return Response.status(Response.Status.OK).
entity(PolicyController.factory.getFeatureProvider(featureName)).
@@ -340,9 +490,21 @@ public class RestManager {
}
@GET
- @Path("engine/controllers/{controllerName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response controller(@PathParam("controllerName") String controllerName) {
+ @Path("engine/controllers/{controller}")
+ @ApiOperation(
+ value="Retrieves a Policy Controller",
+ notes="A Policy Controller is a concrete drools application abstraction. " +
+ "It aggregates networking, drools, and other resources," +
+ "as provides operational controls over drools applications",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response controller(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
try {
return Response.status(Response.Status.OK).
entity(PolicyController.factory.get(controllerName)).
@@ -355,46 +517,26 @@ public class RestManager {
return Response.status(Response.Status.NOT_ACCEPTABLE).
entity(new Error(controllerName + " not acceptable")).
build();
- } catch (Exception e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
- entity(new Error(controllerName + " not acceptable")).
- build();
- }
- }
- @GET
- @Path("engine/controllers/{controllerName}/properties")
- @Produces(MediaType.APPLICATION_JSON)
- public Response controllerProperties(@PathParam("controllerName") String controllerName) {
- try {
- PolicyController controller = PolicyController.factory.get(controllerName);
- return Response.status(Response.Status.OK).
- entity(controller.getProperties()).
- build();
- } catch (IllegalArgumentException e) {
- return Response.status(Response.Status.NOT_FOUND).
- entity(new Error(controllerName + " not found")).
- build();
- } catch (IllegalStateException e) {
- return Response.status(Response.Status.NOT_ACCEPTABLE).
- entity(new Error(controllerName + " not acceptable")).
- build();
- } catch (Exception e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
- entity(new Error(controllerName + " not acceptable")).
- build();
}
}
@DELETE
- @Path("engine/controllers/{controllerName}")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response deleteController(@PathParam("controllerName") String controllerName) {
-
- if (controllerName == null || controllerName.isEmpty())
- return Response.status(Response.Status.BAD_REQUEST).
- entity("A controller name must be provided").
- build();
+ @Path("engine/controllers/{controller}")
+ @ApiOperation(
+ value="Deletes a Policy Controller",
+ notes="A Policy Controller is a concrete drools application abstraction. " +
+ "It aggregates networking, drools, and other resources," +
+ "as provides operational controls over drools applications",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A problem has occurred while deleting the Policy Controller")
+ })
+ public Response controllerDelete(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
PolicyController controller;
try {
@@ -432,17 +574,62 @@ public class RestManager {
build();
}
- /**
- * Updates the Policy Engine
- *
- * @param configuration configuration
- * @return Policy Engine
- */
- @PUT
- @Path("engine/controllers/{controllerName}")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response updateController(@PathParam("controllerName") String controllerName,
+ @GET
+ @Path("engine/controllers/{controller}/properties")
+ @ApiOperation(
+ value="Retrieves the configuration properties of a Policy Controller",
+ notes="Configuration resources used by the controller if Properties format",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response controllerProperties(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
+ try {
+ PolicyController controller = PolicyController.factory.get(controllerName);
+ return Response.status(Response.Status.OK).
+ entity(controller.getProperties()).
+ build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " not acceptable")).
+ build();
+ }
+ }
+
+ @GET
+ @Path("engine/controllers/{controller}/inputs")
+ @ApiOperation(
+ value="Policy Controller Input Ports",
+ notes="List of input ports",
+ responseContainer="List"
+ )
+ public Response controllerInputs() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Inputs.values())).
+ build();
+ }
+
+ @POST
+ @Path("engine/controllers/{controller}/inputs/configuration")
+ @ApiOperation(
+ value="Policy Controller Input Configuration Requests",
+ notes="Feeds a configuration request input into the given Policy Controller"
+ )
+ @ApiResponses(value={
+ @ApiResponse(code=400, message = "The configuration request is invalid"),
+ @ApiResponse(code=406, message = "The configuration request cannot be honored")
+ })
+ public Response controllerUpdate(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Configuration to apply", required=true)
ControllerConfiguration controllerConfiguration) {
if (controllerName == null || controllerName.isEmpty() ||
@@ -478,85 +665,240 @@ public class RestManager {
}
@GET
- @Path("engine/controllers/{controllerName}/drools")
- @Produces(MediaType.APPLICATION_JSON)
- public Response drools(@PathParam("controllerName") String controllerName) {
+ @Path("engine/controllers/{controller}/switches")
+ @ApiOperation(
+ value="Policy Controller Switches",
+ notes="List of the Policy Controller Switches",
+ responseContainer="List"
+ )
+ public Response controllerSwitches() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Switches.values())).
+ build();
+ }
+
+ @PUT
+ @Path("engine/controllers/{controller}/switches/lock")
+ @ApiOperation(
+ value="Switches on the Policy Controller Lock Control",
+ notes="This action on the switch locks the Policy Controller",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response controllerLock(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
+ PolicyController policyController = PolicyController.factory.get(controllerName);
+ boolean success = policyController.lock();
+ if (success)
+ return Response.status(Status.OK).
+ entity(policyController).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("Controller " + controllerName + " cannot be locked")).
+ build();
+ }
+
+ @DELETE
+ @Path("engine/controllers/{controller}/switches/lock")
+ @ApiOperation(
+ value="Switches off the Policy Controller Lock Control",
+ notes="This action on the switch unlocks the Policy Controller",
+ response=PolicyController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response controllerUnlock(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
+ PolicyController policyController = PolicyController.factory.get(controllerName);
+ boolean success = policyController.unlock();
+ if (success)
+ return Response.status(Status.OK).
+ entity(policyController).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("Controller " + controllerName + " cannot be unlocked")).
+ build();
+ }
+
+ @GET
+ @Path("engine/controllers/{controller}/drools")
+ @ApiOperation(
+ value="Retrieves the Drools Controller subcomponent of the Policy Controller",
+ notes="The Drools Controller provides an abstraction over the Drools subsystem",
+ response=DroolsController.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response drools(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
try {
DroolsController drools = getDroolsController(controllerName);
return Response.status(Response.Status.OK).
entity(drools).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count,
- @PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName) {
+ @Path("engine/controllers/{controller}/drools/facts")
+ @ApiOperation(
+ value="Retrieves Facts Summary information for a given controller",
+ notes="Provides the session names, and a count of fact object in the drools working memory",
+ responseContainer="Map"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
try {
+ Map<String,Long> sessionCounts = new HashMap<>();
DroolsController drools = getDroolsController(controllerName);
- if (!count)
- return Response.status(Response.Status.OK).
- entity(drools.factClassNames(sessionName)).
- build();
- else
- return Response.status(Response.Status.OK).
- entity(new Long(drools.factCount(sessionName))).
- build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ for (String session : drools.getSessionNames()) {
+ sessionCounts.put(session, drools.factCount(session));
+ }
+ return Response.status(Response.Status.OK).
+ entity(sessionCounts).
+ build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{className}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count,
- @PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName,
- @PathParam("className") String className) {
+ @Path("engine/controllers/{controller}/drools/facts/{session}")
+ @ApiOperation(
+ value="Retrieves Fact Types (classnames) for a given controller and its count",
+ notes="The fact types are the classnames of the objects inserted in the drools working memory",
+ responseContainer="Map"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller or session cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName) {
try {
DroolsController drools = getDroolsController(controllerName);
- List<Object> facts = drools.facts(sessionName, className, false);
+ return Response.status(Response.Status.OK).
+ entity(drools.factClassNames(sessionName)).
+ build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error("entity not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + " not acceptable")).
+ build();
+ }
+ }
+
+ @GET
+ @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
+ @ApiOperation(
+ value="Retrieves fact objects of a given type in the drools working memory" +
+ "for a given controller and session",
+ notes="The fact types are the classnames of the objects inserted in the drools working memory",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, session, or fact type cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response droolsFacts(@ApiParam(value="Fact count", required=false)
+ @DefaultValue("false") @QueryParam("count") boolean count,
+ @ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName,
+ @ApiParam(value="Drools Fact Type", required=true)
+ @PathParam("factType") String factType) {
+ try {
+ DroolsController drools = getDroolsController(controllerName);
+ List<Object> facts = drools.facts(sessionName, factType, false);
if (!count)
return Response.status(Response.Status.OK).entity(facts).build();
else
return Response.status(Response.Status.OK).entity(facts.size()).build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + sessionName + ":" + factType +
+ " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + ":" + factType +
+ " not acceptable")).
+ build();
}
}
@DELETE
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{className}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response deleteDroolsFacts(@PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName,
- @PathParam("className") String className) {
+ @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
+ @ApiOperation(
+ value="Deletes all the fact objects of a given type from the drools working memory" +
+ "for a given controller and session. The objects retracted from the working " +
+ "memory are provided in the response.",
+ notes="The fact types are the classnames of the objects inserted in the drools working memory",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, session, or fact type, cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response droolsFactsDelete(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName,
+ @ApiParam(value="Drools Fact Type", required=true)
+ @PathParam("factType") String factType) {
try {
DroolsController drools = getDroolsController(controllerName);
- List<Object> facts = drools.facts(sessionName, className, true);
+ List<Object> facts = drools.facts(sessionName, factType, true);
return Response.status(Response.Status.OK).entity(facts).build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + sessionName + ":" + factType +
+ " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + ":" + factType +
+ " not acceptable")).
+ build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
entity(new Error(e.getMessage())).
@@ -565,12 +907,28 @@ public class RestManager {
}
@GET
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{queryName}/{queriedEntity}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count,
- @PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName,
- @PathParam("queryName") String queryName,
+ @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
+ @ApiOperation(
+ value="Gets all the fact objects returned by a DRL query with no parameters from the drools working memory" +
+ "for a given controller and session",
+ notes="The DRL query must be defined in the DRL file",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response droolsFacts(@ApiParam(value="Fact count", required=false)
+ @DefaultValue("false") @QueryParam("count") boolean count,
+ @ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName,
+ @ApiParam(value="Query Name Present in DRL", required=true)
+ @PathParam("query") String queryName,
+ @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
@PathParam("queriedEntity") String queriedEntity) {
try {
DroolsController drools = getDroolsController(controllerName);
@@ -579,10 +937,16 @@ public class RestManager {
return Response.status(Response.Status.OK).entity(facts).build();
else
return Response.status(Response.Status.OK).entity(facts.size()).build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not acceptable")).
+ build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
entity(new Error(e.getMessage())).
@@ -590,14 +954,30 @@ public class RestManager {
}
}
- @PUT
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{queryName}/{queriedEntity}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response droolsFacts(@PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName,
- @PathParam("queryName") String queryName,
+ @POST
+ @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
+ @ApiOperation(
+ value="Gets all the fact objects returned by a DRL query with parameters from the drools working memory" +
+ "for a given controller and session",
+ notes="The DRL query with parameters must be defined in the DRL file",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName,
+ @ApiParam(value="Query Name Present in DRL", required=true)
+ @PathParam("query") String queryName,
+ @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
@PathParam("queriedEntity") String queriedEntity,
- List<Object> queryParameters) {
+ @ApiParam(value="Query Parameter Values to pass in the DRL Query", required=false)
+ List<Object> queryParameters) {
try {
DroolsController drools = getDroolsController(controllerName);
List<Object> facts;
@@ -606,10 +986,16 @@ public class RestManager {
else
facts = drools.factQuery(sessionName, queryName, queriedEntity, false, queryParameters.toArray());
return Response.status(Response.Status.OK).entity(facts).build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not acceptable")).
+ build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
entity(new Error(e.getMessage())).
@@ -618,13 +1004,29 @@ public class RestManager {
}
@DELETE
- @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{queryName}/{queriedEntity}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response deleteDroolsFacts(@PathParam("controllerName") String controllerName,
- @PathParam("sessionName") String sessionName,
- @PathParam("queryName") String queryName,
- @PathParam("queriedEntity") String queriedEntity,
- List<Object> queryParameters) {
+ @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
+ @ApiOperation(
+ value="Deletes all the fact objects returned by a DRL query with parameters from the drools working memory" +
+ "for a given controller and session",
+ notes="The DRL query with parameters must be defined in the DRL file",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response droolsFactsDelete(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Drools Session Name", required=true)
+ @PathParam("session") String sessionName,
+ @ApiParam(value="Query Name Present in DRL", required=true)
+ @PathParam("query") String queryName,
+ @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
+ @PathParam("queriedEntity") String queriedEntity,
+ @ApiParam(value="Query Parameter Values to pass in the DRL Query", required=false)
+ List<Object> queryParameters) {
try {
DroolsController drools = getDroolsController(controllerName);
List<Object> facts;
@@ -633,10 +1035,16 @@ public class RestManager {
else
facts = drools.factQuery(sessionName, queryName, queriedEntity, true, queryParameters.toArray());
return Response.status(Response.Status.OK).entity(facts).build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + sessionName + ":" + queryName +
+ queriedEntity + " not acceptable")).
+ build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
entity(new Error(e.getMessage())).
@@ -644,10 +1052,45 @@ public class RestManager {
}
}
+ @POST
+ @Path("engine/controllers/tools/coders/decoders/filters/rules/{ruleName}")
+ @ApiOperation(
+ value="Produces a Decoder Rule Filter in a format that the Policy Controller can understand",
+ notes="The result can be used with other APIs to attach a filter to a decoder"
+ )
+ public Response rules(@ApiParam(value="Negate regex?", required=true)
+ @DefaultValue("false") @QueryParam("negate") boolean negate,
+ @ApiParam(value="Rule Name", required=true)
+ @PathParam("ruleName") String name,
+ @ApiParam(value="Regex expression", required=true)
+ String regex) {
+ String literalRegex = Pattern.quote(regex);
+ if (negate)
+ literalRegex = "^(?!" + literalRegex + "$).*";
+
+ return Response.status(Status.OK).
+ entity(new JsonProtocolFilter.FilterRule(name,literalRegex)).
+ build();
+ }
+
@GET
- @Path("engine/controllers/{controllerName}/decoders")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoders(@PathParam("controllerName") String controllerName) {
+ @Path("engine/controllers/{controller}/decoders")
+ @ApiOperation(
+ value="Gets all the decoders used by a controller",
+ notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
+ "subscribed network topics into specific (fact) objects. " +
+ "The deserialized (fact) object will typically be inserted in the drools working " +
+ " memory of the controlled drools application.",
+ responseContainer="List",
+ response=ProtocolCoderToolset.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoders(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
try {
DroolsController drools = getDroolsController(controllerName);
List<ProtocolCoderToolset> decoders = EventProtocolCoder.manager.getDecoders
@@ -655,117 +1098,210 @@ public class RestManager {
return Response.status(Response.Status.OK).
entity(decoders).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/filters")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilters(@PathParam("controllerName") String controllerName) {
+ @Path("engine/controllers/{controller}/decoders/filters")
+ @ApiOperation(
+ value="Gets all the filters used by a controller",
+ notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
+ "subscribed network topics into specific (fact) objects. " +
+ "The deserialized (fact) object will typically be inserted in the drools working " +
+ " memory of the controlled drools application." +
+ "Acceptance filters are used to filter out undesired network messages for the given controller",
+ responseContainer="List",
+ response=CoderFilters.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilters(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
try {
DroolsController drools = getDroolsController(controllerName);
List<CoderFilters> filters = EventProtocolCoder.manager.getDecoderFilters
- (drools.getGroupId(), drools.getArtifactId());
+ (drools.getGroupId(), drools.getArtifactId());
return Response.status(Response.Status.OK).
entity(filters).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/{topicName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoder(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName) {
+ @Path("engine/controllers/{controller}/decoders/{topic}")
+ @ApiOperation(
+ value="Gets all the decoders in use by a controller for a networked topic",
+ notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
+ "subscribed network topics into specific (fact) objects. " +
+ "The deserialized (fact) object will typically be inserted in the drools working " +
+ " memory of the controlled drools application.",
+ responseContainer="List",
+ response=ProtocolCoderToolset.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller or topic cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoder(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Networked Topic Name", required=true)
+ @PathParam("topic") String topic) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
return Response.status(Response.Status.OK).
entity(decoder).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilter(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters")
+ @ApiOperation(
+ value="Gets all filters attached to decoders for a given networked topic in use by a controller",
+ notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
+ "subscribed network topics into specific (fact) objects. " +
+ "The deserialized (fact) object will typically be inserted in the drools working " +
+ " memory of the controlled drools application." +
+ "Acceptance filters are used to filter out undesired network messages for the given controller",
+ responseContainer="List",
+ response=CoderFilters.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller or topic cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Networked Topic Name", required=true)
+ @PathParam("topic") String topic) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
if (decoder == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(topicName + " does not exist")).
+ entity(new Error(topic + " does not exist")).
build();
else
return Response.status(Response.Status.OK).
entity(decoder.getCoders()).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilter(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
+ @ApiOperation(
+ value="Gets all filters attached to decoders for a given subscribed networked topic " +
+ "and fact type",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type (classname).",
+ responseContainer="List",
+ response=CoderFilters.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Networked Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(topicName + ":" + factClass + " does not exist")).
+ entity(new Error(topic + ":" + factClass + " does not exist")).
build();
else
return Response.status(Response.Status.OK).
entity(filters).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not acceptable")).
+ build();
}
}
- @POST
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilter(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass,
+ @PUT
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
+ @ApiOperation(
+ value="Attaches filters to the decoder for a given networked topic " +
+ "and fact type",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type (classname).",
+ responseContainer="List",
+ response=CoderFilters.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, fact type, cannot be found, " +
+ "or a filter has not been provided"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass,
+ @ApiParam(value="Configuration Filter", required=true)
JsonProtocolFilter configFilters) {
if (configFilters == null) {
@@ -777,121 +1313,183 @@ public class RestManager {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(topicName + ":" + factClass + " does not exist")).
+ entity(new Error(topic + ":" + factClass + " does not exist")).
build();
filters.setFilter(configFilters);
return Response.status(Response.Status.OK).
entity(filters).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilterRules(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules")
+ @ApiOperation(
+ value="Gets the filter rules attached to a topic decoder of a controller",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type and are composed of field matching rules. ",
+ responseContainer="List",
+ response=FilterRule.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilterRules(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " does not exist")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " does not exist")).
build();
JsonProtocolFilter filter = filters.getFilter();
if (filter == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " no filters")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).
build();
return Response.status(Response.Status.OK).
entity(filter.getRules()).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not acceptable")).
+ build();
}
}
@GET
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules/{ruleName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilterRules(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass,
- @PathParam("ruleName") String ruleName) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}")
+ @ApiOperation(
+ value="Gets a filter rule by name attached to a topic decoder of a controller",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type and are composed of field matching rules. ",
+ responseContainer="List",
+ response=FilterRule.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, fact type, or rule name cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilterRules(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass,
+ @ApiParam(value="Rule Name", required=true)
+ @PathParam("ruleName") String ruleName) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " does not exist")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " does not exist")).
build();
JsonProtocolFilter filter = filters.getFilter();
if (filter == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " no filters")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).
build();
return Response.status(Response.Status.OK).
entity(filter.getRules(ruleName)).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + ": " + ruleName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + ":" + ruleName + " not acceptable")).
+ build();
}
}
@DELETE
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules/{ruleName}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response deleteDecoderFilterRule(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass,
- @PathParam("ruleName") String ruleName,
- FilterRule rule) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}")
+ @ApiOperation(
+ value="Deletes a filter rule by name attached to a topic decoder of a controller",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type and are composed of field matching rules. ",
+ responseContainer="List",
+ response=FilterRule.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, fact type, or rule name cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilterRuleDelete(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass,
+ @ApiParam(value="Rule Name", required=true)
+ @PathParam("ruleName") String ruleName,
+ @ApiParam(value="Filter Rule", required=true)
+ FilterRule rule) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " does not exist")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " does not exist")).
build();
JsonProtocolFilter filter = filters.getFilter();
if (filter == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " no filters")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).
build();
if (rule == null) {
@@ -903,7 +1501,7 @@ public class RestManager {
if (rule.getName() == null || !rule.getName().equals(ruleName))
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + ":" + ruleName +
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + ":" + ruleName +
" rule name request inconsistencies (" + rule.getName() + ")")).
build();
@@ -911,43 +1509,66 @@ public class RestManager {
return Response.status(Response.Status.OK).
entity(filter.getRules()).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + ": " + ruleName + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + ":" + ruleName + " not acceptable")).
+ build();
}
}
@PUT
- @Path("engine/controllers/{controllerName}/decoders/{topicName}/filters/{factClassName}/rules")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decoderFilterRule(@PathParam("controllerName") String controllerName,
- @PathParam("topicName") String topicName,
- @PathParam("factClassName") String factClass,
- JsonProtocolFilter.FilterRule rule) {
+ @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules")
+ @ApiOperation(
+ value="Places a new filter rule in a topic decoder",
+ notes="Decoders are associated with networked topics. A Policy Controller manages " +
+ "multiple topics and therefore its attached decoders. " +
+ "A Policy Controller uses filters to further specify the fact mapping. " +
+ "Filters are applied on a per fact type and are composed of field matching rules. ",
+ responseContainer="List",
+ response=FilterRule.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decoderFilterRule(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Fact Type", required=true)
+ @PathParam("factType") String factClass,
+ @ApiParam(value="Rule Name", required=true)
+ @PathParam("ruleName") String ruleName,
+ @ApiParam(value="Filter Rule", required=true)
+ FilterRule rule) {
try {
DroolsController drools = getDroolsController(controllerName);
ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
- (drools.getGroupId(), drools.getArtifactId(), topicName);
+ (drools.getGroupId(), drools.getArtifactId(), topic);
CoderFilters filters = decoder.getCoder(factClass);
if (filters == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " does not exist")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " does not exist")).
build();
JsonProtocolFilter filter = filters.getFilter();
if (filter == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass + " no filters")).
+ entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).
build();
if (rule.getName() == null)
return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + ":" + topicName + ":" + factClass +
+ entity(new Error(controllerName + ":" + topic + ":" + factClass +
" rule name request inconsistencies (" + rule.getName() + ")")).
build();
@@ -955,59 +1576,54 @@ public class RestManager {
return Response.status(Response.Status.OK).
entity(filter.getRules()).
build();
- } catch (IllegalArgumentException | IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
- }
- }
-
- @GET
- @Path("engine/controllers/{controllerName}/encoders")
- @Produces(MediaType.APPLICATION_JSON)
- public Response encoderFilters(@PathParam("controllerName") String controllerName) {
- List<CoderFilters> encoders;
- try {
- PolicyController controller = PolicyController.factory.get(controllerName);
- if (controller == null)
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + " does not exist")).
- build();
- DroolsController drools = controller.getDrools();
- if (drools == null)
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
- entity(new Error(controllerName + " has not drools component")).
- build();
- encoders = EventProtocolCoder.manager.getEncoderFilters
- (drools.getGroupId(), drools.getArtifactId());
} catch (IllegalArgumentException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(controllerName + " not found: " + e.getMessage())).
- build();
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not found")).
+ build();
} catch (IllegalStateException e) {
- logger.warn(MessageCodes.EXCEPTION_ERROR, e,
- controllerName, this.toString());
return Response.status(Response.Status.NOT_ACCEPTABLE).
- entity(new Error(controllerName + " is not accepting the request")).build();
+ entity(new Error(controllerName + ":" + topic + ":" +
+ factClass + " not acceptable")).
+ build();
}
-
- return Response.status(Response.Status.OK).
- entity(encoders).
- build();
}
@POST
- @Path("engine/controllers/{controllerName}/decoders/{topic}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response decode(@PathParam("controllerName") String controllerName,
- @PathParam("topic") String topic,
- String json) {
+ @Path("engine/controllers/{controller}/decoders/{topic}")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @ApiOperation(
+ value="Decodes a string into a fact object, and encodes it back into a string",
+ notes="Tests the decode/encode functions of a controller",
+ response=CodingResult.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=400, message="Bad input has been provided"),
+ @ApiResponse(code=404, message="The controller cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response decode(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName,
+ @ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="JSON String to decode", required=true)
+ String json) {
- PolicyController policyController = PolicyController.factory.get(controllerName);
+ PolicyController policyController;
+ try {
+ policyController = PolicyController.factory.get(controllerName);
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + ":" + topic + ":" +
+ " not acceptable")).
+ build();
+ }
CodingResult result = new CodingResult();
result.decoding = false;
@@ -1032,9 +1648,7 @@ public class RestManager {
result.jsonEncoding = EventProtocolCoder.manager.encode(topic, event);
result.encoding = true;
} catch (Exception e) {
- return Response.status(Response.Status.OK).
- entity(result).
- build();
+ // continue so to propagate decoding results ..
}
return Response.status(Response.Status.OK).
@@ -1042,318 +1656,526 @@ public class RestManager {
build();
}
+ @GET
+ @Path("engine/controllers/{controller}/encoders")
+ @ApiOperation(
+ value="Retrieves the encoder filters of a controller",
+ notes="The encoders serializes a fact object, typically for network transmission",
+ responseContainer="List",
+ response=CoderFilters.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=400, message="Bad input has been provided"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response encoderFilters(@ApiParam(value="Policy Controller Name", required=true)
+ @PathParam("controller") String controllerName) {
+ List<CoderFilters> encoders;
+ try {
+ PolicyController controller = PolicyController.factory.get(controllerName);
+ DroolsController drools = controller.getDrools();
+ encoders = EventProtocolCoder.manager.getEncoderFilters
+ (drools.getGroupId(), drools.getArtifactId());
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.BAD_REQUEST).
+ entity(new Error(controllerName + " not found: " + e.getMessage())).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(controllerName + " is not accepting the request")).build();
+ }
+
+ return Response.status(Response.Status.OK).
+ entity(encoders).
+ build();
+ }
+
@GET
@Path("engine/topics")
- @Produces(MediaType.APPLICATION_JSON)
- public TopicEndpoint topics() {
- return TopicEndpoint.manager;
+ @ApiOperation(
+ value="Retrieves the managed topics",
+ notes="Network Topics Aggregation",
+ response=TopicEndpoint.class
+ )
+ public Response topics() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager).
+ build();
}
+
+ @GET
+ @Path("engine/topics/switches")
+ @ApiOperation(
+ value="Topics Control Switches",
+ notes="List of the Topic Control Switches",
+ responseContainer="List"
+ )
+ public Response topicSwitches() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Switches.values())).
+ build();
+ }
+
+ @PUT
+ @Path("engine/topics/switches/lock")
+ @ApiOperation(
+ value="Locks all the managed topics",
+ notes="The operation affects all managed sources and sinks",
+ response=TopicEndpoint.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response topicsLock() {
+ boolean success = TopicEndpoint.manager.lock();
+ if (success)
+ return Response.status(Status.OK).
+ entity(TopicEndpoint.manager).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation")).
+ build();
+ }
+
+ @DELETE
+ @Path("engine/topics/switches/lock")
+ @ApiOperation(
+ value="Unlocks all the managed topics",
+ notes="The operation affects all managed sources and sinks",
+ response=TopicEndpoint.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response topicsUnlock() {
+ boolean success = TopicEndpoint.manager.unlock();
+ if (success)
+ return Response.status(Status.OK).
+ entity(TopicEndpoint.manager).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation")).
+ build();
+ }
- @SuppressWarnings("unchecked")
@GET
@Path("engine/topics/sources")
- @Produces(MediaType.APPLICATION_JSON)
- public List<TopicSource> sources() {
- return (List<TopicSource>) TopicEndpoint.manager.getTopicSources();
+ @ApiOperation(
+ value="Retrieves the managed topic sources",
+ notes="Network Topic Sources Agregation",
+ responseContainer="List",
+ response=TopicSource.class
+ )
+ public Response sources() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getTopicSources()).
+ build();
}
- @SuppressWarnings("unchecked")
@GET
@Path("engine/topics/sinks")
- @Produces(MediaType.APPLICATION_JSON)
- public List<TopicSink> sinks() {
- return (List<TopicSink>) TopicEndpoint.manager.getTopicSinks();
+ @ApiOperation(
+ value="Retrieves the managed topic sinks",
+ notes="Network Topic Sinks Agregation",
+ responseContainer="List",
+ response=TopicSink.class
+ )
+ public Response sinks() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getTopicSinks()).
+ build();
}
@GET
@Path("engine/topics/sources/ueb")
- @Produces(MediaType.APPLICATION_JSON)
- public List<UebTopicSource> uebSources() {
- return TopicEndpoint.manager.getUebTopicSources();
+ @ApiOperation(
+ value="Retrieves the UEB managed topic sources",
+ notes="UEB Topic Sources Agregation",
+ responseContainer="List",
+ response=UebTopicSource.class
+ )
+ public Response uebSources() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getUebTopicSources()).
+ build();
}
@GET
@Path("engine/topics/sinks/ueb")
- @Produces(MediaType.APPLICATION_JSON)
- public List<UebTopicSink> uebSinks() {
- return (List<UebTopicSink>) TopicEndpoint.manager.getUebTopicSinks();
+ @ApiOperation(
+ value="Retrieves the UEB managed topic sinks",
+ notes="UEB Topic Sinks Agregation",
+ responseContainer="List",
+ response=UebTopicSource.class
+ )
+ public Response uebSinks() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getUebTopicSinks()).
+ build();
}
@GET
@Path("engine/topics/sources/dmaap")
- @Produces(MediaType.APPLICATION_JSON)
- public List<DmaapTopicSource> dmaapSources() {
- return TopicEndpoint.manager.getDmaapTopicSources();
+ @ApiOperation(
+ value="Retrieves the DMaaP managed topic sources",
+ notes="DMaaP Topic Sources Agregation",
+ responseContainer="List",
+ response=DmaapTopicSource.class
+ )
+ public Response dmaapSources() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getDmaapTopicSources()).
+ build();
}
@GET
@Path("engine/topics/sinks/dmaap")
- @Produces(MediaType.APPLICATION_JSON)
- public List<DmaapTopicSink> dmaapSinks() {
- return (List<DmaapTopicSink>) TopicEndpoint.manager.getDmaapTopicSinks();
- }
-
- @SuppressWarnings("unchecked")
- @GET
- @Path("engine/topics/{topic}/sources")
- @Produces(MediaType.APPLICATION_JSON)
- public List<TopicSource> sourceTopic(@PathParam("topic") String topic) {
- List<String> topics = new ArrayList<String>();
- topics.add(topic);
-
- return (List<TopicSource>) TopicEndpoint.manager.getTopicSources(topics);
+ @ApiOperation(
+ value="Retrieves the DMaaP managed topic sinks",
+ notes="DMaaP Topic Sinks Agregation",
+ responseContainer="List",
+ response=DmaapTopicSink.class
+ )
+ public Response dmaapSinks() {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getDmaapTopicSinks()).
+ build();
}
- @SuppressWarnings("unchecked")
- @GET
- @Path("engine/topics/{topic}/sinks")
- @Produces(MediaType.APPLICATION_JSON)
- public List<TopicSink> sinkTopic(@PathParam("topic") String topic) {
- List<String> topics = new ArrayList<String>();
- topics.add(topic);
-
- return (List<TopicSink>) TopicEndpoint.manager.getTopicSinks(topics);
- }
-
-
@GET
- @Path("engine/topics/{topic}/ueb/source")
- @Produces(MediaType.APPLICATION_JSON)
- public UebTopicSource uebSourceTopic(@PathParam("topic") String topic) {
- return TopicEndpoint.manager.getUebTopicSource(topic);
+ @Path("engine/topics/sources/ueb/{topic}")
+ @ApiOperation(
+ value="Retrieves an UEB managed topic source",
+ notes="This is an UEB Network Communicaton Endpoint source of messages for the Engine",
+ response=UebTopicSource.class
+ )
+ public Response uebSourceTopic(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getUebTopicSource(topic)).
+ build();
}
@GET
- @Path("engine/topics/{topic}/ueb/sink")
- @Produces(MediaType.APPLICATION_JSON)
- public UebTopicSink uebSinkTopic(@PathParam("topic") String topic) {
- return TopicEndpoint.manager.getUebTopicSink(topic);
+ @Path("engine/topics/sinks/ueb/{topic}")
+ @ApiOperation(
+ value="Retrieves an UEB managed topic sink",
+ notes="This is an UEB Network Communicaton Endpoint destination of messages from the Engine",
+ response=UebTopicSink.class
+ )
+ public Response uebSinkTopic(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getUebTopicSink(topic)).
+ build();
}
@GET
- @Path("engine/topics/{topic}/dmaap/source")
- @Produces(MediaType.APPLICATION_JSON)
- public DmaapTopicSource dmaapSourceTopic(@PathParam("topic") String topic) {
- return TopicEndpoint.manager.getDmaapTopicSource(topic);
+ @Path("engine/topics/sources/dmaap/{topic}")
+ @ApiOperation(
+ value="Retrieves a DMaaP managed topic source",
+ notes="This is a DMaaP Network Communicaton Endpoint source of messages for the Engine",
+ response=DmaapTopicSource.class
+ )
+ public Response dmaapSourceTopic(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getDmaapTopicSource(topic)).
+ build();
}
@GET
- @Path("engine/topics/{topic}/dmaap/sink")
- @Produces(MediaType.APPLICATION_JSON)
- public DmaapTopicSink dmaapSinkTopic(@PathParam("topic") String topic) {
- return TopicEndpoint.manager.getDmaapTopicSink(topic);
+ @Path("engine/topics/sinks/dmaap/{topic}")
+ @ApiOperation(
+ value="Retrieves a DMaaP managed topic sink",
+ notes="This is a DMaaP Network Communicaton Endpoint destination of messages from the Engine",
+ response=DmaapTopicSink.class
+ )
+ public Response dmaapSinkTopic(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ return Response.status(Response.Status.OK).
+ entity(TopicEndpoint.manager.getDmaapTopicSink(topic)).
+ build();
}
@GET
- @Path("engine/topics/{topic}/ueb/source/events")
- @Produces(MediaType.APPLICATION_JSON)
- public Response uebSourceEvent(@PathParam("topic") String topicName) {
-
- UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topicName);
- String[] events = uebReader.getRecentEvents();
+ @Path("engine/topics/sources/ueb/{topic}/events")
+ @ApiOperation(
+ value="Retrieves the latest events received by an UEB topic",
+ notes="This is a UEB Network Communicaton Endpoint source of messages for the Engine",
+ responseContainer="List"
+ )
+ public Response uebSourceEvents(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
return Response.status(Status.OK).
- entity(events).
- build();
+ entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSource(topic).getRecentEvents())).
+ build();
}
@GET
- @Path("engine/topics/{topic}/ueb/sink/events")
- @Produces(MediaType.APPLICATION_JSON)
- public Response uebSinkEvent(@PathParam("topic") String topicName) {
-
- UebTopicSink uebSink = TopicEndpoint.manager.getUebTopicSink(topicName);
- String[] events = uebSink.getRecentEvents();
+ @Path("engine/topics/sinks/ueb/{topic}/events")
+ @ApiOperation(
+ value="Retrieves the latest events sent from a topic",
+ notes="This is a UEB Network Communicaton Endpoint sink of messages from the Engine",
+ responseContainer="List"
+ )
+ public Response uebSinkEvents(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
return Response.status(Status.OK).
- entity(events).
- build();
+ entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSink(topic).getRecentEvents())).
+ build();
}
@GET
- @Path("engine/topics/{topic}/dmaap/source/events")
- @Produces(MediaType.APPLICATION_JSON)
- public Response dmaapSourcevent(@PathParam("topic") String topicName) {
-
- DmaapTopicSource uebReader = TopicEndpoint.manager.getDmaapTopicSource(topicName);
- String[] events = uebReader.getRecentEvents();
+ @Path("engine/topics/sources/dmaap/{topic}/events")
+ @ApiOperation(
+ value="Retrieves the latest events received by a DMaaP topic",
+ notes="This is a DMaaP Network Communicaton Endpoint source of messages for the Engine",
+ responseContainer="List"
+ )
+ public Response dmaapSourceEvents(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
return Response.status(Status.OK).
- entity(events).
- build();
+ entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSource(topic).getRecentEvents())).
+ build();
}
- @DELETE
- @Path("engine/topics/lock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response unlockTopics() {
- boolean success = TopicEndpoint.manager.unlock();
- if (success)
- return Response.status(Status.OK).
- entity("Endpoints are unlocked").
- build();
- else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Endpoints cannot be unlocked").
- build();
- }
-
-
- @GET
- @Path("engine/topics/{topic}/dmaap/sink/events")
- @Produces(MediaType.APPLICATION_JSON)
- public Response dmaapSinkEvent(@PathParam("topic") String topicName) {
-
- DmaapTopicSink uebSink = TopicEndpoint.manager.getDmaapTopicSink(topicName);
- String[] events = uebSink.getRecentEvents();
+ @GET
+ @Path("engine/topics/sinks/dmaap/{topic}/events")
+ @ApiOperation(
+ value="Retrieves the latest events send through a DMaaP topic",
+ notes="This is a DMaaP Network Communicaton Endpoint destination of messages from the Engine",
+ responseContainer="List"
+ )
+ public Response dmaapSinkEvents(
+ @PathParam("topic") String topic) {
return Response.status(Status.OK).
- entity(events).
- build();
- }
-
- @PUT
- @Path("engine/topics/{topic}/ueb/sources/events")
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.APPLICATION_JSON)
- public Response uebOffer(@PathParam("topic") String topicName,
- String json) {
- try {
- UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topicName);
- boolean success = uebReader.offer(json);
- if (success)
- return Response.status(Status.OK).
- build();
- else
- return Response.status(Status.NOT_ACCEPTABLE).
- entity(new Error("Failure to inject event over " + topicName)).
- build();
- } catch (Exception e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
- }
+ entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSink(topic).getRecentEvents())).
+ build();
}
- @PUT
- @Path("engine/topics/{topic}/dmaap/sources/events")
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.APPLICATION_JSON)
- public Response dmaapOffer(@PathParam("topic") String topicName,
- String json) {
- try {
- DmaapTopicSource dmaapReader = TopicEndpoint.manager.getDmaapTopicSource(topicName);
- boolean success = dmaapReader.offer(json);
- if (success)
- return Response.status(Status.OK).
- build();
- else
- return Response.status(Status.NOT_ACCEPTABLE).
- entity(new Error("Failure to inject event over " + topicName)).
- build();
- } catch (Exception e) {
- return Response.status(Response.Status.BAD_REQUEST).
- entity(new Error(e.getMessage())).
- build();
- }
+ @GET
+ @Path("engine/topics/sources/ueb/{topic}/switches")
+ @ApiOperation(
+ value="UEB Topic Control Switches",
+ notes="List of the UEB Topic Control Switches",
+ responseContainer="List"
+ )
+ public Response uebTopicSwitches() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Switches.values())).
+ build();
}
@PUT
- @Path("engine/topics/lock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response lockTopics() {
- boolean success = TopicEndpoint.manager.lock();
+ @Path("engine/topics/sources/ueb/{topic}/switches/lock")
+ @ApiOperation(
+ value="Locks an UEB Source topic",
+ response=UebTopicSource.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response uebTopicLock(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ UebTopicSource source = TopicEndpoint.manager.getUebTopicSource(topic);
+ boolean success = source.lock();
if (success)
return Response.status(Status.OK).
- entity("Endpoints are locked").
+ entity(source).
build();
else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Endpoints cannot be locked").
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation on " + topic)).
build();
}
- @PUT
- @Path("engine/topics/{topic}/ueb/sources/lock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response lockTopic(@PathParam("topic") String topicName) {
- UebTopicSource reader = TopicEndpoint.manager.getUebTopicSource(topicName);
- boolean success = reader.lock();
+ @DELETE
+ @Path("engine/topics/sources/ueb/{topic}/switches/lock")
+ @ApiOperation(
+ value="Unlocks an UEB Source topic",
+ response=UebTopicSource.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response uebTopicUnlock(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ UebTopicSource source = TopicEndpoint.manager.getUebTopicSource(topic);
+ boolean success = source.unlock();
if (success)
return Response.status(Status.OK).
- entity("Endpoints are unlocked").
+ entity(source).
build();
else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Endpoints cannot be unlocked").
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation on " + topic)).
build();
}
- @PUT
- @Path("engine/topics/{topic}/ueb/sources/unlock")
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response unlockTopic(@PathParam("topic") String topicName) {
- UebTopicSource reader = TopicEndpoint.manager.getUebTopicSource(topicName);
- boolean success = reader.unlock();
- if (success)
- return Response.status(Status.OK).
- entity("Endpoints are unlocked").
- build();
- else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Endpoints cannot be unlocked").
- build();
+ @GET
+ @Path("engine/topics/sources/dmaap/{topic}/switches")
+ @ApiOperation(
+ value="DMaaP Topic Control Switches",
+ notes="List of the DMaaP Topic Control Switches",
+ responseContainer="List"
+ )
+ public Response dmaapTopicSwitches() {
+ return Response.status(Response.Status.OK).
+ entity(Arrays.asList(Switches.values())).
+ build();
}
@PUT
- @Path("engine/controllers/{controllerName}/lock")
- @Produces(MediaType.APPLICATION_JSON)
- public Response lockController(@PathParam("controllerName") String controllerName) {
- PolicyController policyController = PolicyController.factory.get(controllerName);
- boolean success = policyController.lock();
+ @Path("engine/topics/sources/dmaap/{topic}/switches/lock")
+ @ApiOperation(
+ value="Locks an DMaaP Source topic",
+ response=DmaapTopicSource.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response dmmapTopicLock(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ DmaapTopicSource source = TopicEndpoint.manager.getDmaapTopicSource(topic);
+ boolean success = source.lock();
if (success)
return Response.status(Status.OK).
- entity("Controller " + controllerName + " is now locked").
+ entity(source).
build();
else
- return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Controller " + controllerName + " cannot be locked").
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("cannot perform operation on " + topic)).
build();
- }
+ }
@DELETE
- @Path("engine/controllers/{controllerName}/lock")
- @Produces(MediaType.APPLICATION_JSON)
- public Response unlockController(@PathParam("controllerName") String controllerName) {
- PolicyController policyController = PolicyController.factory.get(controllerName);
- boolean success = policyController.unlock();
+ @Path("engine/topics/sources/dmaap/{topic}/switches/lock")
+ @ApiOperation(
+ value="Unlocks an DMaaP Source topic",
+ response=DmaapTopicSource.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled")
+ })
+ public Response dmaapTopicUnlock(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic) {
+ DmaapTopicSource source = TopicEndpoint.manager.getDmaapTopicSource(topic);
+ boolean success = source.unlock();
if (success)
return Response.status(Status.OK).
- entity("Controller " + controllerName + " is now unlocked").
+ entity(source).
build();
else
return Response.status(Status.SERVICE_UNAVAILABLE).
- entity("Controller " + controllerName + " cannot be unlocked").
+ entity(new Error("cannot perform operation on " + topic)).
build();
}
- @POST
- @Path("engine/util/coders/filters/rules/{ruleName}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response rules(@DefaultValue("false") @QueryParam("negate") boolean negate,
- @PathParam("ruleName") String name,
- String regex) {
- String literalRegex = Pattern.quote(regex);
- if (negate)
- literalRegex = "^(?!" + literalRegex + "$).*";
-
- return Response.status(Status.OK).
- entity(new JsonProtocolFilter.FilterRule(name,literalRegex)).
- build();
+ @PUT
+ @Path("engine/topics/sources/ueb/{topic}/events")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @ApiOperation(
+ value="Offers an event to an UEB topic for internal processing by the engine",
+ notes="The offered event is treated as it was incoming from the network",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The topic information cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response uebOffer(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Network Message", required=true)
+ String json) {
+ try {
+ UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topic);
+ boolean success = uebReader.offer(json);
+ if (success)
+ return Response.status(Status.OK).
+ entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSource(topic).getRecentEvents())).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("Failure to inject event over " + topic)).
+ build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(topic + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(topic + " not acceptable due to current state")).
+ build();
+ } catch (Exception e) {
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+ entity(new Error(e.getMessage())).
+ build();
+ }
+ }
+
+ @PUT
+ @Path("engine/topics/sources/dmaap/{topic}/events")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @ApiOperation(
+ value="Offers an event to a DMaaP topic for internal processing by the engine",
+ notes="The offered event is treated as it was incoming from the network",
+ responseContainer="List"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code=404, message="The topic information cannot be found"),
+ @ApiResponse(code=406, message="The system is an administrative state that prevents " +
+ "this request to be fulfilled"),
+ @ApiResponse(code=500, message="A server error has occurred processing this request")
+ })
+ public Response dmaapOffer(@ApiParam(value="Topic Name", required=true)
+ @PathParam("topic") String topic,
+ @ApiParam(value="Network Message", required=true)
+ String json) {
+ try {
+ DmaapTopicSource dmaapReader = TopicEndpoint.manager.getDmaapTopicSource(topic);
+ boolean success = dmaapReader.offer(json);
+ if (success)
+ return Response.status(Status.OK).
+ entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSource(topic).getRecentEvents())).
+ build();
+ else
+ return Response.status(Status.NOT_ACCEPTABLE).
+ entity(new Error("Failure to inject event over " + topic)).
+ build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.NOT_FOUND).
+ entity(new Error(topic + " not found")).
+ build();
+ } catch (IllegalStateException e) {
+ return Response.status(Response.Status.NOT_ACCEPTABLE).
+ entity(new Error(topic + " not acceptable due to current state")).
+ build();
+ } catch (Exception e) {
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+ entity(new Error(e.getMessage())).
+ build();
+ }
}
@GET
- @Path("engine/util/uuid")
+ @Path("engine/tools/uuid")
+ @ApiOperation(
+ value="Produces an UUID",
+ notes="UUID generation utility"
+ )
+ @Produces(MediaType.TEXT_PLAIN)
public Response uuid() {
return Response.status(Status.OK).
entity(UUID.randomUUID().toString()).
@@ -1381,54 +2203,52 @@ public class RestManager {
/*
* Helper classes for aggregation of results
*/
-
-
- /**
- * Endpoints aggregation Helper class
- */
- public static class Endpoints {
- public List<TopicSource> sources;
- public List<TopicSink> sinks;
-
- public Endpoints(List<TopicSource> sources,
- List<TopicSink> sinks) {
- this.sources = sources;
- this.sinks = sinks;
- }
- }
-
- /**
- * Endpoint Helper Class
- */
- public static class Endpoint {
- public TopicSource source;
- public TopicSink sink;
-
- public Endpoint(TopicSource source,
- TopicSink sink) {
- this.source = source;
- this.sink = sink;
- }
- }
/**
- * Coding (Encoding) Helper class
+ * Coding/Encoding Results Aggregation Helper class
*/
public static class CodingResult {
+ /**
+ * serialized output
+ */
+
public String jsonEncoding;
+ /**
+ * encoding result
+ */
+
public Boolean encoding;
+
+ /**
+ * decoding result
+ */
public Boolean decoding;
}
+ /**
+ * Generic Error Reporting class
+ */
public static class Error {
public String error;
- /**
- * @param error
- */
public Error(String error) {
this.error = error;
}
}
+
+ /**
+ * Feed Ports into Resources
+ */
+ public enum Inputs {
+ configuration,
+ }
+
+ /**
+ * Resource Toggles
+ */
+ public enum Switches {
+ activation,
+ lock,
+ }
}
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java
index d2133374..f18aa78e 100644
--- a/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java
+++ b/policy-management/src/main/java/org/openecomp/policy/drools/system/PolicyEngine.java
@@ -47,6 +47,7 @@ import org.openecomp.policy.drools.protocol.configuration.ControllerConfiguratio
import org.openecomp.policy.drools.protocol.configuration.PdpdConfiguration;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -162,6 +163,14 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
*/
public List<PolicyController> getPolicyControllers();
+
+ /**
+ * get policy controller names
+ *
+ * @return list of controller names
+ */
+ public List<String> getPolicyControllerIds();
+
/**
* get unmanaged sources
*
@@ -296,13 +305,6 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
* Invoked when the host goes into the standby state.
*/
public void deactivate();
-
- /**
- * get policy controller names
- *
- * @return list of controller names
- */
- public List<String> getControllers();
/**
* Policy Engine Manager
@@ -1037,8 +1039,9 @@ class PolicyEngineManager implements PolicyEngine {
/**
* {@inheritDoc}
*/
+ @JsonProperty("controllers")
@Override
- public List<String> getControllers() {
+ public List<String> getPolicyControllerIds() {
List<String> controllerNames = new ArrayList<String>();
for (PolicyController controller: PolicyController.factory.inventory()) {
controllerNames.add(controller.getName());
diff --git a/policy-management/src/main/server/config/IntegrityMonitor.properties b/policy-management/src/main/server/config/IntegrityMonitor.properties
index 529abcda..293f3582 100644
--- a/policy-management/src/main/server/config/IntegrityMonitor.properties
+++ b/policy-management/src/main/server/config/IntegrityMonitor.properties
@@ -25,6 +25,7 @@ http.server.services.TEST.host=0.0.0.0
http.server.services.TEST.port=9981
http.server.services.TEST.restClasses=org.openecomp.policy.drools.core.IntegrityMonitorRestManager
http.server.services.TEST.managed=false
+http.server.services.TEST.swagger=true
# The following were added as part of US673632
#
diff --git a/policy-management/src/main/server/config/policy-engine.properties b/policy-management/src/main/server/config/policy-engine.properties
index 647f7367..dbaf72af 100644
--- a/policy-management/src/main/server/config/policy-engine.properties
+++ b/policy-management/src/main/server/config/policy-engine.properties
@@ -44,3 +44,4 @@ http.server.services.CONFIG.userName=${{ENGINE_MANAGEMENT_USER}}
http.server.services.CONFIG.password=${{ENGINE_MANAGEMENT_PASSWORD}}
http.server.services.CONFIG.restPackages=org.openecomp.policy.drools.server.restful
http.server.services.CONFIG.managed=false
+http.server.services.CONFIG.swagger=true
diff --git a/policy-management/src/main/server/config/policy-healthcheck.properties b/policy-management/src/main/server/config/policy-healthcheck.properties
index 51da7ece..8a44fb9b 100644
--- a/policy-management/src/main/server/config/policy-healthcheck.properties
+++ b/policy-management/src/main/server/config/policy-healthcheck.properties
@@ -3,6 +3,7 @@ http.server.services.HEALTHCHECK.host=0.0.0.0
http.server.services.HEALTHCHECK.port=6969
http.server.services.HEALTHCHECK.restClasses=org.openecomp.policy.drools.healthcheck.RestHealthCheck
http.server.services.HEALTHCHECK.managed=false
+http.server.services.HEALTHCHECK.swagger=true
http.client.services=PAP,PDP
diff --git a/policy-persistence/pom.xml b/policy-persistence/pom.xml
index b8677619..d6c90d5e 100644
--- a/policy-persistence/pom.xml
+++ b/policy-persistence/pom.xml
@@ -96,7 +96,7 @@
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
- <version>${swagger.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.openecomp.policy.drools-pdp</groupId>
diff --git a/pom.xml b/pom.xml
index 5d32039e..42f6d278 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,9 +33,6 @@
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
-
- <swagger-maven-plugin-version>3.1.4</swagger-maven-plugin-version>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.source.version>1.8</project.source.version>
<project.target.version>1.8</project.target.version>
@@ -43,6 +40,7 @@
<dmaap.version>0.2.12</dmaap.version>
<cambria.version>0.0.1</cambria.version>
<jersey.version>2.22.2</jersey.version>
+ <jersey.swagger.version>1.5.13</jersey.swagger.version>
<jackson.version>2.8.4</jackson.version>
<sonar.language>java</sonar.language>
@@ -158,6 +156,11 @@
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-jersey2-jaxrs</artifactId>
+ <version>${jersey.swagger.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -175,53 +178,6 @@
</configuration>
</plugin>
<plugin>
- <groupId>com.github.kongchen</groupId>
- <artifactId>swagger-maven-plugin</artifactId>
- <version>${swagger-maven-plugin-version}</version>
- <configuration>
- <apiSources>
- <apiSource>
- <springmvc>false</springmvc>
- <locations>
- <location>
- org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor
- </location>
- </locations>
- <info>
- <title>Drools PDP</title>
- <version>1.0.0</version>
- </info>
- <swaggerDirectory>${project.build.directory}/swagger/integrityMonitor</swaggerDirectory>
- <swaggerFileName>swagger</swaggerFileName>
- <attachSwaggerArtifact>true</attachSwaggerArtifact>
- </apiSource>
- </apiSources>
- </configuration>
- <dependencies>
- <!-- Adding dependency to swagger-hibernate-validations to enable the BeanValidator as a custom
- model converter -->
- <dependency>
- <groupId>io.swagger</groupId>
- <artifactId>swagger-hibernate-validations</artifactId>
- <version>1.5.6</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.4</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <phase>compile</phase>
- <goals>
- <goal>generate</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8</version> <!-- This version supports the "deployAtEnd" parameter -->