Merge "Add Tests for StatisticsServlet and Group Class"
authorRam Koya <rk541m@att.com>
Thu, 23 Aug 2018 14:44:25 +0000 (14:44 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 23 Aug 2018 14:44:25 +0000 (14:44 +0000)
16 files changed:
.gitignore
datarouter-node/pom.xml
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigTest.java [new file with mode: 0755]
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java [new file with mode: 0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/BaseServletTest.java [changed mode: 0644->0755]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServletTest.java [new file with mode: 0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java [changed mode: 0644->0755]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/GroupServletTest.java [changed mode: 0755->0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/InternalServletTest.java [new file with mode: 0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/LogServletTest.java [new file with mode: 0755]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/PublishServletTest.java [new file with mode: 0755]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/RouteServletTest.java [new file with mode: 0755]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscribeServletTest.java [new file with mode: 0644]
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java [new file with mode: 0644]
docs/data-router/data-router.rst

index a311f8d..bd821d3 100644 (file)
@@ -4,3 +4,4 @@
 *.log*
 *.classpath
 *.project
+datarouter-prov/unit-test-logs/
index 6cc396a..61e9540 100755 (executable)
             <version>1.2.17</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.10</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>1.6.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <version>1.6.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.0</version>
+        </dependency>
     </dependencies>
     <profiles>
         <profile>
diff --git a/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigTest.java b/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigTest.java
new file mode 100755 (executable)
index 0000000..6350e64
--- /dev/null
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * ============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.node;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+@RunWith(PowerMockRunner.class)
+public class NodeConfigTest {
+
+    private static NodeConfig nodeConfig;
+
+    @BeforeClass
+    public static void setUp() throws IOException{
+        ProvData provData = setUpProvData();
+        nodeConfig = new NodeConfig(provData, "Name", "spool/dir", 80, "Key");
+    }
+
+    @Test
+    public void Given_Feed_Does_Not_Exist_Then_Is_Publish_Permitted_Returns_Not_Null() {
+        String permitted = nodeConfig.isPublishPermitted("2", "user", "0.0.0.0");
+        Assert.assertEquals("Feed does not exist", permitted);
+    }
+
+    @Test
+    public void Given_Feed_But_User_Not_Permitted_Then_Is_Publish_Permitted_Returns_Not_Null() {
+        String permitted = nodeConfig.isPublishPermitted("1", "user", "0.0.0.0");
+        Assert.assertEquals("Publisher not permitted for this feed", permitted);
+    }
+
+    @Test
+    public void Given_Feed_But_Ip_Does_Not_Match_Then_Is_Publish_Permitted_Returns_Not_Null() {
+        String permitted = nodeConfig.isPublishPermitted("1", "Basic dXNlcjE6cGFzc3dvcmQx", "0.0.0.0");
+        Assert.assertEquals("Publisher not permitted for this feed", permitted);
+    }
+
+    @Test
+    public void Given_Feed_Then_Is_Publish_Permitted_Returns_Null() {
+        String permitted = nodeConfig.isPublishPermitted("1", "Basic dXNlcjE6cGFzc3dvcmQx", "172.0.0.1");
+        Assert.assertNull(permitted);
+    }
+
+    @Test
+    public void Given_SubId_Then_Get_Feed_Id_Returns_Correct_Id() {
+        String feedId = nodeConfig.getFeedId("1");
+        Assert.assertEquals("1", feedId);
+    }
+
+    @Test
+    public void Given_Incorrect_SubId_Then_Get_Feed_Id_Returns_Null() {
+        String feedId = nodeConfig.getFeedId("2");
+        Assert.assertNull(feedId);
+    }
+
+    @Test
+    public void Given_SubId_Then_Get_Spool_Dir_Returns_Correct_Id() {
+        String spoolDir = nodeConfig.getSpoolDir("1");
+        Assert.assertEquals("spool/dir/s/0/1", spoolDir);
+    }
+
+    @Test
+    public void Given_Incorrect_SubId_Then_Get_Spool_Dir_Returns_Null() {
+        String spoolDir = nodeConfig.getSpoolDir("2");
+        Assert.assertNull(spoolDir);
+    }
+
+    @Test
+    public void Given_Feed_And_Incorrect_Credentials_Then_Get_Auth_User_Returns_Null() {
+        String authUser = nodeConfig.getAuthUser("1", "incorrect");
+        Assert.assertNull(authUser);
+    }
+
+    @Test
+    public void Given_Feed_And_Correct_Credentials_Then_Get_Auth_User_Returns_User() {
+        String authUser = nodeConfig.getAuthUser("1", "Basic dXNlcjE6cGFzc3dvcmQx");
+        Assert.assertEquals("user1", authUser);
+    }
+
+    @Test
+    public void Given_Correct_Feed_Then_Get_Ingress_Node_Returns_Node() {
+        String node = nodeConfig.getIngressNode("1", "user1", "172.0.0.1");
+        Assert.assertEquals("172.0.0.4", node);
+    }
+
+    @Test
+    public void Given_Correct_Feed_Then_Get_Targets_Returns_Correct_Dest_Info() {
+        Target[] targets = nodeConfig.getTargets("1");
+        Assert.assertEquals("1", targets[0].getDestInfo().getSubId());
+        Assert.assertEquals("spool/dir/s/0/1", targets[0].getDestInfo().getSpool());
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void Given_Null_Feed_Then_Get_Targets_Returns_Empty_Array() {
+        Target[] targets = nodeConfig.getTargets(null);
+        targets[0].getDestInfo();
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void Given_Incorrect_Feed_Then_Get_Targets_Returns_Empty_Array() {
+        Target[] targets = nodeConfig.getTargets("2");
+        targets[0].getDestInfo();
+    }
+
+    @Test
+    public void Given_Same_Ip_Then_Is_Another_Node_Returns_False() {
+        Boolean isAnotherNode = nodeConfig.isAnotherNode("Basic MTcyLjAuMC40OmtCTmhkWVFvbzhXNUphZ2g4T1N4Zmp6Mzl1ND0=", "172.0.0.1");
+        Assert.assertFalse(isAnotherNode);
+    }
+
+    @Test
+    public void Given_Different_Ip_Then_Is_Another_Node_Returns_True() {
+        Boolean isAnotherNode = nodeConfig.isAnotherNode("Basic MTcyLjAuMC40OmtCTmhkWVFvbzhXNUphZ2g4T1N4Zmp6Mzl1ND0=", "172.0.0.4");
+        Assert.assertTrue(isAnotherNode);
+    }
+
+    @Test
+    public void Given_Param_Name_Then_Get_Prov_Param_Returns_Parameter() {
+        String paramValue = nodeConfig.getProvParam("DELIVERY_MAX_AGE");
+        Assert.assertEquals("86400", paramValue);
+    }
+
+    @Test
+    public void Validate_Get_All_Dests_Returns_Dest_Info() {
+        DestInfo[] destInfo = nodeConfig.getAllDests();
+        Assert.assertEquals("n:172.0.0.4", destInfo[0].getName());
+    }
+
+    @Test
+    public void Validate_Get_MyAuth_Returns_Correct_Auth() {
+        String auth = nodeConfig.getMyAuth();
+        Assert.assertEquals("Basic TmFtZTp6Z04wMFkyS3gybFppbXltNy94ZDhuMkdEYjA9", auth);
+    }
+
+    private static ProvData setUpProvData() throws IOException {
+        JSONObject provData = new JSONObject();
+        createValidFeed(provData);
+        createValidSubscription(provData);
+        createValidParameters(provData);
+        createValidIngressValues(provData);
+        createValidEgressValues(provData);
+        createValidRoutingValues(provData);
+        Reader reader = new StringReader(provData.toString());
+        return new ProvData(reader);
+    }
+
+    private static void createValidFeed(JSONObject provData) {
+        JSONArray feeds = new JSONArray();
+        JSONObject feed = new JSONObject();
+        JSONObject auth = new JSONObject();
+        JSONArray endpointIds = new JSONArray();
+        JSONArray endpointAddrs = new JSONArray();
+        JSONObject endpointId = new JSONObject();
+        feed.put("feedid", "1");
+        feed.put("name", "Feed1");
+        feed.put("version", "m1.0");
+        feed.put("suspend", false);
+        feed.put("deleted", false);
+        endpointId.put("id", "user1");
+        endpointId.put("password", "password1");
+        endpointIds.put(endpointId);
+        auth.put("endpoint_ids", endpointIds);
+        endpointAddrs.put("172.0.0.1");
+        auth.put("endpoint_addrs", endpointAddrs);
+        feed.put("authorization", auth);
+        feeds.put(feed);
+        provData.put("feeds", feeds);
+    }
+
+    private static void createValidSubscription(JSONObject provData) {
+        JSONArray subscriptions = new JSONArray();
+        JSONObject subscription = new JSONObject();
+        JSONObject delivery = new JSONObject();
+        subscription.put("subid", "1");
+        subscription.put("feedid", "1");
+        subscription.put("suspend", false);
+        subscription.put("metadataOnly", false);
+        delivery.put("url", "https://172.0.0.2");
+        delivery.put("user", "user1");
+        delivery.put("password", "password1");
+        delivery.put("use100", true);
+        subscription.put("delivery", delivery);
+        subscriptions.put(subscription);
+        provData.put("subscriptions", subscriptions);
+    }
+
+    private static void createValidParameters(JSONObject provData) {
+        JSONObject parameters = new JSONObject();
+        JSONArray nodes = new JSONArray();
+        parameters.put("PROV_NAME", "prov.datarouternew.com");
+        parameters.put("DELIVERY_INIT_RETRY_INTERVAL", "10");
+        parameters.put("DELIVERY_MAX_AGE", "86400");
+        parameters.put("PROV_DOMAIN", "");
+        nodes.put("172.0.0.4");
+        parameters.put("NODES", nodes);
+        provData.put("parameters", parameters);
+    }
+
+    private static void createValidIngressValues(JSONObject provData) {
+        JSONArray ingresses = new JSONArray();
+        JSONObject ingress = new JSONObject();
+        ingress.put("feedid", "1");
+        ingress.put("subnet", "");
+        ingress.put("user", "");
+        ingress.put("node", "172.0.0.4");
+        ingresses.put(ingress);
+        provData.put("ingress", ingresses);
+    }
+
+    private static void createValidEgressValues(JSONObject provData) {
+        JSONObject egress = new JSONObject();
+        egress.put("subid", "1");
+        egress.put("nodeid", "172.0.0.4");
+        provData.put("egress", egress);
+    }
+
+    private static void createValidRoutingValues(JSONObject provData) {
+        JSONArray routings = new JSONArray();
+        JSONObject routing = new JSONObject();
+        routing.put("from", "prov.datarouternew.com");
+        routing.put("to", "172.0.0.4");
+        routing.put("via", "172.100.0.1");
+        routings.put(routing);
+        provData.put("routing", routings);
+    }
+}
diff --git a/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java b/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java
new file mode 100644 (file)
index 0000000..048c44f
--- /dev/null
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * ============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.node;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+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.*;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.node.NodeConfigManager")
+public class NodeServletTest {
+
+    private NodeServlet nodeServlet;
+
+    @Mock
+    private HttpServletRequest request;
+
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception{
+        nodeServlet = new NodeServlet();
+        setBehalfHeader("Stub_Value");
+        when(request.getPathInfo()).thenReturn("2");
+        when(request.isSecure()).thenReturn(true);
+        setUpConfig();
+        setUpNodeMainDelivery();
+        when(request.getHeader("Authorization")).thenReturn("User1");
+        when(request.getHeader("X-ATT-DR-PUBLISH-ID")).thenReturn("User1");
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Config_Is_Down_Then_Service_Unavailable_Response_Is_Generated() throws Exception {
+        setNodeConfigManagerIsConfiguredToReturnFalse();
+        nodeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_SERVICE_UNAVAILABLE));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_Internal_FetchProv_Then_No_Content_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/fetchProv");
+        nodeServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_ResetSubscription_Then_No_Content_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/resetSubscription/1");
+        nodeServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_Internal_Logs_And_File_Does_Not_Exist_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/logs/fileName");
+        when(request.getRemoteAddr()).thenReturn("135.207.136.128");
+        nodeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Endpoint_Is_Internal_Rtt_And_Error_Connecting_To_Socket_Occurs_Then_Ok_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/rtt/0.0.0.0");
+        when(request.getRemoteAddr()).thenReturn("135.207.136.128");
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        nodeServlet.doGet(request, response);
+        verify(response).setStatus(eq(200));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_To_Invalid_Endpoint_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect");
+        nodeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Config_Is_Down_Then_Service_Unavailable_Response_Is_Generated() throws Exception {
+        setNodeConfigManagerIsConfiguredToReturnFalse();
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_SERVICE_UNAVAILABLE));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Endpoint_Is_Incorrect_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect/");
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Secure_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_File_Id_Is_Null_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Authorization_Is_Null_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Authorization")).thenReturn(null);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Publish_Does_Not_Include_File_Id_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/");
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Publish_Not_Permitted_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setNodeConfigManagerIsPublishPermittedToReturnAReason();
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Internal_Publish_On_Same_Node_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/publish/1/fileName");
+        setNodeConfigManagerIsPublishPermittedToReturnAReason();
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Internal_Publish_But_Invalid_File_Id_Then_Not_Found_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/internal/publish/1/");
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_On_Publish_And_Ingress_Node_Is_Provided_Then_Request_Is_Redirected() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setNodeConfigManagerToAllowRedirectOnIngressNode();
+        nodeServlet.doPut(request, response);
+        verify(response).sendRedirect(anyString());
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_On_Publish_With_Meta_Data_Too_Long_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setHeadersForValidRequest(true);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setHeadersForValidRequest(false);
+        nodeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_On_Publish_With_Meta_Data_Malformed_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/publish/1/fileName");
+        setHeadersForValidRequest(false);
+        nodeServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+
+    private void setBehalfHeader(String headerValue) {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF")).thenReturn(headerValue);
+    }
+
+    private void setUpConfig() throws IllegalAccessException{
+        NodeConfigManager config = mock(NodeConfigManager.class);
+        PowerMockito.mockStatic(NodeConfigManager.class);
+        when(config.isShutdown()).thenReturn(false);
+        when(config.isConfigured()).thenReturn(true);
+        when(config.getSpoolDir()).thenReturn("spool/dir");
+        when(config.getLogDir()).thenReturn("log/dir");
+        when(config.getPublishId()).thenReturn("User1");
+        when(config.isAnotherNode(anyString(), anyString())).thenReturn(true);
+        when(config.getEventLogInterval()).thenReturn("40");
+        FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
+        FieldUtils.writeDeclaredStaticField(NodeMain.class, "nodeConfigManager", config, true);
+        PowerMockito.when(NodeConfigManager.getInstance()).thenReturn(config);
+    }
+
+
+    private void setUpNodeMainDelivery() throws IllegalAccessException{
+        Delivery delivery = mock(Delivery.class);
+        doNothing().when(delivery).resetQueue(anyObject());
+        FieldUtils.writeDeclaredStaticField(NodeMain.class, "delivery", delivery, true);
+    }
+
+    private void setNodeConfigManagerIsConfiguredToReturnFalse() throws IllegalAccessException{
+        NodeConfigManager config = mock(NodeConfigManager.class);
+        when(config.isConfigured()).thenReturn(false);
+        FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
+    }
+
+    private void setNodeConfigManagerIsPublishPermittedToReturnAReason() throws IllegalAccessException{
+        NodeConfigManager config = mock(NodeConfigManager.class);
+        when(config.isShutdown()).thenReturn(false);
+        when(config.isConfigured()).thenReturn(true);
+        when(config.getSpoolDir()).thenReturn("spool/dir");
+        when(config.getLogDir()).thenReturn("log/dir");
+        when(config.isPublishPermitted(anyString(), anyString(), anyString())).thenReturn("Not Permitted");
+        when(config.isAnotherNode(anyString(), anyString())).thenReturn(false);
+        FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
+    }
+
+    private void setNodeConfigManagerToAllowRedirectOnIngressNode() throws IllegalAccessException{
+        NodeConfigManager config = mock(NodeConfigManager.class);
+        when(config.isShutdown()).thenReturn(false);
+        when(config.isConfigured()).thenReturn(true);
+        when(config.getSpoolDir()).thenReturn("spool/dir");
+        when(config.getLogDir()).thenReturn("log/dir");
+        when(config.getPublishId()).thenReturn("User1");
+        when(config.isAnotherNode(anyString(), anyString())).thenReturn(true);
+        when(config.getAuthUser(anyString(), anyString())).thenReturn("User1");
+        when(config.getIngressNode(anyString(), anyString(), anyString())).thenReturn("NewNode");
+        when(config.getExtHttpsPort()).thenReturn(8080);
+        FieldUtils.writeDeclaredStaticField(NodeServlet.class, "config", config, true);
+    }
+
+    private String createLargeMetaDataString() {
+        StringBuilder myString = new StringBuilder("meta");
+        for (int i = 0; i <= 4098; ++i) {
+            myString.append('x');
+        }
+        return myString.toString();
+    }
+
+    private void setHeadersForValidRequest(boolean isMetaTooLong) {
+        String metaDataString;
+        if (isMetaTooLong) {
+            metaDataString = createLargeMetaDataString();
+        } else {
+            metaDataString = "?#@><";
+        }
+        List<String> headers = new ArrayList<>();
+        headers.add("Content-Type");
+        headers.add("X-ATT-DR-ON-BEHALF-OF");
+        headers.add("X-ATT-DR-META");
+        Enumeration<String> headerNames = Collections.enumeration(headers);
+        when(request.getHeaderNames()).thenReturn(headerNames);
+        Enumeration<String> contentTypeHeader = Collections.enumeration(Arrays.asList("text/plain"));
+        Enumeration<String> behalfHeader = Collections.enumeration(Arrays.asList("User1"));
+        Enumeration<String> metaDataHeader = Collections.enumeration(Arrays.asList(metaDataString));
+        when(request.getHeaders("Content-Type")).thenReturn(contentTypeHeader);
+        when(request.getHeaders("X-ATT-DR-ON-BEHALF-OF")).thenReturn(behalfHeader);
+        when(request.getHeaders("X-ATT-DR-META")).thenReturn(metaDataHeader);
+    }
+}
old mode 100644 (file)
new mode 100755 (executable)
index 757852a..61d030d
@@ -28,18 +28,27 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
+import org.onap.dmaap.datarouter.provisioning.beans.Feed;
+import org.onap.dmaap.datarouter.provisioning.beans.FeedAuthorization;
+import org.onap.dmaap.datarouter.provisioning.beans.Group;
+import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.powermock.modules.junit4.PowerMockRunner;
 import javax.servlet.http.HttpServletRequest;
 import java.util.HashSet;
 import java.util.Set;
-
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@RunWith(MockitoJUnitRunner.class)
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.Feed",
+        "org.onap.dmaap.datarouter.provisioning.beans.Subscription",
+        "org.onap.dmaap.datarouter.provisioning.beans.Group"})
 public class BaseServletTest extends DrServletTestBase {
 
     private BaseServlet baseServlet;
@@ -69,14 +78,118 @@ public class BaseServletTest extends DrServletTestBase {
     }
 
     @Test
-    public void Given_Request_Path_Info_Is_Not_Valid_Then_Minus_One_Is() throws Exception {
+    public void Given_Remote_Address_Is_Known_And_RequireCerts_Is_True() throws Exception {
         when(request.isSecure()).thenReturn(true);
         Set<String> authAddressesAndNetworks = new HashSet<String>();
         authAddressesAndNetworks.add(("127.0.0.1"));
-        FieldUtils
-            .writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks,
-                true);
-        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
-        assertThat(baseServlet.isAuthorizedForProvisioning(request), is(nullValue()));
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", true, true);
+        assertThat(baseServlet.isAuthorizedForProvisioning(request), is("Client certificate is missing."));
+    }
+
+    @Test
+    public void Given_Request_Is_GetFeedOwner_And_Feed_Exists() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        when(feed.getPublisher()).thenReturn("stub_publisher");
+        assertThat(baseServlet.getFeedOwner("3"), is("stub_publisher"));
+    }
+
+    @Test
+    public void Given_Request_Is_GetFeedOwner_And_Feed_Does_Not_Exist() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
+        assertThat(baseServlet.getFeedOwner("3"), is(nullValue()));
+    }
+
+    @Test
+    public void Given_Request_Is_GetFeedClassification_And_Feed_Exists() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        FeedAuthorization fAuth = mock(FeedAuthorization.class);
+        when(feed.getAuthorization()).thenReturn(fAuth);
+        when(fAuth.getClassification()).thenReturn("stub_classification");
+        assertThat(baseServlet.getFeedClassification("3"), is("stub_classification"));
+    }
+
+    @Test
+    public void Given_Request_Is_GetFeedClassification_And_Feed_Does_Not_Exist() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
+        assertThat(baseServlet.getFeedClassification("3"), is(nullValue()));
+    }
+
+    @Test
+    public void Given_Request_Is_GetSubscriptionOwner_And_Subscription_Exists() throws Exception {
+        PowerMockito.mockStatic(Subscription.class);
+        Subscription subscription = mock(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(subscription);
+        when(subscription.getSubscriber()).thenReturn("stub_subscriber");
+        assertThat(baseServlet.getSubscriptionOwner("3"), is("stub_subscriber"));
+    }
+
+    @Test
+    public void Given_Request_Is_GetSubscriptionOwner_And_Subscription_Does_Not_Exist() throws Exception {
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(null);
+        assertThat(baseServlet.getSubscriptionOwner("3"), is(nullValue()));
+    }
+
+    @Test
+    public void Given_Request_Is_GetGroupByFeedGroupId_And_User_Is_A_Member_Of_Group() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        when(feed.getGroupid()).thenReturn(3);
+        PowerMockito.mockStatic(Group.class);
+        Group group = mock(Group.class);
+        when(group.getMembers()).thenReturn("{id: stub_user}");
+        PowerMockito.when(Group.getGroupById(anyInt())).thenReturn(group);
+        when(group.getAuthid()).thenReturn("stub_authID");
+        assertThat(baseServlet.getGroupByFeedGroupId("stub_user", "3"), is("stub_authID"));
+    }
+
+    @Test
+    public void Given_Request_Is_GetGroupByFeedGroupId_And_User_Is_Not_A_Member_Of_Group() throws Exception {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        when(feed.getGroupid()).thenReturn(3);
+        PowerMockito.mockStatic(Group.class);
+        Group group = mock(Group.class);
+        when(group.getMembers()).thenReturn("{id: stub_otherUser}");
+        PowerMockito.when(Group.getGroupById(anyInt())).thenReturn(group);
+        when(group.getAuthid()).thenReturn("stub_authID");
+        assertThat(baseServlet.getGroupByFeedGroupId("stub_user", "3"), is(nullValue()));
+    }
+
+    @Test
+    public void Given_Request_Is_GetGroupBySubGroupId_And_User_Is_A_Member_Of_Group() throws Exception {
+        PowerMockito.mockStatic(Subscription.class);
+        Subscription subscription = mock(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(subscription);
+        when(subscription.getGroupid()).thenReturn(3);
+        PowerMockito.mockStatic(Group.class);
+        Group group = mock(Group.class);
+        when(group.getMembers()).thenReturn("{id: stub_user}");
+        PowerMockito.when(Group.getGroupById(anyInt())).thenReturn(group);
+        when(group.getAuthid()).thenReturn("stub_authID");
+        assertThat(baseServlet.getGroupBySubGroupId("stub_user", "3"), is("stub_authID"));
+    }
+
+    @Test
+    public void Given_Request_Is_GetGroupBySubGroupId_And_User_Is_Not_A_Member_Of_Group() throws Exception {
+        PowerMockito.mockStatic(Subscription.class);
+        Subscription subscription = mock(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(subscription);
+        when(subscription.getGroupid()).thenReturn(3);
+        PowerMockito.mockStatic(Group.class);
+        Group group = mock(Group.class);
+        when(group.getMembers()).thenReturn("{id: stub_otherUser}");
+        PowerMockito.when(Group.getGroupById(anyInt())).thenReturn(group);
+        when(group.getAuthid()).thenReturn("stub_authID");
+        assertThat(baseServlet.getGroupBySubGroupId("stub_user", "3"), is(nullValue()));
     }
 }
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServletTest.java
new file mode 100644 (file)
index 0000000..35bc85d
--- /dev/null
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.jetbrains.annotations.NotNull;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.Authorizer;
+import org.onap.dmaap.datarouter.provisioning.beans.Feed;
+import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
+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.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Mockito.*;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.provisioning.beans.Feed")
+public class DRFeedsServletTest extends DrServletTestBase {
+    private static DRFeedsServlet drfeedsServlet;
+
+    @Mock
+    private HttpServletRequest request;
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        drfeedsServlet = new DRFeedsServlet();
+        setAuthoriserToReturnRequestIsAuthorized();
+        setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
+        setupValidAuthorisedRequest();
+        setUpValidSecurityOnHttpRequest();
+        setUpValidContentHeadersAndJSONOnHttpRequest();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
+        drfeedsServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        drfeedsServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        drfeedsServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_URL_Path_Not_Valid_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getRequestURI()).thenReturn("/123");
+        drfeedsServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        drfeedsServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Fails_With_Valid_Name_And_Version() throws Exception {
+        when(request.getParameter("name")).thenReturn("stub_name");
+        when(request.getParameter("version")).thenReturn("stub_version");
+        drfeedsServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Succeeds_With_Valid_Name_And_Version() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getParameter("name")).thenReturn("stub_name");
+        when(request.getParameter("version")).thenReturn("stub_version");
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(feed);
+        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
+        drfeedsServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Succeeds_With_Invalid_Name_And_Version() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        drfeedsServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
+        drfeedsServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_URL_Path_Not_Valid_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getRequestURI()).thenReturn("/123");
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed; version=1.1");
+        when(request.getContentType()).thenReturn("stub_contentType");
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxFeeds", 0, true);
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Feed_Is_Not_Valid_Object_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
+        JSONObject JSObject = buildRequestJsonObject();
+
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                return jo;
+            }
+        };
+
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Feed_Already_Exists_Bad_Request_Response_Is_Generated() throws Exception {
+        setFeedToReturnInvalidFeedIdSupplied();
+        JSONObject JSObject = buildRequestJsonObject();
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return false;
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Change_On_Feeds_Succeeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        JSONObject JSObject = buildRequestJsonObject();
+        DRFeedsServlet drfeedsServlet = new DRFeedsServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return true;
+            }
+        };
+        drfeedsServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
+    }
+
+    @NotNull
+    private JSONObject buildRequestJsonObject() {
+        JSONObject JSObject = new JSONObject();
+        JSONArray endpointIDs = new JSONArray();
+        JSONObject JOEndpointIDs = new JSONObject();
+        JOEndpointIDs.put("id", "stub_endpoint_id");
+        JOEndpointIDs.put("password", "stub_endpoint_password");
+        endpointIDs.put(JOEndpointIDs);
+
+        JSONArray endpointAddresses = new JSONArray();
+        endpointAddresses.put("127.0.0.1");
+
+        JSObject.put("classification", "stub_classification");
+        JSObject.put("endpoint_ids", endpointIDs);
+        JSObject.put("endpoint_addrs", endpointAddresses);
+        return JSObject;
+    }
+
+    private void setUpValidSecurityOnHttpRequest() throws Exception {
+        when(request.isSecure()).thenReturn(true);
+        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        authAddressesAndNetworks.add(("127.0.0.1"));
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxFeeds", 100, true);
+    }
+
+    private void setBehalfHeader(String headerValue) {
+        when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
+    }
+
+    private void setValidPathInfoInHttpHeader() {
+        when(request.getPathInfo()).thenReturn("/123");
+    }
+
+    private void setFeedToReturnInvalidFeedIdSupplied() {
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
+        when(Feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(mock(Feed.class));
+    }
+
+    private void setFeedToReturnValidFeedForSuppliedId() {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        when(feed.isDeleted()).thenReturn(false);
+        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
+        when(feed.getPublisher()).thenReturn("Stub_Value");
+        when(feed.getName()).thenReturn("stub_name");
+        when(feed.getVersion()).thenReturn("1.0");
+        when(feed.asLimitedJSONObject()).thenReturn(mock(JSONObject.class));
+        PowerMockito.when(feed.getFeedByNameVersion(anyString(), anyString())).thenReturn(null);
+    }
+
+    private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(false);
+    }
+
+    private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(true);
+    }
+
+    private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
+        Poker poker = mock(Poker.class);
+        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+    }
+
+    private void setupValidAuthorisedRequest() throws Exception {
+        setUpValidSecurityOnHttpRequest();
+        setBehalfHeader("Stub_Value");
+        setValidPathInfoInHttpHeader();
+        setFeedToReturnValidFeedForSuppliedId();
+    }
+
+    private void setUpValidContentHeadersAndJSONOnHttpRequest() {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed; version=1.0");
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+
+    }
+}
index cf03512..414fc18 100644 (file)
@@ -38,6 +38,9 @@ public class DrServletTestBase {
     public void setUp() throws Exception {
         Properties props = new Properties();
         props.setProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
+        props.setProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir", "datarouter-prov/unit-test-logs");
+        props.setProperty("org.onap.dmaap.datarouter.provserver.spooldir", "resources/spooldir");
+        props.setProperty("org.onap.dmaap.datarouter.provserver.https.relaxation", "false");
         FieldUtils.writeDeclaredStaticField(DB.class, "props", props, true);
         FieldUtils.writeDeclaredStaticField(BaseServlet.class, "startmsgFlag", false, true);
         SynchronizerTask synchronizerTask = mock(SynchronizerTask.class);
old mode 100644 (file)
new mode 100755 (executable)
index d65b1f9..f5302cb
@@ -23,6 +23,8 @@
 package org.onap.dmaap.datarouter.provisioning;
 
 import org.apache.commons.lang3.reflect.FieldUtils;
+import org.jetbrains.annotations.NotNull;
+import org.json.JSONArray;
 import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
@@ -67,6 +69,7 @@ public class FeedServletTest extends DrServletTestBase {
         setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
         setUpValidAuthorisedRequest();
         setUpValidSecurityOnHttpRequest();
+        setUpValidContentHeadersAndJSONOnHttpRequest();
     }
 
     @Test
@@ -230,6 +233,7 @@ public class FeedServletTest extends DrServletTestBase {
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated()
         throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed-fail; version=2.0");
         when(request.getContentType()).thenReturn("stub_contentType");
         feedServlet.doPut(request, response);
         verify(response)
@@ -239,13 +243,161 @@ public class FeedServletTest extends DrServletTestBase {
     @Test
     public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated()
         throws Exception {
-        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed; version=1.0");
         ServletInputStream inStream = mock(ServletInputStream.class);
         when(request.getInputStream()).thenReturn(inStream);
         feedServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Invalid_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Feed_Change_Is_Not_Publisher_Who_Requested_Feed_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+        };
+
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Feed_Name_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "not_stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Feed_Version_Change_is_Requested_Bad_Request_Response_Is_Generated() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+        };
+        setAuthoriserToReturnRequestNotAuthorized();
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Fails_A_STATUS_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return false;
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Change_On_Feeds_Suceeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        JSONObject JSObject = buildRequestJsonObject();
+        FeedServlet feedServlet = new FeedServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "1.0");
+                jo.put("authorization", JSObject);
+                return jo;
+            }
+
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return true;
+            }
+        };
+        feedServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
+        feedServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @NotNull
+    private JSONObject buildRequestJsonObject() {
+        JSONObject JSObject = new JSONObject();
+        JSONArray endpointIDs = new JSONArray();
+        JSONObject JOEndpointIDs = new JSONObject();
+        JOEndpointIDs.put("id", "stub_endpoint_id");
+        JOEndpointIDs.put("password", "stub_endpoint_password");
+        endpointIDs.put(JOEndpointIDs);
+
+        JSONArray endpointAddresses = new JSONArray();
+        endpointAddresses.put("127.0.0.1");
+
+        JSObject.put("classification", "stub_classification");
+        JSObject.put("endpoint_ids", endpointIDs);
+        JSObject.put("endpoint_addrs", endpointAddresses);
+        return JSObject;
+    }
+
     private void setUpValidSecurityOnHttpRequest() throws Exception {
         when(request.isSecure()).thenReturn(true);
         Set<String> authAddressesAndNetworks = new HashSet<String>();
@@ -275,6 +427,10 @@ public class FeedServletTest extends DrServletTestBase {
         PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
         when(feed.isDeleted()).thenReturn(false);
         when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
+        when(feed.getPublisher()).thenReturn("Stub_Value");
+        when(feed.getName()).thenReturn("stub_name");
+        when(feed.getVersion()).thenReturn("1.0");
+        when(feed.asLimitedJSONObject()).thenReturn(mock(JSONObject.class));
     }
 
     private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
@@ -304,4 +460,9 @@ public class FeedServletTest extends DrServletTestBase {
         setValidPathInfoInHttpHeader();
         setFeedToReturnValidFeedForSuppliedId();
     }
+
+    private void setUpValidContentHeadersAndJSONOnHttpRequest() {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed; version=1.0");
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+    }
 }
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index ed0e257..a0831b7
@@ -55,6 +55,7 @@ import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
 @RunWith(PowerMockRunner.class)
 @SuppressStaticInitializationFor("org.onap.dmaap.datarouter.provisioning.beans.Group")
 public class GroupServletTest extends DrServletTestBase {
+
     private GroupServlet groupServlet;
 
     @Mock
@@ -68,7 +69,7 @@ public class GroupServletTest extends DrServletTestBase {
         super.setUp();
         groupServlet = new GroupServlet();
         setAuthoriserToReturnRequestIsAuthorized();
-        setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
+        setPokerToNotCreateTimers();
         setUpValidAuthorisedRequest();
     }
 
@@ -250,7 +251,7 @@ public class GroupServletTest extends DrServletTestBase {
         when(authResponse.isAuthorized()).thenReturn(true);
     }
 
-    private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
+    private void setPokerToNotCreateTimers() throws Exception {
         Poker poker = mock(Poker.class);
         FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
     }
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/InternalServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/InternalServletTest.java
new file mode 100644 (file)
index 0000000..104d137
--- /dev/null
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.Authorizer;
+import org.onap.dmaap.datarouter.provisioning.beans.*;
+import org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader;
+import org.onap.dmaap.datarouter.provisioning.utils.RLEBitSet;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.Feed", "org.onap.dmaap.datarouter.provisioning.beans.Parameters", "org.onap.dmaap.datarouter.provisioning.beans.NodeClass",
+                                  "org.onap.dmaap.datarouter.provisioning.beans.Subscription", "org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader"})
+public class InternalServletTest extends DrServletTestBase {
+    private InternalServlet internalServlet;
+
+    @Mock
+    private HttpServletRequest request;
+
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        internalServlet = new InternalServlet();
+        setAuthoriserToReturnRequestIsAuthorized();
+        setUpValidAuthorisedRequest();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getRemoteAddr()).thenReturn("127.100.0.3");
+        internalServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Halt_In_Endpoint_But_Not_Sent_From_Localhost_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/halt");
+        when(request.isSecure()).thenReturn(false);
+        when(request.getRemoteAddr()).thenReturn("127.100.0.3");
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_FORBIDDEN));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Halt_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/halt");
+        when(request.isSecure()).thenReturn(false);
+        when(request.getRemoteAddr()).thenReturn("127.0.0.1");
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_FetchProv_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/fetchProv");
+        when(request.isSecure()).thenReturn(false);
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Prov_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/prov");
+        when(request.getQueryString()).thenReturn(null);
+        setPokerToNotCreateTimers();
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Logs_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/logs/");
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_Starts_With_Logs_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/logs/TestFile");
+        internalServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NO_CONTENT), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(false);
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_With_Drlogs_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/drlogs/");
+        PowerMockito.mockStatic(LogfileLoader.class);
+        LogfileLoader logfileLoader = mock(LogfileLoader.class);
+        when(logfileLoader.getBitSet()).thenReturn(new RLEBitSet());
+        PowerMockito.when(LogfileLoader.getLoader()).thenReturn(logfileLoader);
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        internalServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_Incorrect_Endpoint_Then_No_Content_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect/");
+        internalServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getRemoteAddr()).thenReturn("127.100.0.3");
+        internalServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(false);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerSuccess();
+        setPokerToNotCreateTimers();
+        mockProvisioningParametersChanged();
+        internalServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_With_Api_In_Endpoint_And_Update_Fails_Then_Internal_Server_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(false);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerFailure();
+        internalServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect");
+        internalServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getRemoteAddr()).thenReturn("127.100.0.3");
+        internalServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(false);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerSuccess();
+        setPokerToNotCreateTimers();
+        mockProvisioningParametersChanged();
+        internalServlet.doDelete(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_With_Api_In_Endpoint_And_Delete_Fails_Then_Internal_Server_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(false);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerFailure();
+        internalServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect");
+        internalServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Address_Not_Authorized_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getRemoteAddr()).thenReturn("127.100.0.3");
+        internalServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_With_Api_In_Endpoint_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(true);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerSuccess();
+        setPokerToNotCreateTimers();
+        mockProvisioningParametersChanged();
+        internalServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_With_Api_In_Endpoint_And_Insert_Fails_Then_Internal_Server_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/api/Key");
+        setParametersToNotContactDb(true);
+        String[] values = {"V", "a", "l", "u", "e", "s"};
+        when(request.getParameterValues(anyString())).thenReturn(values);
+        internalServlet = internalServerFailure();
+        internalServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_To_Logs_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("stub_contentType");
+        when(request.getPathInfo()).thenReturn("/logs/");
+        internalServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_To_Logs_And_Content_Encoding_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Encoding")).thenReturn("not-supported");
+        when(request.getPathInfo()).thenReturn("/logs/");
+        internalServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_To_Drlogs_And_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("stub_contentType");
+        when(request.getPathInfo()).thenReturn("/drlogs/");
+        internalServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_To_Drlogs_And_Request_Succeeds() throws Exception {
+        when(request.getPathInfo()).thenReturn("/drlogs/");
+        ServletInputStream inStream = mock(ServletInputStream.class);
+        when(inStream.read()).thenReturn(1, -1);
+        when(request.getInputStream()).thenReturn(inStream);
+        internalServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_With_Incorrect_Endpoint_Then_Not_Found_Error_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn("/incorrect/");
+        internalServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(true);
+    }
+
+    private void setUpValidAuthorisedRequest() throws Exception {
+        setUpValidSecurityOnHttpRequest();
+        setBehalfHeader("Stub_Value");
+        setValidPathInfoInHttpHeader();
+        when(request.getHeader("Content-Type")).thenReturn("text/plain");
+        when(request.getHeader("Content-Encoding")).thenReturn("gzip");
+    }
+
+    private void setUpValidSecurityOnHttpRequest() throws Exception {
+        when(request.isSecure()).thenReturn(true);
+        when(request.getRemoteAddr()).thenReturn(InetAddress.getLocalHost().getHostAddress());
+        InetAddress[] nodeAddresses = new InetAddress[1];
+        nodeAddresses[0] = InetAddress.getLocalHost();
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodeAddresses", nodeAddresses, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
+    }
+
+    private void setBehalfHeader(String headerValue) {
+        when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
+    }
+
+    private void setValidPathInfoInHttpHeader() {
+        when(request.getPathInfo()).thenReturn("/123");
+    }
+
+    private void setPokerToNotCreateTimers() throws Exception {
+        Poker poker = mock(Poker.class);
+        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+    }
+
+    private void setParametersToNotContactDb(boolean isPost) {
+        PowerMockito.mockStatic(Parameters.class);
+        Parameters parameters = mock(Parameters.class);
+        if (isPost) {
+            PowerMockito.when(Parameters.getParameter(anyString())).thenReturn(null);
+        } else {
+            PowerMockito.when(Parameters.getParameter(anyString())).thenReturn(parameters);
+        }
+    }
+
+    private InternalServlet internalServerSuccess() {
+        InternalServlet internalServlet = new InternalServlet() {
+
+            protected boolean doUpdate(Updateable bean) {
+                return true;
+            }
+
+            protected boolean doDelete(Deleteable bean) {
+                return true;
+            }
+
+            protected boolean doInsert(Insertable bean) {
+                return true;
+            }
+        };
+        return internalServlet;
+    }
+
+    private InternalServlet internalServerFailure() {
+        InternalServlet internalServlet = new InternalServlet() {
+
+            protected boolean doUpdate(Updateable bean) {
+                return false;
+            }
+
+            protected boolean doDelete(Deleteable bean) {
+                return false;
+            }
+
+            protected boolean doInsert(Insertable bean) {
+                return false;
+            }
+        };
+        return internalServlet;
+    }
+
+    private void mockProvisioningParametersChanged() throws IllegalAccessException{
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Feed.countActiveFeeds()).thenReturn(0);
+        PowerMockito.when(Subscription.countActiveSubscriptions()).thenReturn(0);
+        Map<String, Integer> map = new HashMap<>();
+        FieldUtils.writeDeclaredStaticField(NodeClass.class, "map", map, true);
+    }
+}
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/LogServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/LogServletTest.java
new file mode 100755 (executable)
index 0000000..9a55059
--- /dev/null
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * ============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;
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+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 static org.hamcrest.CoreMatchers.notNullValue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.Subscription"})
+public class LogServletTest extends DrServletTestBase {
+
+    private static LogServlet logServlet;
+
+    @Mock
+    private HttpServletRequest request;
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logServlet = new LogServlet(true);
+        setUpValidParameterValuesForMap();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Is_Not_Allowed_Then_Forbidden_Response_Is_Generated()
+            throws Exception {
+        logServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_FeedID_Is_Invalid_Then_Bad_Request_Response_Is_Generated()
+            throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_Type()
+            throws Exception {
+        when(request.getParameter("type")).thenReturn("bad_type");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_PublishID()
+            throws Exception {
+        when(request.getParameter("publishId")).thenReturn("bad_PublishID'");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_StatusCode()
+            throws Exception {
+        when(request.getParameter("statusCode")).thenReturn("1'");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_ExpiryReason()
+            throws Exception {
+        when(request.getParameter("expiryReason")).thenReturn("bad_ExpiryReason");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_Start()
+            throws Exception {
+        when(request.getParameter("start")).thenReturn("bad_startTime");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Has_Bad_End()
+            throws Exception {
+        when(request.getParameter("end")).thenReturn("bad_endTime");
+        logServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Is_FeedLog()
+            throws Exception {
+        logServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Is_Not_FeedLog()
+            throws Exception {
+        LogServlet logServletNotFeedlog = new LogServlet(false);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(mock(Subscription.class));
+        logServletNotFeedlog.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Is_Not_Allowed_Then_Forbidden_Response_Is_Generated()
+            throws Exception {
+        logServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Is_Not_Allowed_Then_Forbidden_Response_Is_Generated()
+            throws Exception {
+        logServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_GetPublishRecordsForFeed_And_Type_Is_Publish()
+            throws Exception {
+        when(request.getParameter("type")).thenReturn("pub");
+        when(request.getParameter("expiryReason")).thenReturn(null);
+        logServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_getDeliveryRecordsForFeed_And_Type_Is_Delivery()
+            throws Exception {
+        when(request.getParameter("type")).thenReturn("del");
+        when(request.getParameter("expiryReason")).thenReturn(null);
+        logServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_getExpiryRecordsForFeed_And_Type_Is_Expire()
+            throws Exception {
+        when(request.getParameter("type")).thenReturn("exp");
+        when(request.getParameter("statusCode")).thenReturn(null);
+        when(request.getParameter("expiryReason")).thenReturn(null);
+        ServletOutputStream s = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(s);
+        logServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_getDeliveryRecordsForSubscription_And_Type_Is_Delivery()
+            throws Exception {
+        LogServlet logServletNotFeedlog = new LogServlet(false);
+        when(request.getParameter("type")).thenReturn("del");
+        when(request.getParameter("statusCode")).thenReturn(null);
+        when(request.getParameter("expiryReason")).thenReturn(null);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(mock(Subscription.class));
+        logServletNotFeedlog.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_getExpiryRecordsForSubscription_And_Type_Is_Expiry()
+            throws Exception {
+        LogServlet logServletNotFeedlog = new LogServlet(false);
+        when(request.getParameter("type")).thenReturn("exp");
+        when(request.getParameter("statusCode")).thenReturn(null);
+        when(request.getParameter("expiryReason")).thenReturn(null);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(mock(Subscription.class));
+        logServletNotFeedlog.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    private void setUpValidParameterValuesForMap() throws Exception {
+        when(request.getPathInfo()).thenReturn("123");
+        when(request.getParameter("type")).thenReturn("exp");
+        when(request.getParameter("publishId")).thenReturn("bad_PublishID");
+        when(request.getParameter("statusCode")).thenReturn("-1");
+        when(request.getParameter("expiryReason")).thenReturn("other");
+        when(request.getParameter("start")).thenReturn(null);
+        when(request.getParameter("end")).thenReturn(null);
+        ServletOutputStream s = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(s);
+    }
+}
\ No newline at end of file
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/PublishServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/PublishServletTest.java
new file mode 100755 (executable)
index 0000000..92403ac
--- /dev/null
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.Authorizer;
+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.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
+/**
+ * Created by ezcoxem on 21/08/2018.
+ */
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.provisioning.beans.Feed")
+public class PublishServletTest extends DrServletTestBase {
+    private PublishServlet publishServlet;
+
+    private static String START_JSON_STRING = "{";
+    private static String END_JSON_STRING = "}";
+    private static String START_JSON_ARRAY = "[";
+    private static String END_JSON_ARRAY = "]";
+    private static String COMMA = ",";
+
+    @Mock
+    private HttpServletRequest request;
+
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        publishServlet = new PublishServlet();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_There_Are_No_Nodes_Then_Service_Unavailable_Error_Is_Returned()
+            throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[0], true);
+        publishServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_SERVICE_UNAVAILABLE), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Path_Is_Null_Then_Not_Found_Error_Is_Returned()
+            throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[1], true);
+        publishServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Ix_Is_Null_Then_Not_Found_Error_Is_Returned()
+            throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[1], true);
+        when(request.getPathInfo()).thenReturn("/123/");
+        publishServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Feed_Is_Not_Valid_Then_Not_Found_Error_Is_Returned()
+            throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[1], true);
+        when(request.getPathInfo()).thenReturn("/123/fileName.txt");
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.isFeedValid(anyInt())).thenReturn(false);
+        publishServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Feed_Is_Not_A_Number_Then_Not_Found_Error_Is_Returned()
+            throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[1], true);
+        when(request.getPathInfo()).thenReturn("/abc/fileName.txt");
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.isFeedValid(anyInt())).thenReturn(false);
+        publishServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_All_Ok_Then_Request_succeeds()
+            throws Exception {
+        setConditionsForPositiveSuccessFlow();
+        when(request.getHeader(anyString())).thenReturn("Basic dXNlcg==");
+        publishServlet.doDelete(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_MOVED_PERMANENTLY));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_succeeds()
+            throws Exception {
+        setConditionsForPositiveSuccessFlow();
+
+        publishServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_MOVED_PERMANENTLY));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_succeeds()
+            throws Exception {
+        setConditionsForPositiveSuccessFlow();
+
+        publishServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_MOVED_PERMANENTLY));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_succeeds()
+            throws Exception {
+        setConditionsForPositiveSuccessFlow();
+
+        publishServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_MOVED_PERMANENTLY));
+    }
+
+    private void setConditionsForPositiveSuccessFlow() throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "nodes", new String[1], true);
+        FieldUtils.writeDeclaredField(publishServlet, "next_node", 0, true);
+        FieldUtils.writeDeclaredField(publishServlet, "provstring", "", true);
+        FieldUtils.writeDeclaredField(publishServlet, "irt", new ArrayList<IngressRoute>(), true);
+        FieldUtils.writeDeclaredStaticField(NodeClass.class, "map", new HashMap<String,String>(), true);
+        when(request.getPathInfo()).thenReturn("/123/fileName.txt");
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.isFeedValid(anyInt())).thenReturn(true);
+        setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
+    }
+
+    private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
+        Poker poker = mock(Poker.class);
+        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+        when(poker.getProvisioningString()).thenReturn(buildProvisioningString());
+    }
+
+
+    private String buildProvisioningString(){
+        StringBuffer provisionString = new StringBuffer();
+        provisionString.append(START_JSON_STRING);
+        provisionString.append("'ingress':");
+        provisionString.append(START_JSON_ARRAY);
+        provisionString.append(buildIngressRoute());
+        provisionString.append(END_JSON_ARRAY);
+        provisionString.append(END_JSON_STRING);
+        return provisionString.toString();
+    }
+
+    private StringBuffer buildIngressRoute(){
+        StringBuffer provisionString = new StringBuffer();
+        provisionString.append(START_JSON_STRING);
+        provisionString.append("'seq':1");
+        provisionString.append(COMMA);
+        provisionString.append("'feedid':123");
+        provisionString.append(COMMA);
+        provisionString.append("'user':'user'");
+        provisionString.append(COMMA);
+        provisionString.append("'subnet':'127.0.0.1'");
+        provisionString.append(COMMA);
+        provisionString.append("'nodelist':-1");
+        provisionString.append(COMMA);
+        provisionString.append("'node':['1','2']");
+        provisionString.append(END_JSON_STRING);
+        return provisionString;
+    }
+
+
+}
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/RouteServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/RouteServletTest.java
new file mode 100755 (executable)
index 0000000..6371580
--- /dev/null
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.json.JSONObject;
+import org.junit.Before;
+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;
+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
+{
+    private RouteServlet routeServlet;
+
+    @Mock
+    private HttpServletRequest request;
+
+    @Mock
+    private HttpServletResponse response;
+
+    @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 {
+        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 {
+        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 {
+        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 {
+        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)));
+    }
+
+    @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)));
+    }
+
+    @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)));
+    }
+
+    @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)));
+    }
+
+    @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)));
+    }
+
+    @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 {
+        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");
+        RouteServlet routeServlet = new RouteServlet() {
+            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
+                return true;
+            }
+
+            @Override
+            protected boolean doDelete(Deleteable bean) {
+                return false;
+            }
+        };
+        routeServlet.doDelete(request, response);
+        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 {
+        routeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @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)));
+    }
+
+
+    @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));
+    }
+
+    @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));
+    }
+
+    @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 {
+        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)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Is_Not_Authorized() throws Exception {
+        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 {
+        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 {
+        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;
+            }
+        };
+        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 {
+        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)));
+    }
+
+    @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)));
+    }
+
+    @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)));
+    }
+
+    @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)));
+    }
+
+    @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");
+        RouteServlet routeServlet = new RouteServlet() {
+            protected boolean isAuthorizedForInternal(HttpServletRequest req) {
+                return true;
+            }
+
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                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);
+    }
+}
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscribeServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscribeServletTest.java
new file mode 100644 (file)
index 0000000..c663451
--- /dev/null
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.jetbrains.annotations.NotNull;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.Authorizer;
+import org.onap.dmaap.datarouter.provisioning.beans.Feed;
+import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
+import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+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.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Mockito.*;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor({"org.onap.dmaap.datarouter.provisioning.beans.Feed", "org.onap.dmaap.datarouter.provisioning.beans.Subscription"})
+public class SubscribeServletTest extends DrServletTestBase {
+    private static SubscribeServlet subscribeServlet;
+
+    @Mock
+    private HttpServletRequest request;
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        subscribeServlet = new SubscribeServlet();
+        setAuthoriserToReturnRequestIsAuthorized();
+        setPokerToNotCreateTimersWhenDeleteFeedIsCalled();
+        setupValidAuthorisedRequest();
+        setUpValidSecurityOnHttpRequest();
+        setUpValidContentHeadersAndJSONOnHttpRequest();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
+        subscribeServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscribeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscribeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscribeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setFeedToReturnInvalidFeedIdSupplied();
+        subscribeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscribeServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        PowerMockito.mockStatic(Subscription.class);
+        List<String> list = new ArrayList<String>();
+        list.add("{}");
+        PowerMockito.when(Subscription.getSubscriptionUrlList(anyInt())).thenReturn(list);
+        subscribeServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_SC_METHOD_NOT_ALLOWED_Response_Is_Generated() throws Exception {
+        subscribeServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_METHOD_NOT_ALLOWED), argThat(notNullValue(String.class)));
+    }
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscribeServlet.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_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Feed_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setFeedToReturnInvalidFeedIdSupplied();
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.feed; version=1.1");
+        when(request.getContentType()).thenReturn("stub_contentType");
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Active_Feeds_Equals_Max_Feeds_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 0, true);
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                return new JSONObject();
+            }
+        };
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_CONFLICT), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_POST_Fails_Bad_Request_Response_Is_Generated() throws Exception {
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionMatching(mock(Subscription.class))).thenReturn(null);
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", false);
+                return jo;
+            }
+
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return false;
+            }
+        };
+        subscribeServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Change_On_Feeds_Succeeds_A_STATUS_OK_Response_Is_Generated() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionMatching(mock(Subscription.class))).thenReturn(null);
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscribeServlet subscribeServlet = new SubscribeServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", true);
+                return jo;
+            }
+
+            @Override
+            protected boolean doInsert(Insertable bean) {
+                return true;
+            }
+        };
+        subscribeServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_CREATED));
+    }
+
+
+    @NotNull
+    private JSONObject buildRequestJsonObject() {
+        JSONObject JSObject = new JSONObject();
+        JSObject.put("url", "https://stub_address");
+        JSObject.put("use100", "true");
+        JSObject.put("password", "stub_password");
+        JSObject.put("user", "stub_user");
+        return JSObject;
+    }
+
+    private void setUpValidSecurityOnHttpRequest() throws Exception {
+        when(request.isSecure()).thenReturn(true);
+        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        authAddressesAndNetworks.add(("127.0.0.1"));
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "maxSubs", 1, true);
+    }
+
+    private void setBehalfHeader(String headerValue) {
+        when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
+    }
+
+    private void setValidPathInfoInHttpHeader() {
+        when(request.getPathInfo()).thenReturn("/123");
+    }
+
+    private void setFeedToReturnInvalidFeedIdSupplied() {
+        PowerMockito.mockStatic(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(null);
+    }
+
+    private void setFeedToReturnValidFeedForSuppliedId() {
+        PowerMockito.mockStatic(Feed.class);
+        Feed feed = mock(Feed.class);
+        PowerMockito.when(Feed.getFeedById(anyInt())).thenReturn(feed);
+        when(feed.isDeleted()).thenReturn(false);
+        when(feed.asJSONObject(true)).thenReturn(mock(JSONObject.class));
+        when(feed.getPublisher()).thenReturn("Stub_Value");
+        when(feed.getName()).thenReturn("stub_name");
+        when(feed.getVersion()).thenReturn("1.0");
+        when(feed.asLimitedJSONObject()).thenReturn(mock(JSONObject.class));
+    }
+
+    private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(false);
+    }
+
+    private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(true);
+    }
+
+    private void setPokerToNotCreateTimersWhenDeleteFeedIsCalled() throws Exception {
+        Poker poker = mock(Poker.class);
+        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+    }
+
+    private void setupValidAuthorisedRequest() throws Exception {
+        setUpValidSecurityOnHttpRequest();
+        setBehalfHeader("Stub_Value");
+        setValidPathInfoInHttpHeader();
+        setFeedToReturnValidFeedForSuppliedId();
+    }
+
+    private void setUpValidContentHeadersAndJSONOnHttpRequest() {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+
+    }
+}
diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java
new file mode 100644 (file)
index 0000000..b42e3a7
--- /dev/null
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * ============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;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.jetbrains.annotations.NotNull;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.Authorizer;
+import org.onap.dmaap.datarouter.provisioning.beans.Deleteable;
+import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
+import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Mockito.*;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
+
+@RunWith(PowerMockRunner.class)
+@SuppressStaticInitializationFor("org.onap.dmaap.datarouter.provisioning.beans.Subscription")
+public class SubscriptionServletTest extends DrServletTestBase {
+    private SubscriptionServlet subscriptionServlet;
+
+    @Mock
+    private HttpServletRequest request;
+    @Mock
+    private HttpServletResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        subscriptionServlet = new SubscriptionServlet();
+        setAuthoriserToReturnRequestIsAuthorized();
+        setPokerToNotCreateTimersWhenDeleteSubscriptionIsCalled();
+        setupValidAuthorisedRequest();
+        setUpValidSecurityOnHttpRequest();
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_SC_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setSubscriptionToReturnInvalidSubscriptionIdSupplied();
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Fails_An_Internal_Server_Error_Is_Reported() throws Exception {
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet(){
+            public boolean doDelete(Deleteable deletable){
+                return false;
+            }
+        };
+        subscriptionServlet.doDelete(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_And_Delete_On_Database_Succeeds_A_NO_CONTENT_Response_Is_Generated() throws Exception {
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet(){
+            public boolean doDelete(Deleteable deletable){
+                return true;
+            }
+        };
+        subscriptionServlet.doDelete(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_NO_CONTENT));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscriptionServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscriptionServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscriptionServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setSubscriptionToReturnInvalidSubscriptionIdSupplied();
+        subscriptionServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscriptionServlet.doGet(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_GET_And_Request_Succeeds() throws Exception {
+        JSONObject JSObject = buildRequestJsonObject();
+        JSONObject jo = new JSONObject();
+        jo.put("name", "stub_name");
+        jo.put("version", "2.0");
+        jo.put("metadataOnly", true);
+        jo.put("suspend", true);
+        jo.put("delivery", JSObject);
+        jo.put("sync", true);
+        Subscription sub = new Subscription(jo);
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(sub);
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        subscriptionServlet.doGet(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Path_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setSubscriptionToReturnInvalidSubscriptionIdSupplied();
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getContentType()).thenReturn("stub_ContentType");
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        ServletInputStream inStream = mock(ServletInputStream.class);
+        when(request.getInputStream()).thenReturn(inStream);
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Subscription_Object_Is_Invalid_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                return jo;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Subscriber_Modified_By_Different_Creator() throws Exception {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn(null);
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", true);
+                return jo;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Update_Fails() throws Exception {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", true);
+                return jo;
+            }
+
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return false;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_PUT_And_Update_Succeeds() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("sync", true);
+                return jo;
+            }
+
+            @Override
+            protected boolean doUpdate(Updateable bean) {
+                return true;
+            }
+        };
+        subscriptionServlet.doPut(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Is_Not_Secure_When_HTTPS_Is_Required_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_BEHALF_HEADER_Is_Not_Set_In_Request_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        setBehalfHeader(null);
+        subscriptionServlet.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_Header_Is_Not_Set_In_Request_With_Valid_Path_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getPathInfo()).thenReturn(null);
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Subscription_Id_Is_Invalid_Then_Not_Found_Response_Is_Generated() throws Exception {
+        setSubscriptionToReturnInvalidSubscriptionIdSupplied();
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Content_Header_Is_Not_Supported_Type_Then_Unsupported_Media_Type_Response_Is_Generated() throws Exception {
+        when(request.getContentType()).thenReturn("stub_ContentType");
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Is_Not_Authorized_Then_Forbidden_Response_Is_Generated() throws Exception {
+        when(request.getHeader(anyString())).thenReturn("application/vnd.att-dr.subscription-control");
+        setAuthoriserToReturnRequestNotAuthorized();
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Request_Contains_Badly_Formed_JSON_Then_Bad_Request_Response_Is_Generated() throws Exception {
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription-control; version=1.0");
+        ServletInputStream inStream = mock(ServletInputStream.class);
+        when(request.getInputStream()).thenReturn(inStream);
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Post_Fails() throws Exception {
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription-control; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                return jo;
+            }
+        };
+        subscriptionServlet.doPost(request, response);
+        verify(response).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), argThat(notNullValue(String.class)));
+    }
+
+    @Test
+    public void Given_Request_Is_HTTP_POST_And_Post_Succeeds() throws Exception {
+        ServletOutputStream outStream = mock(ServletOutputStream.class);
+        when(response.getOutputStream()).thenReturn(outStream);
+        when(request.getHeader("X-ATT-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_subjectGroup");
+        when(request.getHeader("Content-Type")).thenReturn("application/vnd.att-dr.subscription-control; version=1.0");
+        JSONObject JSObject = buildRequestJsonObject();
+        SubscriptionServlet subscriptionServlet = new SubscriptionServlet() {
+            protected JSONObject getJSONfromInput(HttpServletRequest req) {
+                JSONObject jo = new JSONObject();
+                jo.put("name", "stub_name");
+                jo.put("version", "2.0");
+                jo.put("metadataOnly", true);
+                jo.put("suspend", true);
+                jo.put("delivery", JSObject);
+                jo.put("failed", false);
+                return jo;
+            }
+        };
+        subscriptionServlet.doPost(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_ACCEPTED));
+    }
+
+    @NotNull
+    private JSONObject buildRequestJsonObject() {
+        JSONObject JSObject = new JSONObject();
+        JSObject.put("url", "https://stub_address");
+        JSObject.put("use100", "true");
+        JSObject.put("password", "stub_password");
+        JSObject.put("user", "stub_user");
+        return JSObject;
+    }
+
+    private void setUpValidSecurityOnHttpRequest() throws Exception {
+        when(request.isSecure()).thenReturn(true);
+        Set<String> authAddressesAndNetworks = new HashSet<String>();
+        authAddressesAndNetworks.add(("127.0.0.1"));
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authorizedAddressesAndNetworks", authAddressesAndNetworks, true);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "requireCert", false, true);
+    }
+
+    private void setBehalfHeader(String headerValue) {
+        when(request.getHeader(BEHALF_HEADER)).thenReturn(headerValue);
+    }
+
+    private void setValidPathInfoInHttpHeader() {
+        when(request.getPathInfo()).thenReturn("/123");
+    }
+
+    private void setSubscriptionToReturnInvalidSubscriptionIdSupplied() {
+        PowerMockito.mockStatic(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(null);
+    }
+
+    private void setSubscriptionToReturnValidSubscriptionForSuppliedId() {
+        PowerMockito.mockStatic(Subscription.class);
+        Subscription subscription = mock(Subscription.class);
+        PowerMockito.when(Subscription.getSubscriptionById(anyInt())).thenReturn(subscription);
+        when(subscription.getSubscriber()).thenReturn("Stub_Value");
+        when(subscription.asJSONObject()).thenReturn(mock(JSONObject.class));
+    }
+
+    private void setAuthoriserToReturnRequestNotAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(false);
+    }
+
+    private void setAuthoriserToReturnRequestIsAuthorized() throws IllegalAccessException {
+        AuthorizationResponse authResponse = mock(AuthorizationResponse.class);
+        Authorizer authorizer = mock(Authorizer.class);
+        FieldUtils.writeDeclaredStaticField(BaseServlet.class, "authz", authorizer, true);
+        when(authorizer.decide(request)).thenReturn(authResponse);
+        when(authResponse.isAuthorized()).thenReturn(true);
+    }
+
+    private void setPokerToNotCreateTimersWhenDeleteSubscriptionIsCalled() throws Exception {
+        Poker poker = mock(Poker.class);
+        FieldUtils.writeDeclaredStaticField(Poker.class, "poker", poker, true);
+    }
+
+    private void setupValidAuthorisedRequest() throws Exception {
+        setUpValidSecurityOnHttpRequest();
+        setBehalfHeader("Stub_Value");
+        setValidPathInfoInHttpHeader();
+        setSubscriptionToReturnValidSubscriptionForSuppliedId();
+    }
+}
\ No newline at end of file
index 44d7b4c..33ae168 100644 (file)
@@ -68,16 +68,129 @@ Request Parameters:
 | Authorization          | Information for authorizing     |     Body         |   Object   |              |     Y       |                     |                                      |\r
 |                        | publishing requests             |                  |            |              |             |                     |                                      |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| suspend                | Set to true if the feed is in   |     Body         |   Boolean  |              |     N       |                     | true                                 |\r
-|                        | the suspended state             |                  |            |              |             |                     | false                                |\r
+| suspend                | Set to true if the feed is in   |     Body         |   Boolean  |              |     N       |                     | * true                               |\r
+|                        | the suspended state             |                  |            |              |             |                     | * false                              |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
 | group-id               |                                 |     Body         |   Integer  |              |     Y       |                     |                                      |\r
 |                        |                                 |                  |            |              |             |                     |                                      |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| content-type           | To specify type of message      |     Header       |   String   |     20       |     N       |                     | application/vnd.att-dr.subscription  |\r
+| content-type           | To specify type of message      |     Header       |   String   |     20       |     N       |                     | application/vnd.att-dr.feed          |\r
 |                        | (feed,subscriber,publisher)     |                  |            |              |             |                     |                                      |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| X-ATT-DR-ON-BEHALF-OF  | User id of subscriber           |     Header       |   String   |     1        |     N       |                     |  username                            |\r
+| X-ATT-DR-ON-BEHALF-OF  | User id of owner of feed        |     Header       |   String   |     1        |     N       |                     |  username                            |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+\r
+Response/Error Codes\r
+====================\r
+\r
++------------------------+-------------------------------------------+\r
+| Response statusCode    | Response Description                      |\r
++========================+===========================================+\r
+| 201                    | Successful query                          |\r
++------------------------+-------------------------------------------+\r
+| 400                    | Bad request - The request is defective in |\r
+|                        | some way. Possible causes:                |\r
+|                        |                                           |\r
+|                        | * JSON object in request body does not    |\r
+|                        |   conform to the spec.                    |\r
+|                        | * Invalid parameter value in query string |\r
++------------------------+-------------------------------------------+\r
+| 401                    | Indicates that the request was missing the|\r
+|                        | Authorization header or, if the header    |\r
+|                        | was presented, the credentials were not   |\r
+|                        | acceptable                                |\r
++------------------------+-------------------------------------------+\r
+| 403                    | The request failed authorization.         |\r
+|                        | Possible causes:                          |\r
+|                        |                                           |\r
+|                        | * Request originated from an unauthorized |\r
+|                        |   IP address                              |\r
+|                        | * Client certificate subject is not on    |\r
+|                        |   the API’s authorized list.              |\r
+|                        | * X-ATT-DR-ON-BEHALF-OF identity is not   |\r
+|                        |   authorized to perform                   |\r
++------------------------+-------------------------------------------+\r
+| 404                    | Not Found - The Request-URI does not point|\r
+|                        | to a resource that is known to the API.   |\r
++------------------------+-------------------------------------------+\r
+| 405                    | Method Not Allowed - The HTTP method in   |\r
+|                        | the request is not supported for the      |\r
+|                        | resource addressed by the Request-URI.    |\r
++------------------------+-------------------------------------------+\r
+| 415                    | Unsupported Media Type - The media type in|\r
+|                        | the requests Content-Type header is not   |\r
+|                        | appropriate for the request.              |\r
++------------------------+-------------------------------------------+\r
+| 500                    | Internal Server Error - The DR API server |\r
+|                        | encountered an internal error and could   |\r
+|                        | not complete the request.                 |\r
++------------------------+-------------------------------------------+\r
+| 503                    | Service Unavailable - The DR API service  |\r
+|                        | is currently unavailable                  |\r
++------------------------+-------------------------------------------+\r
+| -1                     | Failed Delivery                           |\r
++------------------------+-------------------------------------------+\r
+\r
+Sample Body\r
+===========\r
+.. code-block:: json\r
+\r
+ {\r
+     "name": "Jettydemo",\r
+     "version": "m1.0",\r
+     "description": "Jettydemo",\r
+     "business_description": "Jettydemo",\r
+     "suspend": false,\r
+     "deleted": false,\r
+     "changeowner": true,\r
+     "authorization": {\r
+          "classification": "unclassified",\r
+          "endpoint_addrs": [\r
+               "172.18.0.3",\r
+            ],\r
+          "endpoint_ids": [\r
+               {\r
+                    "password": "password",\r
+                    "id": "user"\r
+               }\r
+          ]\r
+     },\r
+\r
+}\r
+\r
+Updating a Feed\r
+---------------\r
+\r
+**Description**: Update a feed with new parameters.\r
+\r
+Sample Request\r
+==============\r
+\r
+curl -v -X PUT -H "Content-Type: application/vnd.att-dr.feed" -H "X-ATT-DR-ON-BEHALF-OF: {user}" --data-ascii @/opt/app/datartr/addFeed3.txt --location-trusted -k https:/{host}:{port}\r
+\r
+Request Parameters:\r
+===================\r
+\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| Name                   | Description                     |  Param Type      |  Data Type |   MaxLen     |  Required   |  Format             |  Valid/Example Values                |\r
++========================+=================================+==================+============+==============+=============+=====================+======================================+\r
+| description            | Feed description                |     Body         |   String   |              |     Y       |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| business description   | Business description            |     Body         |   String   |              |     Y       |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| Authorization          | Information for authorizing     |     Body         |   Object   |              |     Y       |                     |                                      |\r
+|                        | publishing requests             |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| suspend                | Set to true if the feed is in   |     Body         |   Boolean  |              |     N       |                     | * true                               |\r
+|                        | the suspended state             |                  |            |              |             |                     | * false                              |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| group-id               |                                 |     Body         |   Integer  |              |     Y       |                     |                                      |\r
+|                        |                                 |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| content-type           | To specify type of message      |     Header       |   String   |     20       |     N       |                     | application/vnd.att-dr.feed          |\r
+|                        | (feed,subscriber,publisher)     |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| X-ATT-DR-ON-BEHALF-OF  | User id of owner of feed        |     Header       |   String   |     1        |     N       |                     |  username                            |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
 \r
 Response/Error Codes\r
@@ -158,7 +271,6 @@ Sample Body
 \r
 }\r
 \r
-\r
 Get a Feed\r
 ----------\r
 \r
@@ -169,7 +281,7 @@ Request URL
 \r
 http[s]://{host}:{port}/feed/{feedId}\r
 \r
-* {feedId}: Id of the feed you wish to see a representation of\r
+* {feedId}: Id of the feed you want to see a representation of\r
 \r
 Sample Request\r
 ==============\r
@@ -220,6 +332,66 @@ Response/Error Codes
 | -1                     | Failed Delivery                           |\r
 +------------------------+-------------------------------------------+\r
 \r
+Delete a Feed\r
+-------------\r
+\r
+**Description**: Deletes a specified feed\r
+\r
+Request URL\r
+===========\r
+\r
+http[s]://{host}:{port}/feed/{feedId}\r
+\r
+* {feedId}: Id of the feed you want to delete\r
+\r
+Sample Request\r
+==============\r
+\r
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/feed/{feedId}\r
+\r
+Response/Error Codes\r
+====================\r
+\r
++------------------------+-------------------------------------------+\r
+| Response statusCode    | Response Description                      |\r
++========================+===========================================+\r
+| 204                    | Successful query                          |\r
++------------------------+-------------------------------------------+\r
+| 401                    | Indicates that the request was missing the|\r
+|                        | Authorization header or, if the header    |\r
+|                        | was presented, the credentials were not   |\r
+|                        | acceptable                                |\r
++------------------------+-------------------------------------------+\r
+| 403                    | The request failed authorization.         |\r
+|                        | Possible causes:                          |\r
+|                        |                                           |\r
+|                        | * Request originated from an unauthorized |\r
+|                        |   IP address                              |\r
+|                        | * Client certificate subject is not on    |\r
+|                        |   the API’s authorized list.              |\r
+|                        | * X-ATT-DR-ON-BEHALF-OF identity is not   |\r
+|                        |   authorized to perform                   |\r
++------------------------+-------------------------------------------+\r
+| 404                    | Not Found - The Request-URI does not point|\r
+|                        | to a resource that is known to the API.   |\r
++------------------------+-------------------------------------------+\r
+| 405                    | Method Not Allowed - The HTTP method in   |\r
+|                        | the request is not supported for the      |\r
+|                        | resource addressed by the Request-URI.    |\r
++------------------------+-------------------------------------------+\r
+| 415                    | Unsupported Media Type - The media type in|\r
+|                        | the request’s Content-Type header is not  |\r
+|                        | appropriate for the request.              |\r
++------------------------+-------------------------------------------+\r
+| 500                    | Internal Server Error - The DR API server |\r
+|                        | encountered an internal error and could   |\r
+|                        | not complete the request.                 |\r
++------------------------+-------------------------------------------+\r
+| 503                    | Service Unavailable - The DR API service  |\r
+|                        | is currently unavailable                  |\r
++------------------------+-------------------------------------------+\r
+| -1                     | Failed Delivery                           |\r
++------------------------+-------------------------------------------+\r
 \r
 \r
 Subscribe to Feed\r
@@ -249,14 +421,128 @@ Request Parameters:
 | delivery               | Address and credentials for     |     Body         |   Object   |              |     Y       |                     |                                      |\r
 |                        | delivery                        |                  |            |              |             |                     |                                      |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| follow_redirect        | Set to true if feed redirection |     Body         |   Boolean  |              |     Y       |                     | true                                 |\r
-|                        | is expected                     |                  |            |              |             |                     | false                                |\r
+| follow_redirect        | Set to true if feed redirection |     Body         |   Boolean  |              |     Y       |                     | * true                               |\r
+|                        | is expected                     |                  |            |              |             |                     | * false                              |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| metadata_only          | Set to true if subscription is  |     Body         |   Boolean  |              |     Y       |                     | * true                               |\r
+|                        | to receive per-file metadata    |                  |            |              |             |                     | * false                              |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| suspend                | Set to true if the subscription |     Body         |   Boolean  |              |     N       |                     | * true                               |\r
+|                        | is in the suspended state       |                  |            |              |             |                     | * false                              |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| group-id               |                                 |     Body         |   Integer  |              |     Y       |                     |                                      |\r
+|                        |                                 |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| content-type           | To specify type of message      |     Header       |   String   |     20       |     N       |                     | application/vnd.att-dr.subscription  |\r
+|                        | (feed,subscriber,publisher)     |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| X-ATT-DR-ON-BEHALF-OF  | User id of subscriber           |     Header       |   String   |     1        |     N       |                     |  username                            |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+\r
+Response/Error Codes\r
+====================\r
+\r
++------------------------+-------------------------------------------+\r
+| Response statusCode    | Response Description                      |\r
++========================+===========================================+\r
+| 201                    | Successful query                          |\r
++------------------------+-------------------------------------------+\r
+| 400                    | Bad request - The request is defective in |\r
+|                        | some way. Possible causes:                |\r
+|                        |                                           |\r
+|                        | * JSON object in request body does not    |\r
+|                        |   conform to the spec.                    |\r
+|                        | * Invalid parameter value in query string |\r
++------------------------+-------------------------------------------+\r
+| 401                    | Indicates that the request was missing the|\r
+|                        | Authorization header or, if the header    |\r
+|                        | was presented, the credentials were not   |\r
+|                        | acceptable                                |\r
++------------------------+-------------------------------------------+\r
+| 403                    | The request failed authorization.         |\r
+|                        | Possible causes:                          |\r
+|                        |                                           |\r
+|                        | * Request originated from an unauthorized |\r
+|                        |   IP address                              |\r
+|                        | * Client certificate subject is not on    |\r
+|                        |   the API’s authorized list.              |\r
+|                        | * X-ATT-DR-ON-BEHALF-OF identity is not   |\r
+|                        |   authorized to perform                   |\r
++------------------------+-------------------------------------------+\r
+| 404                    | Not Found - The Request-URI does not point|\r
+|                        | to a resource that is known to the API.   |\r
++------------------------+-------------------------------------------+\r
+| 405                    | Method Not Allowed - The HTTP method in   |\r
+|                        | the request is not supported for the      |\r
+|                        | resource addressed by the Request-URI.    |\r
++------------------------+-------------------------------------------+\r
+| 415                    | Unsupported Media Type - The media type in|\r
+|                        | the requests Content-Type header is not   |\r
+|                        | appropriate for the request.              |\r
++------------------------+-------------------------------------------+\r
+| 500                    | Internal Server Error - The DR API server |\r
+|                        | encountered an internal error and could   |\r
+|                        | not complete the request.                 |\r
++------------------------+-------------------------------------------+\r
+| 503                    | Service Unavailable - The DR API service  |\r
+|                        | is currently unavailable                  |\r
++------------------------+-------------------------------------------+\r
+| -1                     | Failed Delivery                           |\r
++------------------------+-------------------------------------------+\r
+\r
+Sample Body\r
+===========\r
+.. code-block:: json\r
+\r
+ {\r
+    "delivery" :{\r
+        "url" : "http://172.18.0.3:7070/",\r
+        "user" : "LOGIN",\r
+        "password" : "PASSWORD",\r
+        "use100" : true\r
+    },\r
+    "metadataOnly" : false,\r
+    "suspend" : false,\r
+    "groupid" : 29,\r
+    "subscriber" : "subscriber123"\r
+\r
+}\r
+\r
+Update subscription\r
+-------------------\r
+\r
+**Description**: Update a subscription to a feed.\r
+\r
+Request URL\r
+===========\r
+\r
+http[s]://{host}:{port}/subscribe/{feedId}\r
+\r
+Sample Request\r
+==============\r
+\r
+curl -v -X PUT -H "Content-Type: application/vnd.att-dr.subscription" -H "X-ATT-DR-ON-BEHALF-OF: {user}" --data-ascii @/opt/app/datartr/addSubscriber.txt --location-trusted -k https://{host}:{port}/subscribe/{feedId}\r
+\r
+Request Parameters:\r
+===================\r
+\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| Name                   | Description                     |  Param Type      |  Data Type |   MaxLen     |  Required   |  Format             |  Valid/Example Values                |\r
++========================+=================================+==================+============+==============+=============+=====================+======================================+\r
+| feedId                 | ID for the subscription you are |     Path         |   String   |              |     Y       |                     |                                      |\r
+|                        | updating                        |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| delivery               | Address and credentials for     |     Body         |   Object   |              |     Y       |                     |                                      |\r
+|                        | delivery                        |                  |            |              |             |                     |                                      |\r
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
+| follow_redirect        | Set to true if feed redirection |     Body         |   Boolean  |              |     Y       |                     | * true                               |\r
+|                        | is expected                     |                  |            |              |             |                     | * false                              |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| metadata_only          | Set to true if subscription is  |     Body         |   Boolean  |              |     Y       |                     | true                                 |\r
-|                        | to receive per-file metadata    |                  |            |              |             |                     | false                                |\r
+| metadata_only          | Set to true if subscription is  |     Body         |   Boolean  |              |     Y       |                     | * true                               |\r
+|                        | to receive per-file metadata    |                  |            |              |             |                     | * false                              |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
-| suspend                | Set to true if the subscription |     Body         |   Boolean  |              |     N       |                     | true                                 |\r
-|                        | is in the suspended state       |                  |            |              |             |                     | false                                |\r
+| suspend                | Set to true if the subscription |     Body         |   Boolean  |              |     N       |                     | * true                               |\r
+|                        | is in the suspended state       |                  |            |              |             |                     | * false                              |\r
 +------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+\r
 | group-id               |                                 |     Body         |   Integer  |              |     Y       |                     |                                      |\r
 |                        |                                 |                  |            |              |             |                     |                                      |\r
@@ -332,7 +618,7 @@ Sample Body
     "metadataOnly" : false,\r
     "suspend" : false,\r
     "groupid" : 29,\r
-    "subscriber" : "sg481n"\r
+    "subscriber" : "subscriber123"\r
 \r
 }\r
 \r
@@ -347,7 +633,7 @@ Request URL
 \r
 http[s]://{host}:{port}/subscribe/{subId}\r
 \r
-* {subId}: Id of the subscription you wish to see a representation of\r
+* {subId}: Id of the subscription you want to see a representation of\r
 \r
 Sample Request\r
 ==============\r
@@ -398,6 +684,67 @@ Response/Error Codes
 | -1                     | Failed Delivery                           |\r
 +------------------------+-------------------------------------------+\r
 \r
+Delete a subscription\r
+---------------------\r
+\r
+**Description**: Deletes a specified subscription\r
+\r
+Request URL\r
+===========\r
+\r
+http[s]://{host}:{port}/feed/{feedId}\r
+\r
+* {feedId}: Id of the subscription you want to delete\r
+\r
+Sample Request\r
+==============\r
+\r
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/subscribe/{feedId}\r
+\r
+Response/Error Codes\r
+====================\r
+\r
++------------------------+-------------------------------------------+\r
+| Response statusCode    | Response Description                      |\r
++========================+===========================================+\r
+| 204                    | Successful query                          |\r
++------------------------+-------------------------------------------+\r
+| 401                    | Indicates that the request was missing the|\r
+|                        | Authorization header or, if the header    |\r
+|                        | was presented, the credentials were not   |\r
+|                        | acceptable                                |\r
++------------------------+-------------------------------------------+\r
+| 403                    | The request failed authorization.         |\r
+|                        | Possible causes:                          |\r
+|                        |                                           |\r
+|                        | * Request originated from an unauthorized |\r
+|                        |   IP address                              |\r
+|                        | * Client certificate subject is not on    |\r
+|                        |   the API’s authorized list.              |\r
+|                        | * X-ATT-DR-ON-BEHALF-OF identity is not   |\r
+|                        |   authorized to perform                   |\r
++------------------------+-------------------------------------------+\r
+| 404                    | Not Found - The Request-URI does not point|\r
+|                        | to a resource that is known to the API.   |\r
++------------------------+-------------------------------------------+\r
+| 405                    | Method Not Allowed - The HTTP method in   |\r
+|                        | the request is not supported for the      |\r
+|                        | resource addressed by the Request-URI.    |\r
++------------------------+-------------------------------------------+\r
+| 415                    | Unsupported Media Type - The media type in|\r
+|                        | the request’s Content-Type header is not  |\r
+|                        | appropriate for the request.              |\r
++------------------------+-------------------------------------------+\r
+| 500                    | Internal Server Error - The DR API server |\r
+|                        | encountered an internal error and could   |\r
+|                        | not complete the request.                 |\r
++------------------------+-------------------------------------------+\r
+| 503                    | Service Unavailable - The DR API service  |\r
+|                        | is currently unavailable                  |\r
++------------------------+-------------------------------------------+\r
+| -1                     | Failed Delivery                           |\r
++------------------------+-------------------------------------------+\r
+\r
 Publish to Feed\r
 ---------------\r
 \r
@@ -460,7 +807,54 @@ Response/Error Codes
 Sample Request\r
 ==============\r
 \r
-curl -v -X PUT --user {user}:{password} -H "Content-Type: application/octet-stream" --data-binary @/opt/app/datartr/sampleFile.txt --post301 --location-trusted -k https://{host}:{port}/publish/{feedId}/sampleFile.txt\r
+curl -v -X PUT --user {user}:{password} -H "Content-Type: application/octet-stream" --data-binary @/opt/app/datartr/sampleFile.txt --location-trusted -k https://{host}:{port}/publish/{feedId}/sampleFile.txt\r
+\r
+Delete a Published file\r
+-----------------------\r
+\r
+**Description**: Deletes a specified published file\r
+\r
+Request URL\r
+===========\r
+\r
+http[s]://{host}:{port}/publish/{feedId}/{fileId}\r
+\r
+* {feedId}: Id of the feed you want to delete a published file from\r
+* {fileId}: Id of the published file you want to delete\r
+\r
+Sample Request\r
+==============\r
+\r
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/publish/{feedId}/{fileId}\r
+\r
+Response/Error Codes\r
+====================\r
+\r
++------------------------+---------------------------------+\r
+| Response statusCode    | Response Description            |\r
++========================+=================================+\r
+| 204                    | Successful PUT or DELETE        |\r
++------------------------+---------------------------------+\r
+| 400                    | Failure - Malformed request     |\r
++------------------------+---------------------------------+\r
+| 401                    | Failure - Request was missing   |\r
+|                        | authorization header, or        |\r
+|                        | credentials were not accepted   |\r
++------------------------+---------------------------------+\r
+| 403                    | Failure - User could not be     |\r
+|                        | authenticated, or was not       |\r
+|                        | authorized to make the request  |\r
++------------------------+---------------------------------+\r
+| 404                    | Failure - Path in the request   |\r
+|                        | URL did not point to a valid    |\r
+|                        | feed publishing URL             |\r
++------------------------+---------------------------------+\r
+| 500                    | Failure - DR experienced an     |\r
+|                        | internal problem                |\r
++------------------------+---------------------------------+\r
+| 503                    | Failure - DR is not currently   |\r
+|                        | available                       |\r
++------------------------+---------------------------------+\r
 \r
 Feed logging\r
 ------------\r
@@ -473,8 +867,8 @@ Request URL
 \r
 http[s]://{host}:{port}/feedlog/{feedId}?{queryParameter}\r
 \r
-* {feedId} is the id of the feed you wish to get logs from\r
-* {queryParameter} a parameter passed through to narrow the returned logs. multiple parameters can be passed\r
+* {feedId} : The id of the feed you want to get logs from\r
+* {queryParameter}: A parameter passed through to narrow the returned logs. multiple parameters can be passed\r
 \r
 Request parameters\r
 ==================\r
@@ -623,8 +1017,8 @@ Request URL
 \r
 http[s]://{host}:{port}/sublog/{subId}?{queryParameter}\r
 \r
-* {subId} is the id of the feed you wish to get logs from\r
-* {queryParameter} a parameter passed through to narrow the returned logs. multiple parameters can be passed\r
+* {subId}: The id of the feed you want to get logs from\r
+* {queryParameter}: A parameter passed through to narrow the returned logs. multiple parameters can be passed\r
 \r
 Request parameters\r
 ==================\r