Merge "Fixed 13 blockers in Subscription.java"
authorRam Koya <rk541m@att.com>
Thu, 13 Sep 2018 14:58:51 +0000 (14:58 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 13 Sep 2018 14:58:51 +0000 (14:58 +0000)
20 files changed:
datarouter-node/pom.xml
datarouter-prov/pom.xml
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DRRouteCLI.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/LogfileLoader.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/RouteServletTest.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/beans/FeedTest.java [new file with mode: 0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/beans/GroupTest.java
datarouter-prov/src/test/resources/create.sql
datarouter-subscriber/pom.xml
datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServlet.java [new file with mode: 0644]
datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberMain.java [moved from datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/Subscriber.java with 70% similarity]
datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberProps.java [new file with mode: 0644]
datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberServlet.java [deleted file]
datarouter-subscriber/src/main/resources/docker/startup.sh
datarouter-subscriber/src/main/resources/subscriber.properties
datarouter-subscriber/src/test/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServletTest.java [new file with mode: 0755]
datarouter-subscriber/src/test/resources/log4j.properties [new file with mode: 0644]
datarouter-subscriber/src/test/resources/testsubscriber.properties [new file with mode: 0644]
docker-compose/docker-compose.yml
pom.xml

index 5edffa6..f9bdce6 100755 (executable)
         <datarouter.node.image.name>onap/dmaap/datarouter-node</datarouter.node.image.name>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${google.guava.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons-codec.version}</version>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -54,7 +64,7 @@
         <dependency>
             <groupId>javax.mail</groupId>
             <artifactId>javax.mail-api</artifactId>
-            <version>1.5.1</version>
+            <version>${javax.mail-api.version}</version>
         </dependency>
         <dependency>
             <groupId>com.att.eelf</groupId>
             <artifactId>httpcore</artifactId>
             <version>4.4</version>
         </dependency>
-        <dependency>
-            <groupId>commons-codec</groupId>
-            <artifactId>commons-codec</artifactId>
-            <version>1.6</version>
-        </dependency>
         <dependency>
             <groupId>org.mozilla</groupId>
             <artifactId>rhino</artifactId>
index 9ccbb55..c9c0c2f 100755 (executable)
         <datarouter.prov.image.name>onap/dmaap/datarouter-prov</datarouter.prov.image.name>\r
     </properties>\r
     <dependencies>\r
+        <dependency>\r
+            <groupId>dom4j</groupId>\r
+            <artifactId>dom4j</artifactId>\r
+            <version>${dom4j.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>commons-codec</groupId>\r
+            <artifactId>commons-codec</artifactId>\r
+            <version>${commons-codec.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.google.guava</groupId>\r
+            <artifactId>guava</artifactId>\r
+            <version>${google.guava.version}</version>\r
+        </dependency>\r
         <dependency>\r
             <groupId>ch.qos.logback</groupId>\r
             <artifactId>logback-classic</artifactId>\r
@@ -67,7 +82,7 @@
         <dependency>\r
             <groupId>javax.mail</groupId>\r
             <artifactId>javax.mail-api</artifactId>\r
-            <version>1.5.1</version>\r
+            <version>${javax.mail-api.version}</version>\r
         </dependency>\r
         <dependency>\r
             <groupId>com.att.eelf</groupId>\r
index 1bbf446..af8bd6d 100644 (file)
@@ -339,8 +339,11 @@ public class DRRouteCLI {
             sb.append("Egress Routing Table\n");\r
             sb.append(String.format("%s  Node\n", ext("SubID", cw1)));\r
             for (int i = 0; i < subs.length; i++) {\r
-                String node = ert.getString(subs[i]);\r
-                sb.append(String.format("%s  %s\n", ext(subs[i], cw1), node));\r
+                if(ert!=null&&ert.length()!=0) {\r
+                    String node = ert.getString(subs[i]);\r
+                    sb.append(String.format("%s  %s\n", ext(subs[i], cw1), node));\r
+                }\r
+\r
             }\r
         }\r
         if (tbl.startsWith("al") || tbl.startsWith("ne")) {\r
index 8975f16..110c63d 100644 (file)
@@ -188,6 +188,7 @@ public class LogfileLoader extends Thread {
                         try {\r
                             Thread.sleep(1000L);\r
                         } catch (InterruptedException e) {\r
+                            Thread.currentThread().interrupt();\r
                         }\r
                         idle = false;\r
                     } else {\r
@@ -332,26 +333,25 @@ public class LogfileLoader extends Thread {
         Connection conn = null;\r
         try {\r
             conn = db.getConnection();\r
-            Statement stmt = conn.createStatement();\r
-            // Build a bitset of all records in the LOG_RECORDS table\r
-            // We need to run this SELECT in stages, because otherwise we run out of memory!\r
             RLEBitSet nbs = new RLEBitSet();\r
-            final long stepsize = 6000000L;\r
-            boolean go_again = true;\r
-            for (long i = 0; go_again; i += stepsize) {\r
-                String sql = String.format("select RECORD_ID from LOG_RECORDS LIMIT %d,%d", i, stepsize);\r
-                try(ResultSet rs = stmt.executeQuery(sql)) {\r
-                    go_again = false;\r
-                    while (rs.next()) {\r
-                        long n = rs.getLong("RECORD_ID");\r
-                        nbs.set(n);\r
-                        go_again = true;\r
+            try(Statement stmt = conn.createStatement()) {\r
+                // Build a bitset of all records in the LOG_RECORDS table\r
+                // We need to run this SELECT in stages, because otherwise we run out of memory!\r
+                final long stepsize = 6000000L;\r
+                boolean go_again = true;\r
+                for (long i = 0; go_again; i += stepsize) {\r
+                    String sql = String.format("select RECORD_ID from LOG_RECORDS LIMIT %d,%d", i, stepsize);\r
+                    try (ResultSet rs = stmt.executeQuery(sql)) {\r
+                        go_again = false;\r
+                        while (rs.next()) {\r
+                            long n = rs.getLong("RECORD_ID");\r
+                            nbs.set(n);\r
+                            go_again = true;\r
+                        }\r
                     }\r
                 }\r
             }\r
-            stmt.close();\r
             seq_set = nbs;\r
-\r
             // Compare with the range for this server\r
             // Determine the next ID for this set of record IDs\r
             RLEBitSet tbs = (RLEBitSet) nbs.clone();\r
index f1082ba..226dae0 100755 (executable)
 
 package org.onap.dmaap.datarouter.provisioning;
 
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.json.JSONObject;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.onap.dmaap.datarouter.provisioning.beans.*;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
 import org.powermock.modules.junit4.PowerMockRunner;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.SortedSet;
-import java.util.TreeSet;
+
 import static org.hamcrest.Matchers.notNullValue;
 import static org.mockito.Matchers.*;
 import static org.mockito.Mockito.mock;
@@ -45,12 +45,10 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 @RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.IngressRoute",
-        "org.onap.dmaap.datarouter.provisioning.beans.EgressRoute",
-        "org.onap.dmaap.datarouter.provisioning.beans.NodeClass",
-        "org.onap.dmaap.datarouter.provisioning.beans.NetworkRoute"})
-public class RouteServletTest extends DrServletTestBase
-{
+public class RouteServletTest {
+
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
     private RouteServlet routeServlet;
 
     @Mock
@@ -59,53 +57,55 @@ public class RouteServletTest extends DrServletTestBase
     @Mock
     private HttpServletResponse response;
 
+    @BeforeClass
+    public static void init() {
+        emf = Persistence.createEntityManagerFactory("dr-unit-tests");
+        em = emf.createEntityManager();
+        System.setProperty(
+                "org.onap.dmaap.datarouter.provserver.properties",
+                "src/test/resources/h2Database.properties");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        em.clear();
+        em.close();
+        emf.close();
+    }
+
     @Before
     public void setUp() throws Exception {
-        super.setUp();
-        setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
-        setRouteToReturnValid();
         routeServlet = new RouteServlet();
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Is_Not_Authorized() throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
+    public void Given_Request_Is_HTTP_DELETE_And_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
+            throws Exception {
+        when(request.getRemoteAddr()).thenReturn("stub_addr");
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Route_Does_Not_Exist_In_Path() throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Route_Does_Not_Exist_In_Path_Then_Route_Does_Not_Exist_Is_Returned()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/3/internal/route/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Path_Contains_Invalid_FeedID() throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Path_Contains_Invalid_FeedID_Then_Feed_Not_Found_Is_Returned()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/feedID/internal/route/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Path_Contains_Invalid_Sequence_Number() throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Ingress_Path_Contains_Invalid_Sequence_Number_Then_Invalid_Sequence_Is_Returned()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/feedID/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -113,11 +113,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Ingress_Path_Contains_Invalid_Number_Of_Arguments() throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -125,11 +120,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Egress_Route_Does_Not_Exist_In_Path() throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/3");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -137,11 +127,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Egress_Path_Contains_Invalid_SubID() throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/subID");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -149,11 +134,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Egress_Path_Contains_Invalid_Number_Of_Arguments() throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -161,37 +141,20 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Network_Path_Contains_Invalid_Number_Of_Arguments() throws Exception {
         when(request.getPathInfo()).thenReturn("/network/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_DELETE_And_Deletable_Is_Null() throws Exception {
+    public void Given_Request_Is_HTTP_DELETE_And_Deletable_Is_Null_Then_Bad_Url_Is_Returned() throws Exception {
         when(request.getPathInfo()).thenReturn("/route/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-
-            @Override
-            protected boolean doDelete(Deleteable bean) {
-                return true;
-            }
-        };
         routeServlet.doDelete(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
 
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_Fails() throws Exception {
-        when(request.getPathInfo()).thenReturn("/network/subID/route");
-        PowerMockito.mockStatic(NodeClass.class);
-        PowerMockito.when(NodeClass.normalizeNodename(anyString())).thenReturn("stub_val");
+        when(request.getPathInfo()).thenReturn("/network/node01/node02");
         RouteServlet routeServlet = new RouteServlet() {
             protected boolean isAuthorizedForInternal(HttpServletRequest req) {
                 return true;
@@ -203,12 +166,13 @@ public class RouteServletTest extends DrServletTestBase
             }
         };
         routeServlet.doDelete(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+        verify(response)
+                .sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
     }
 
     @Test
     public void Given_Request_Is_HTTP_GET_And_Is_Not_Authorized() throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
+        when(request.getRemoteAddr()).thenReturn("stub_addr");
         routeServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
@@ -216,11 +180,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_GET_And_Path_Does_Not_Start_With_Valid_Route() throws Exception {
         when(request.getPathInfo()).thenReturn("/route/");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doGet(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -229,14 +188,8 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_GET_And_Path_Equals_Ingress_And_Get_Succeeds() throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
     }
@@ -244,14 +197,8 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_GET_And_Path_Equals_Egress_And_Get_Succeeds() throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
     }
@@ -259,32 +206,21 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_GET_And_Ingress_Path_Equals_Network_And_Get_Succeeds() throws Exception {
         when(request.getPathInfo()).thenReturn("/network/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         ServletOutputStream outStream = mock(ServletOutputStream.class);
         when(response.getOutputStream()).thenReturn(outStream);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doGet(request, response);
         verify(response).setStatus(eq(HttpServletResponse.SC_OK));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Is_Not_Authorized() throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
+        when(request.getRemoteAddr()).thenReturn("stub_addr");
         routeServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Contains_Bad_URL() throws Exception {
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -292,55 +228,38 @@ public class RouteServletTest extends DrServletTestBase
 
     @Test
     public void Given_Request_Is_HTTP_POST_And_Is_Not_Authorized() throws Exception {
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "isAddressAuthEnabled", "true", true);
+        when(request.getRemoteAddr()).thenReturn("stub_addr");
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Ingress_Path_Starts_With_Ingress_And_Contains_Invalid_Arguments() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_Ingress_Path_Starts_With_Ingress_And_Contains_Invalid_Arguments()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/ingress/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         when(request.getParameter("feed")).thenReturn("3");
         when(request.getParameter("user")).thenReturn(null);
         when(request.getParameter("subnet")).thenReturn(null);
         when(request.getParameter("nodepatt")).thenReturn(null);
         when(request.getParameter("seq")).thenReturn(null);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Egress_And_EgressRoute_Already_Exists() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Egress_And_EgressRoute_Already_Exists()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
-        when(request.getParameter("sub")).thenReturn("3");
-        EgressRoute e = mock(EgressRoute.class);
-        PowerMockito.when(EgressRoute.getEgressRoute(anyInt())).thenReturn(e);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
+        when(request.getParameter("sub")).thenReturn("1");
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
 
     @Test
-    public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Egress_And_Contains_Invalid_Arguments() throws Exception {
+    public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Egress_And_Contains_Invalid_Arguments()
+            throws Exception {
         when(request.getPathInfo()).thenReturn("/egress/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         when(request.getParameter("sub")).thenReturn("3");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
@@ -348,12 +267,6 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Network_And_Is_Missing_Arguments() throws Exception {
         when(request.getPathInfo()).thenReturn("/network/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
@@ -361,20 +274,9 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_POST_And_Path_Starts_With_Network_And_Route_Already_Exists() throws Exception {
         when(request.getPathInfo()).thenReturn("/network/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         when(request.getParameter("from")).thenReturn("stub_from");
         when(request.getParameter("to")).thenReturn("stub_to");
         when(request.getParameter("via")).thenReturn("stub_via");
-        PowerMockito.mockStatic(NodeClass.class);
-        PowerMockito.when(NodeClass.normalizeNodename(anyString())).thenReturn("stub_val");
-        SortedSet<NetworkRoute> networkSet = new TreeSet();
-        networkSet.add(mock(NetworkRoute.class));
-        PowerMockito.when(NetworkRoute.getAllNetworkRoutes()).thenReturn(networkSet);
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
@@ -382,17 +284,9 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_POST_And_Path_URL_Is_Null() throws Exception {
         when(request.getPathInfo()).thenReturn("/route/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
         when(request.getParameter("from")).thenReturn("stub_from");
         when(request.getParameter("to")).thenReturn("stub_to");
         when(request.getParameter("via")).thenReturn("stub_via");
-        PowerMockito.mockStatic(NodeClass.class);
-        PowerMockito.when(NodeClass.normalizeNodename(anyString())).thenReturn("stub_val");
-        RouteServlet routeServlet = new RouteServlet() {
-            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
-                return true;
-            }
-        };
         routeServlet.doPost(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
     }
@@ -400,12 +294,9 @@ public class RouteServletTest extends DrServletTestBase
     @Test
     public void Given_Request_Is_HTTP_POST_And_Fails() throws Exception {
         when(request.getPathInfo()).thenReturn("/network/");
-        when(request.getRemoteAddr()).thenReturn("stub_addr");
-        when(request.getParameter("from")).thenReturn("stub_from");
-        when(request.getParameter("to")).thenReturn("stub_to");
-        when(request.getParameter("via")).thenReturn("stub_via");
-        PowerMockito.mockStatic(NodeClass.class);
-        PowerMockito.when(NodeClass.normalizeNodename(anyString())).thenReturn("stub_val");
+        when(request.getParameter("from")).thenReturn("node01");
+        when(request.getParameter("to")).thenReturn("node02");
+        when(request.getParameter("via")).thenReturn("node03");
         RouteServlet routeServlet = new RouteServlet() {
             protected boolean isAuthorizedForInternal(HttpServletRequest req) {
                 return true;
@@ -416,39 +307,9 @@ public class RouteServletTest extends DrServletTestBase
                 return false;
             }
         };
-        routeServlet.doPost(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
-    }
 
-    private void setRouteToReturnValid() throws IllegalAccessException {
-        PowerMockito.mockStatic(IngressRoute.class);
-        PowerMockito.when(IngressRoute.getIngressRoute(anyInt(), anyString(), anyString())).thenReturn(null);
-        SortedSet<IngressRoute> ingressSet = new TreeSet();
-        IngressRoute ingressRoute = mock(IngressRoute.class);
-        JSONObject joIngress = mock(JSONObject.class);
-        when(joIngress.toString()).thenReturn("{}");
-        when(ingressRoute.asJSONObject()).thenReturn(joIngress);
-        ingressSet.add(ingressRoute);
-        PowerMockito.when(IngressRoute.getAllIngressRoutes()).thenReturn(ingressSet);
-
-        PowerMockito.mockStatic(EgressRoute.class);
-        PowerMockito.when(EgressRoute.getEgressRoute(anyInt())).thenReturn(null);
-        SortedSet<EgressRoute> egressSet = new TreeSet();
-        EgressRoute egressRoute = mock(EgressRoute.class);
-        JSONObject joEgress = mock(JSONObject.class);
-        when(joEgress.toString()).thenReturn("{}");
-        when(egressRoute.asJSONObject()).thenReturn(joEgress);
-        egressSet.add(egressRoute);
-        PowerMockito.when(EgressRoute.getAllEgressRoutes()).thenReturn(egressSet);
-
-        PowerMockito.mockStatic(NetworkRoute.class);
-        SortedSet<NetworkRoute> networkSet = new TreeSet();
-        PowerMockito.when(NetworkRoute.getAllNetworkRoutes()).thenReturn(networkSet);
-
-    }
-
-    private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
-        Poker poker = mock(Poker.class);
-        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+        routeServlet.doPost(request, response);
+        verify(response)
+                .sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
     }
 }
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/beans/FeedTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/beans/FeedTest.java
new file mode 100644 (file)
index 0000000..907aa93
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * ============LICENSE_START==================================================
+ * * org.onap.dmaap
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ *  * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package org.onap.dmaap.datarouter.provisioning.beans;
+
+import org.json.JSONObject;
+import org.junit.*;
+import org.junit.runner.RunWith;
+import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import java.io.InvalidObjectException;
+import java.sql.SQLException;
+import java.util.List;
+
+@RunWith(PowerMockRunner.class)
+public class FeedTest {
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
+    private Feed feed;
+    private DB db;
+
+    @BeforeClass
+    public static void init() {
+        emf = Persistence.createEntityManagerFactory("dr-unit-tests");
+        em = emf.createEntityManager();
+        System.setProperty(
+                "org.onap.dmaap.datarouter.provserver.properties",
+                "src/test/resources/h2Database.properties");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        em.clear();
+        em.close();
+        emf.close();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        db = new DB();
+        feed = new Feed("Feed1","v0.1", "First Feed for testing", "First Feed for testing");
+        feed.setFeedid(1);
+        feed.setGroupid(1);
+        feed.setPublisher("pub");
+        feed.setDeleted(false);
+    }
+
+    @Test
+    public void Given_getFilteredFeedUrlList_With_Name_Then_Method_Returns_Self_Links() {
+        List<String>  list= feed.getFilteredFeedUrlList("name","Feed1");
+        Assert.assertEquals("self_link",list.get(0));
+    }
+
+    @Test
+    public void Given_getFilteredFeedUrlList_With_Publ_Then_Method_Returns_Self_Links() {
+        List<String>  list= feed.getFilteredFeedUrlList("publ","pub");
+        Assert.assertEquals("self_link",list.get(0));
+    }
+
+    @Test
+    public void Given_getFilteredFeedUrlList_With_Subs_Then_Method_Returns_Self_Links() {
+        List<String>  list= feed.getFilteredFeedUrlList("subs","sub123");
+        Assert.assertEquals("self_link",list.get(0));
+    }
+
+    @Test
+    public void Given_doDelete_Succeeds_Then_doInsert_To_Put_Feed_Back_And_Bool_Is_True() throws SQLException, InvalidObjectException {
+        Boolean bool = feed.doDelete(db.getConnection());
+        Assert.assertEquals(true, bool);
+        JSONObject jo = new JSONObject();
+        jo.put("self","self_link");
+        jo.put("publish","publish_link");
+        jo.put("subscribe","subscribe_link");
+        jo.put("log","log_link");
+        feed.setLinks(new FeedLinks(jo));
+        bool = feed.doInsert(db.getConnection());
+        Assert.assertEquals(true, bool);
+    }
+
+    @Test
+    public void Validate_ChaneOwnerShip_Returns_True()
+    {
+        Boolean bool = feed.changeOwnerShip();
+        Assert.assertEquals(true, bool);
+    }
+
+    @Test
+    public void Given_Feeds_Are_Equal_Then_Equals_Returns_True()
+    {
+        Feed feed2 = feed;
+        Boolean bool = feed.equals(feed2);
+        Assert.assertEquals(true, bool);
+    }
+}
\ No newline at end of file
index 91d72af..b785fdc 100644 (file)
@@ -23,7 +23,9 @@
 package org.onap.dmaap.datarouter.provisioning.beans;
 
 import org.junit.*;
+import org.junit.runner.RunWith;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
@@ -32,6 +34,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
+@RunWith(PowerMockRunner.class)
 public class GroupTest {
   private static EntityManagerFactory emf;
   private static EntityManager em;
index 2f9d3d9..cd87dde 100755 (executable)
@@ -164,7 +164,7 @@ insert into INGRESS_ROUTES(SEQUENCE, FEEDID , USERID, SUBNET, NODESET)
 VALUES (2,1,'user',null,2);
 
 insert into NODESETS(SETID, NODEID)
-VALUES (2,0);
+VALUES (2,2);
 
 insert into LOG_RECORDS(RECORD_ID,TYPE,EVENT_TIME,PUBLISH_ID,FEEDID,REQURI,METHOD,CONTENT_TYPE,CONTENT_LENGTH,FEED_FILEID,REMOTE_ADDR,USER,STATUS,DELIVERY_SUBID,DELIVERY_FILEID,RESULT,ATTEMPTS,REASON)
 VALUES(1,'pub',2536159564422,'ID',1,'URL','GET','application/vnd.att-dr.log-list; version=1.0',100,1,'172.0.0.8','user',204,1,1,204,0,'other');
@@ -173,4 +173,18 @@ CREATE ALIAS IF NOT EXISTS `SUBSTRING_INDEX` AS $$
     String Function(String one, String two, String three){
         return "url";
     }
-$$;
\ No newline at end of file
+$$;
+
+insert into NETWORK_ROUTES(FROMNODE, TONODE, VIANODE)
+VALUES (1, 3, 2);
+
+insert into NODES(NODEID, NAME) values
+    (1, 'stub_from.'),
+    (2, 'stub_via.'),
+    (3, 'stub_to.'),
+    (4, 'node01.'),
+    (5, 'node02.'),
+    (6, 'node03.')
+;
+insert into EGRESS_ROUTES(SUBID, NODEID) values (1, 1);
+
index 4d09d68..cc1d486 100755 (executable)
         <datarouter.prov.image.name>onap/dmaap/datarouter-subscriber</datarouter.prov.image.name>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${google.guava.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons-codec.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-server</artifactId>
             <version>1.2.17</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.2</version>
+        </dependency>
     </dependencies>
     <profiles>
         <profile>
                     <archive>
                         <manifest>
                             <addClasspath>true</addClasspath>
-                            <mainClass>org.onap.dmaap.datarouter.subscriber.Subscriber</mainClass>
+                            <mainClass>org.onap.dmaap.datarouter.subscriber.SubscriberMain</mainClass>
                         </manifest>
                     </archive>
                 </configuration>
diff --git a/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServlet.java b/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServlet.java
new file mode 100644 (file)
index 0000000..58bc4c4
--- /dev/null
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * ============LICENSE_START==================================================
+ * * org.onap.dmaap
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ *  * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package org.onap.dmaap.datarouter.subscriber;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class SampleSubscriberServlet extends HttpServlet {
+
+  private static Logger logger =
+      Logger.getLogger("org.onap.dmaap.datarouter.subscriber.SampleSubscriberServlet");
+  private String outputDirectory;
+  private String basicAuth;
+
+  /**
+   * Configure the SampleSubscriberServlet.
+   *
+   * <ul>
+   *   <li>Login - The login expected in the Authorization header (default "LOGIN").
+   *   <li>Password - The password expected in the Authorization header (default "PASSWORD").
+   *   <li>outputDirectory - The directory where files are placed (default
+   *       "/opt/app/subscriber/delivery").
+   * </ul>
+   */
+  @Override
+  public void init() {
+    SubscriberProps props = SubscriberProps.getInstance();
+    String login = props.getValue("org.onap.dmaap.datarouter.subscriber.auth.user", "LOGIN");
+    String password =
+        props.getValue("org.onap.dmaap.datarouter.subscriber.auth.password", "PASSWORD");
+    outputDirectory =
+        props.getValue(
+            "org.onap.dmaap.datarouter.subscriber.delivery.dir", "/opt/app/subscriber/delivery");
+    try {
+      Files.createDirectory(Paths.get(outputDirectory));
+    } catch (IOException e) {
+      logger.info("SubServlet: Failed to create delivery dir: " + e.getMessage());
+    }
+    basicAuth = "Basic " + Base64.encodeBase64String((login + ":" + password).getBytes());
+  }
+
+  @Override
+  protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
+    try {
+      common(req, resp, false);
+    } catch (IOException e) {
+      logger.info(
+          "SampleSubServlet: Failed to doPut: " + req.getRemoteAddr() + " : " + req.getPathInfo(),
+          e);
+    }
+  }
+
+  @Override
+  protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
+    try {
+      common(req, resp, true);
+    } catch (IOException e) {
+      logger.info(
+          "SampleSubServlet: Failed to doDelete: "
+              + req.getRemoteAddr()
+              + " : "
+              + req.getPathInfo(),
+          e);
+    }
+  }
+  /**
+   * Process a PUT or DELETE request.
+   *
+   * <ol>
+   *   <li>Verify that the request contains an Authorization header or else UNAUTHORIZED.
+   *   <li>Verify that the Authorization header matches the configured Login and Password or else
+   *       FORBIDDEN.
+   *   <li>If the request is PUT, store the message body as a file in the configured outputDirectory
+   *       directory protecting against evil characters in the received FileID. The file is created
+   *       initially with its name prefixed with a ".", and once it is complete, it is renamed to
+   *       remove the leading "." character.
+   *   <li>If the request is DELETE, instead delete the file (if it exists) from the configured
+   *       outputDirectory directory.
+   *   <li>Respond with NO_CONTENT.
+   * </ol>
+   */
+  private void common(HttpServletRequest req, HttpServletResponse resp, boolean isdelete)
+      throws IOException {
+    String authHeader = req.getHeader("Authorization");
+    if (authHeader == null) {
+      logger.info(
+          "SampleSubServlet: Rejecting request with no Authorization header from "
+              + req.getRemoteAddr()
+              + ": "
+              + req.getPathInfo());
+      resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+      return;
+    }
+    if (!basicAuth.equals(authHeader)) {
+      logger.info(
+          "SampleSubServlet: Rejecting request with incorrect Authorization header from "
+              + req.getRemoteAddr()
+              + ": "
+              + req.getPathInfo());
+      resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+      return;
+    }
+    String fileid = req.getPathInfo();
+    fileid = fileid.substring(fileid.lastIndexOf('/') + 1);
+    String queryString = req.getQueryString();
+    if (queryString != null) {
+      fileid = fileid + "?" + queryString;
+    }
+    String publishid = req.getHeader("X-ATT-DR-PUBLISH-ID");
+    String filename =
+        URLEncoder.encode(fileid, "UTF-8").replaceAll("^\\.", "%2E").replaceAll("\\*", "%2A");
+    String fullPath = outputDirectory + "/" + filename;
+    String tmpPath = outputDirectory + "/." + filename;
+    try {
+      if (isdelete) {
+        Files.deleteIfExists(Paths.get(fullPath));
+        logger.info(
+            "SampleSubServlet: Received delete for file id "
+                + fileid
+                + " from "
+                + req.getRemoteAddr()
+                + " publish id "
+                + publishid
+                + " as "
+                + fullPath);
+      } else {
+        new File(tmpPath).createNewFile();
+        try (InputStream is = req.getInputStream();
+            OutputStream os = new FileOutputStream(tmpPath)) {
+          byte[] buf = new byte[65536];
+          int i;
+          while ((i = is.read(buf)) > 0) {
+            os.write(buf, 0, i);
+          }
+        }
+        Files.move(Paths.get(tmpPath), Paths.get(fullPath), StandardCopyOption.REPLACE_EXISTING);
+        logger.info(
+            "SampleSubServlet: Received file id "
+                + fileid
+                + " from "
+                + req.getRemoteAddr()
+                + " publish id "
+                + publishid
+                + " as "
+                + fullPath);
+        resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
+      }
+      resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
+    } catch (IOException ioe) {
+      Files.deleteIfExists(Paths.get(tmpPath));
+      logger.info(
+          "SampleSubServlet: Failed to process file "
+              + fullPath
+              + " from "
+              + req.getRemoteAddr()
+              + ": "
+              + req.getPathInfo());
+      throw ioe;
+    }
+  }
+}
 package org.onap.dmaap.datarouter.subscriber;
 
 import org.apache.log4j.Logger;
-import org.eclipse.jetty.servlet.*;
-import org.eclipse.jetty.util.ssl.*;
-import org.eclipse.jetty.server.*;
 import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.util.Arrays;
-import java.util.Properties;
-
-public class Subscriber {
 
-    private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.subscriber.Subscriber");
+public class SubscriberMain {
 
-    private static final String CONTEXT_PATH = "/";
-    private static final String URL_PATTERN = "/*";
-
-    static Properties props;
-
-    private static void loadProps() {
-        if (props == null) {
-            props = new Properties();
-            try {
-                props.load(new FileInputStream(System.getProperty(
-                        "org.onap.dmaap.datarouter.subscriber.properties",
-                        "/opt/app/subscriber/etc/subscriber.properties")));
-            } catch (IOException e) {
-                logger.fatal("SubServlet: Exception opening properties: " + e.getMessage());
-                System.exit(1);
-            }
-        }
-    }
+    private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.subscriber.SubscriberMain");
 
     public static void main(String[] args) throws Exception {
-        //Load the properties
-        loadProps();
-
-        int httpsPort = Integer.parseInt(props.getProperty("org.onap.dmaap.datarouter.subscriber.https.port", "8443"));
-        int httpPort = Integer.parseInt(props.getProperty("org.onap.dmaap.datarouter.subscriber.http.port", "8080"));
+        SubscriberProps props = SubscriberProps.getInstance(
+                System.getProperty("org.onap.dmaap.datarouter.subscriber.properties", "subscriber.properties"));
+        int httpsPort = Integer.parseInt(props.getValue("org.onap.dmaap.datarouter.subscriber.https.port", "8443"));
+        int httpPort = Integer.parseInt(props.getValue("org.onap.dmaap.datarouter.subscriber.http.port", "8080"));
 
         Server server = new Server();
         HttpConfiguration httpConfig = new HttpConfiguration();
@@ -91,7 +69,7 @@ public class Subscriber {
 
             /*Skip SSLv3 Fixes*/
             sslContextFactory.addExcludeProtocols("SSLv3");
-            logger.info("Excluded protocols for Subscriber:" + Arrays.toString(sslContextFactory.getExcludeProtocols()));
+            logger.info("Excluded protocols for SubscriberMain:" + Arrays.toString(sslContextFactory.getExcludeProtocols()));
             /*End of SSLv3 Fixes*/
 
             // HTTPS Configuration
@@ -104,17 +82,17 @@ public class Subscriber {
             server.setConnectors(new Connector[]{ httpServerConnector });
         }
         ctxt = new ServletContextHandler(0);
-        ctxt.setContextPath(CONTEXT_PATH);
+        ctxt.setContextPath("/");
         server.setHandler(ctxt);
 
-        ctxt.addServlet(new ServletHolder(new SubscriberServlet()), URL_PATTERN);
+        ctxt.addServlet(new ServletHolder(new SampleSubscriberServlet()), "/*");
         try {
             server.start();
         } catch ( Exception e ) {
             logger.info("Jetty failed to start. Reporting will be unavailable-"+e);
         }
         server.join();
-        logger.info("org.onap.dmaap.datarouter.subscriber.Subscriber started-"+ server.getState());
+        logger.info("org.onap.dmaap.datarouter.subscriber.SubscriberMain started-"+ server.getState());
 
     }
 }
\ No newline at end of file
diff --git a/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberProps.java b/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberProps.java
new file mode 100644 (file)
index 0000000..39ab166
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * ============LICENSE_START==================================================
+ * * org.onap.dmaap
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ *  * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+
+package org.onap.dmaap.datarouter.subscriber;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class SubscriberProps {
+
+    private static SubscriberProps instance = null;
+    private Properties properties;
+
+    private SubscriberProps(String propsPath) throws IOException{
+        properties = new Properties();
+        properties.load(getClass().getClassLoader().getResourceAsStream(propsPath));
+
+    }
+
+    public static SubscriberProps getInstance(String propsPath) {
+        if(instance == null) {
+            try {
+                instance = new SubscriberProps(propsPath);
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
+        }
+        return instance;
+    }
+
+    public static SubscriberProps getInstance() {
+        return instance;
+    }
+
+    public String getValue(String key) {
+        return properties.getProperty(key);
+    }
+
+    public String getValue(String key, String defaultValue) {
+        return properties.getProperty(key, defaultValue);
+    }
+
+}
\ No newline at end of file
diff --git a/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberServlet.java b/datarouter-subscriber/src/main/java/org/onap/dmaap/datarouter/subscriber/SubscriberServlet.java
deleted file mode 100644 (file)
index 72afcf0..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START==================================================
- * * org.onap.dmaap
- * * ===========================================================================
- * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
- * * ===========================================================================
- * * Licensed under the Apache License, Version 2.0 (the "License");
- * * you may not use this file except in compliance with the License.
- * * You may obtain a copy of the License at
- * *
- *  *      http://www.apache.org/licenses/LICENSE-2.0
- * *
- *  * Unless required by applicable law or agreed to in writing, software
- * * distributed under the License is distributed on an "AS IS" BASIS,
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * * See the License for the specific language governing permissions and
- * * limitations under the License.
- * * ============LICENSE_END====================================================
- * *
- * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- * *
- ******************************************************************************/
-
-package org.onap.dmaap.datarouter.subscriber;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.*;
-import java.net.URLEncoder;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.PosixFilePermissions;
-
-import static org.onap.dmaap.datarouter.subscriber.Subscriber.props;
-
-public class SubscriberServlet extends HttpServlet {
-
-       private static Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.subscriber.SubscriberServlet");
-       private String outputDirectory;
-       private String basicAuth;
-
-       /**
-        *      Configure this subscriberservlet.  Configuration parameters from config.getInitParameter() are:
-        *      <ul>
-        *      <li>Login - The login expected in the Authorization header (default "LOGIN").
-        *      <li>Password - The password expected in the Authorization header (default "PASSWORD").
-        *      <li>outputDirectory - The directory where files are placed (default "tmp").
-        *      </ul>
-        */
-       @Override
-    public void init(ServletConfig config) {
-        String login = props.getProperty("org.onap.dmaap.datarouter.subscriber.auth.user", "LOGIN");
-               String password = props.getProperty("org.onap.dmaap.datarouter.subscriber.auth.password", "PASSWORD");
-        outputDirectory = props.getProperty("org.onap.dmaap.datarouter.subscriber.delivery.dir", "/tmp");
-        try {
-            Files.createDirectory(Paths.get(outputDirectory), PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx")));
-        } catch (IOException e) {
-            logger.info("SubServlet: Failed to create delivery dir: " + e.getMessage());
-            e.printStackTrace();
-        }
-               basicAuth = "Basic " + Base64.encodeBase64String((login + ":" + password).getBytes());
-       }
-
-       @Override
-       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-               File filesPath = new File(outputDirectory);
-               File[] filesArr = filesPath.listFiles();
-        assert filesArr != null;
-        for (File file: filesArr) {
-            try (BufferedReader in = new BufferedReader(new FileReader(file))) {
-                String line = in.readLine();
-                while (line != null) {
-                    line = in.readLine();
-                }
-            }
-               }
-       }
-       /**
-        *      Invoke common(req, resp, false).
-        */
-       @Override
-       protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
-        try {
-            common(req, resp, false);
-        } catch (IOException e) {
-            logger.info("SubServlet: Failed to doPut: " + req.getRemoteAddr() + " : " + req.getPathInfo(), e);
-        }
-    }
-       /**
-        *      Invoke common(req, resp, true).
-        */
-       @Override
-       protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
-        try {
-            common(req, resp, true);
-        } catch (IOException e) {
-            logger.info("SubServlet: Failed to doDelete: " + req.getRemoteAddr() + " : " + req.getPathInfo(), e);
-        }
-    }
-       /**
-        *      Process a PUT or DELETE request.
-        *      <ol>
-        *      <li>Verify that the request contains an Authorization header
-        *      or else UNAUTHORIZED.
-        *      <li>Verify that the Authorization header matches the configured
-        *      Login and Password or else FORBIDDEN.
-        *      <li>If the request is PUT, store the message body as a file
-        *      in the configured outputDirectory directory protecting against
-        *      evil characters in the received FileID.  The file is created
-        *      initially with its name prefixed with a ".", and once it is complete, it is
-        *      renamed to remove the leading "." character.
-        *      <li>If the request is DELETE, instead delete the file (if it exists) from the configured outputDirectory directory.
-        *      <li>Respond with NO_CONTENT.
-        *      </ol>
-        */
-    private void common(HttpServletRequest req, HttpServletResponse resp, boolean isdelete) throws IOException {
-               String authHeader = req.getHeader("Authorization");
-               if (authHeader == null) {
-                       logger.info("Rejecting request with no Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
-                       resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
-                       return;
-               }
-               if (!basicAuth.equals(authHeader)) {
-                       logger.info("Rejecting request with incorrect Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
-                       resp.sendError(HttpServletResponse.SC_FORBIDDEN);
-                       return;
-               }
-               String fileid = req.getPathInfo();
-               fileid = fileid.substring(fileid.lastIndexOf('/') + 1);
-               String queryString = req.getQueryString();
-               if (queryString != null) {
-                       fileid = fileid + "?" + queryString;
-               }
-               String publishid = req.getHeader("X-ATT-DR-PUBLISH-ID");
-               String filename = URLEncoder.encode(fileid, "UTF-8").replaceAll("^\\.", "%2E").replaceAll("\\*", "%2A");
-               String fullPath = outputDirectory + "/" + filename;
-               String tmpPath = outputDirectory + "/." + filename;
-               try {
-                       if (isdelete) {
-                           Files.deleteIfExists(Paths.get(fullPath));
-                               logger.info("Received delete for file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + fullPath);
-                       } else {
-                new File(tmpPath).createNewFile();
-                try (InputStream is = req.getInputStream(); OutputStream os = new FileOutputStream(tmpPath)) {
-                    byte[] buf = new byte[65536];
-                    int i;
-                    while ((i = is.read(buf)) > 0) {
-                        os.write(buf, 0, i);
-                    }
-                }
-                Files.move(Paths.get(tmpPath), Paths.get(fullPath), StandardCopyOption.REPLACE_EXISTING);
-                               logger.info("Received file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + fullPath);
-                               resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
-                       }
-                       resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
-               } catch (IOException ioe) {
-            Files.deleteIfExists(Paths.get(tmpPath));
-                       logger.info("Failed to process file " + fullPath + " from " + req.getRemoteAddr() + ": " + req.getPathInfo());
-                       throw ioe;
-               }
-       }
-}
index 53b1053..fb5610d 100644 (file)
@@ -5,7 +5,7 @@ CLASSPATH=$ETC
 for FILE in `find $LIB -name *.jar`; do
   CLASSPATH=$CLASSPATH:$FILE
 done
-java -classpath $CLASSPATH  org.onap.dmaap.datarouter.subscriber.Subscriber
+java -classpath $CLASSPATH  org.onap.dmaap.datarouter.subscriber.SubscriberMain
 
 runner_file="$LIB/subscriber-jar-with-dependencies.jar"
 echo "Starting using" $runner_file
index 771fdd3..ed3237b 100644 (file)
@@ -21,7 +21,7 @@
 # *
 #-------------------------------------------------------------------------------
 
-#Subscriber properties
+#SubscriberMain properties
 org.onap.dmaap.datarouter.subscriber.http.port           = 7070
 org.onap.dmaap.datarouter.subscriber.https.port          = 7443
 org.onap.dmaap.datarouter.subscriber.auth.user           = LOGIN
diff --git a/datarouter-subscriber/src/test/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServletTest.java b/datarouter-subscriber/src/test/java/org/onap/dmaap/datarouter/subscriber/SampleSubscriberServletTest.java
new file mode 100755 (executable)
index 0000000..e31b347
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * ============LICENSE_START==================================================
+ * * org.onap.dmaap
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ *  * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package org.onap.dmaap.datarouter.subscriber;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+@RunWith(PowerMockRunner.class)
+public class SampleSubscriberServletTest {
+
+  private SampleSubscriberServlet sampleSubServlet;
+  private SubscriberProps props = SubscriberProps.getInstance();
+
+  @Mock private HttpServletRequest request;
+  @Mock private HttpServletResponse response;
+
+  @Before
+  public void setUp() {
+    props =
+        SubscriberProps.getInstance(
+            System.getProperty(
+                "org.onap.dmaap.datarouter.subscriber.properties", "testsubscriber.properties"));
+    sampleSubServlet = new SampleSubscriberServlet();
+    sampleSubServlet.init();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    FileUtils.deleteDirectory(
+        new File(props.getValue("org.onap.dmaap.datarouter.subscriber.delivery.dir")));
+  }
+
+  @Test
+  public void
+      Given_Request_Is_HTTP_PUT_And_Request_Header_Is_Null_Then_Unathorized_Response_Is_Generated()
+          throws Exception {
+    when(request.getHeader("Authorization")).thenReturn(null);
+    sampleSubServlet.doPut(request, response);
+    verify(response).sendError(eq(HttpServletResponse.SC_UNAUTHORIZED));
+  }
+
+  @Test
+  public void
+      Given_Request_Is_HTTP_PUT_And_Request_Header_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated()
+          throws Exception {
+    when(request.getHeader("Authorization")).thenReturn("Invalid Header");
+    sampleSubServlet.doPut(request, response);
+    verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN));
+  }
+
+  @Test
+  public void Given_Request_Is_HTTP_PUT_Then_Request_Succeeds() throws Exception {
+    setUpSuccessfulFlow();
+    sampleSubServlet.doPut(request, response);
+    verify(response, times(2)).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+  }
+
+  @Test
+  public void Given_Request_Is_HTTP_DELETE_Then_Request_Succeeds() throws Exception {
+    setUpSuccessfulFlow();
+    sampleSubServlet.doDelete(request, response);
+    verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+  }
+
+  private void setUpSuccessfulFlow() throws IOException {
+    when(request.getHeader("Authorization")).thenReturn("Basic TE9HSU46UEFTU1dPUkQ=");
+    when(request.getPathInfo()).thenReturn("/publish/1/testfile");
+    when(request.getHeader("X-ATT-DR-PUBLISH-ID")).thenReturn("1");
+    when(request.getQueryString()).thenReturn(null);
+    ServletInputStream inStream = mock(ServletInputStream.class);
+    when(request.getInputStream()).thenReturn(inStream);
+  }
+}
diff --git a/datarouter-subscriber/src/test/resources/log4j.properties b/datarouter-subscriber/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..b8d349e
--- /dev/null
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------------
+# ============LICENSE_START==================================================
+# * org.onap.dmaap
+# * ===========================================================================
+# * Copyright � 2017 AT&T Intellectual Property. All rights reserved.
+# * ===========================================================================
+# * Licensed under the Apache License, Version 2.0 (the "License");
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+#  *      http://www.apache.org/licenses/LICENSE-2.0
+# *
+#  * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# * ============LICENSE_END====================================================
+# *
+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# *
+#-------------------------------------------------------------------------------
+
+log4j.rootLogger=info,Root
+
+log4j.appender.Root=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.Root.file=./logs/subscriber.log
+log4j.appender.Root.datePattern='.'yyyyMMdd
+log4j.appender.Root.append=true
+log4j.appender.Root.layout=org.apache.log4j.PatternLayout
+log4j.appender.Root.layout.ConversionPattern=%d %p %t %m%n
diff --git a/datarouter-subscriber/src/test/resources/testsubscriber.properties b/datarouter-subscriber/src/test/resources/testsubscriber.properties
new file mode 100644 (file)
index 0000000..2bdd362
--- /dev/null
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------------
+# ============LICENSE_START==================================================
+# * org.onap.dmaap
+# * ===========================================================================
+# * Copyright � 2017 AT&T Intellectual Property. All rights reserved.
+# * ===========================================================================
+# * Licensed under the Apache License, Version 2.0 (the "License");
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+#  *      http://www.apache.org/licenses/LICENSE-2.0
+# *
+#  * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# * ============LICENSE_END====================================================
+# *
+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# *
+#-------------------------------------------------------------------------------
+
+#SubscriberMain test properties
+org.onap.dmaap.datarouter.subscriber.http.port           = 7070
+org.onap.dmaap.datarouter.subscriber.https.port          = 7443
+org.onap.dmaap.datarouter.subscriber.auth.user           = LOGIN
+org.onap.dmaap.datarouter.subscriber.auth.password       = PASSWORD
+org.onap.dmaap.datarouter.subscriber.delivery.dir        = tmp
+
+
index 35ed74c..a7b0f98 100644 (file)
@@ -23,7 +23,7 @@
 version: '2.1'
 services:
   datarouter-prov:
-    image: nexus3.onap.org:10003/onap/dmaap/datarouter-prov
+    image: nexus3.onap.org:10001/onap/dmaap/datarouter-prov
     container_name: datarouter-prov
     hostname: dmaap-dr-prov
     ports:
@@ -49,7 +49,7 @@ services:
         ipv4_address: 172.100.0.3
 
   datarouter-node:
-    image: nexus3.onap.org:10003/onap/dmaap/datarouter-node
+    image: nexus3.onap.org:10001/onap/dmaap/datarouter-node
     container_name: datarouter-node
     hostname: dmaap-dr-node
     ports:
@@ -67,7 +67,7 @@ services:
         ipv4_address: 172.100.0.4
 
   datarouter-subscriber:
-      image: nexus3.onap.org:10003/onap/dmaap/datarouter-subscriber
+      image: nexus3.onap.org:10001/onap/dmaap/datarouter-subscriber
       container_name: subscriber-node
       hostname: subscriber.com
       ports:
diff --git a/pom.xml b/pom.xml
index 2781ab0..afbbf92 100755 (executable)
--- a/pom.xml
+++ b/pom.xml
         <sonar.projectVersion>${project.version}</sonar.projectVersion>
         <jetty.version>9.3.8.RC0</jetty.version>
         <jetty.websocket.version>8.2.0.v20160908</jetty.websocket.version>
+        <javax.mail-api.version>1.5.5</javax.mail-api.version>
+        <dom4j.version>1.6</dom4j.version>
         <thoughtworks.version>1.4.10</thoughtworks.version>
+        <google.guava.version>26.0-jre</google.guava.version>
         <qos.logback.version>1.2.3</qos.logback.version>
         <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
         <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
@@ -57,6 +60,7 @@
         <skip.docker.build>true</skip.docker.build>
         <skip.docker.tag>true</skip.docker.tag>
         <skip.docker.push>true</skip.docker.push>
+        <commons-codec.version>1.10</commons-codec.version>
     </properties>
     <modules>
         <module>datarouter-prov</module>