diff options
16 files changed, 3766 insertions, 32 deletions
@@ -4,3 +4,4 @@ *.log* *.classpath *.project +datarouter-prov/unit-test-logs/ diff --git a/datarouter-node/pom.xml b/datarouter-node/pom.xml index 6cc396a1..61e95400 100755 --- a/datarouter-node/pom.xml +++ b/datarouter-node/pom.xml @@ -186,6 +186,35 @@ <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 index 00000000..6350e640 --- /dev/null +++ b/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigTest.java @@ -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 index 00000000..048c44fa --- /dev/null +++ b/datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java @@ -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); + } +} diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/BaseServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/BaseServletTest.java index 757852aa..61d030d9 100644..100755 --- a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/BaseServletTest.java +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/BaseServletTest.java @@ -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 index 00000000..35bc85d8 --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DRFeedsServletTest.java @@ -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"); + + } +} diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java index cf035121..414fc185 100644 --- a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/DrServletTestBase.java @@ -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); diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java index d65b1f97..f5302cb9 100644..100755 --- a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/FeedServletTest.java @@ -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 diff --git a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/GroupServletTest.java b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/GroupServletTest.java index ed0e2572..a0831b73 100755..100644 --- a/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/GroupServletTest.java +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/GroupServletTest.java @@ -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 index 00000000..104d137a --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/InternalServletTest.java @@ -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 index 00000000..9a550593 --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/LogServletTest.java @@ -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 index 00000000..92403ac8 --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/PublishServletTest.java @@ -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 index 00000000..63715804 --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/RouteServletTest.java @@ -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 index 00000000..c663451b --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscribeServletTest.java @@ -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 index 00000000..b42e3a76 --- /dev/null +++ b/datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java @@ -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 diff --git a/docs/data-router/data-router.rst b/docs/data-router/data-router.rst index 44d7b4c0..33ae1682 100644 --- a/docs/data-router/data-router.rst +++ b/docs/data-router/data-router.rst @@ -68,16 +68,129 @@ Request Parameters: | Authorization | Information for authorizing | Body | Object | | Y | | |
| | publishing requests | | | | | | |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| suspend | Set to true if the feed is in | Body | Boolean | | N | | true |
-| | the suspended state | | | | | | false |
+| suspend | Set to true if the feed is in | Body | Boolean | | N | | * true |
+| | the suspended state | | | | | | * false |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
| group-id | | Body | Integer | | Y | | |
| | | | | | | | |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| content-type | To specify type of message | Header | String | 20 | N | | application/vnd.att-dr.subscription |
+| content-type | To specify type of message | Header | String | 20 | N | | application/vnd.att-dr.feed |
| | (feed,subscriber,publisher) | | | | | | |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| X-ATT-DR-ON-BEHALF-OF | User id of subscriber | Header | String | 1 | N | | username |
+| X-ATT-DR-ON-BEHALF-OF | User id of owner of feed | Header | String | 1 | N | | username |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+
+Response/Error Codes
+====================
+
++------------------------+-------------------------------------------+
+| Response statusCode | Response Description |
++========================+===========================================+
+| 201 | Successful query |
++------------------------+-------------------------------------------+
+| 400 | Bad request - The request is defective in |
+| | some way. Possible causes: |
+| | |
+| | * JSON object in request body does not |
+| | conform to the spec. |
+| | * Invalid parameter value in query string |
++------------------------+-------------------------------------------+
+| 401 | Indicates that the request was missing the|
+| | Authorization header or, if the header |
+| | was presented, the credentials were not |
+| | acceptable |
++------------------------+-------------------------------------------+
+| 403 | The request failed authorization. |
+| | Possible causes: |
+| | |
+| | * Request originated from an unauthorized |
+| | IP address |
+| | * Client certificate subject is not on |
+| | the API’s authorized list. |
+| | * X-ATT-DR-ON-BEHALF-OF identity is not |
+| | authorized to perform |
++------------------------+-------------------------------------------+
+| 404 | Not Found - The Request-URI does not point|
+| | to a resource that is known to the API. |
++------------------------+-------------------------------------------+
+| 405 | Method Not Allowed - The HTTP method in |
+| | the request is not supported for the |
+| | resource addressed by the Request-URI. |
++------------------------+-------------------------------------------+
+| 415 | Unsupported Media Type - The media type in|
+| | the requests Content-Type header is not |
+| | appropriate for the request. |
++------------------------+-------------------------------------------+
+| 500 | Internal Server Error - The DR API server |
+| | encountered an internal error and could |
+| | not complete the request. |
++------------------------+-------------------------------------------+
+| 503 | Service Unavailable - The DR API service |
+| | is currently unavailable |
++------------------------+-------------------------------------------+
+| -1 | Failed Delivery |
++------------------------+-------------------------------------------+
+
+Sample Body
+===========
+.. code-block:: json
+
+ {
+ "name": "Jettydemo",
+ "version": "m1.0",
+ "description": "Jettydemo",
+ "business_description": "Jettydemo",
+ "suspend": false,
+ "deleted": false,
+ "changeowner": true,
+ "authorization": {
+ "classification": "unclassified",
+ "endpoint_addrs": [
+ "172.18.0.3",
+ ],
+ "endpoint_ids": [
+ {
+ "password": "password",
+ "id": "user"
+ }
+ ]
+ },
+
+}
+
+Updating a Feed
+---------------
+
+**Description**: Update a feed with new parameters.
+
+Sample Request
+==============
+
+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}
+
+Request Parameters:
+===================
+
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| Name | Description | Param Type | Data Type | MaxLen | Required | Format | Valid/Example Values |
++========================+=================================+==================+============+==============+=============+=====================+======================================+
+| description | Feed description | Body | String | | Y | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| business description | Business description | Body | String | | Y | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| Authorization | Information for authorizing | Body | Object | | Y | | |
+| | publishing requests | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| suspend | Set to true if the feed is in | Body | Boolean | | N | | * true |
+| | the suspended state | | | | | | * false |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| group-id | | Body | Integer | | Y | | |
+| | | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| content-type | To specify type of message | Header | String | 20 | N | | application/vnd.att-dr.feed |
+| | (feed,subscriber,publisher) | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| X-ATT-DR-ON-BEHALF-OF | User id of owner of feed | Header | String | 1 | N | | username |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
Response/Error Codes
@@ -158,7 +271,6 @@ Sample Body }
-
Get a Feed
----------
@@ -169,7 +281,7 @@ Request URL http[s]://{host}:{port}/feed/{feedId}
-* {feedId}: Id of the feed you wish to see a representation of
+* {feedId}: Id of the feed you want to see a representation of
Sample Request
==============
@@ -220,6 +332,66 @@ Response/Error Codes | -1 | Failed Delivery |
+------------------------+-------------------------------------------+
+Delete a Feed
+-------------
+
+**Description**: Deletes a specified feed
+
+Request URL
+===========
+
+http[s]://{host}:{port}/feed/{feedId}
+
+* {feedId}: Id of the feed you want to delete
+
+Sample Request
+==============
+
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/feed/{feedId}
+
+Response/Error Codes
+====================
+
++------------------------+-------------------------------------------+
+| Response statusCode | Response Description |
++========================+===========================================+
+| 204 | Successful query |
++------------------------+-------------------------------------------+
+| 401 | Indicates that the request was missing the|
+| | Authorization header or, if the header |
+| | was presented, the credentials were not |
+| | acceptable |
++------------------------+-------------------------------------------+
+| 403 | The request failed authorization. |
+| | Possible causes: |
+| | |
+| | * Request originated from an unauthorized |
+| | IP address |
+| | * Client certificate subject is not on |
+| | the API’s authorized list. |
+| | * X-ATT-DR-ON-BEHALF-OF identity is not |
+| | authorized to perform |
++------------------------+-------------------------------------------+
+| 404 | Not Found - The Request-URI does not point|
+| | to a resource that is known to the API. |
++------------------------+-------------------------------------------+
+| 405 | Method Not Allowed - The HTTP method in |
+| | the request is not supported for the |
+| | resource addressed by the Request-URI. |
++------------------------+-------------------------------------------+
+| 415 | Unsupported Media Type - The media type in|
+| | the request’s Content-Type header is not |
+| | appropriate for the request. |
++------------------------+-------------------------------------------+
+| 500 | Internal Server Error - The DR API server |
+| | encountered an internal error and could |
+| | not complete the request. |
++------------------------+-------------------------------------------+
+| 503 | Service Unavailable - The DR API service |
+| | is currently unavailable |
++------------------------+-------------------------------------------+
+| -1 | Failed Delivery |
++------------------------+-------------------------------------------+
Subscribe to Feed
@@ -249,14 +421,128 @@ Request Parameters: | delivery | Address and credentials for | Body | Object | | Y | | |
| | delivery | | | | | | |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| follow_redirect | Set to true if feed redirection | Body | Boolean | | Y | | true |
-| | is expected | | | | | | false |
+| follow_redirect | Set to true if feed redirection | Body | Boolean | | Y | | * true |
+| | is expected | | | | | | * false |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| metadata_only | Set to true if subscription is | Body | Boolean | | Y | | * true |
+| | to receive per-file metadata | | | | | | * false |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| suspend | Set to true if the subscription | Body | Boolean | | N | | * true |
+| | is in the suspended state | | | | | | * false |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| group-id | | Body | Integer | | Y | | |
+| | | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| content-type | To specify type of message | Header | String | 20 | N | | application/vnd.att-dr.subscription |
+| | (feed,subscriber,publisher) | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| X-ATT-DR-ON-BEHALF-OF | User id of subscriber | Header | String | 1 | N | | username |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+
+Response/Error Codes
+====================
+
++------------------------+-------------------------------------------+
+| Response statusCode | Response Description |
++========================+===========================================+
+| 201 | Successful query |
++------------------------+-------------------------------------------+
+| 400 | Bad request - The request is defective in |
+| | some way. Possible causes: |
+| | |
+| | * JSON object in request body does not |
+| | conform to the spec. |
+| | * Invalid parameter value in query string |
++------------------------+-------------------------------------------+
+| 401 | Indicates that the request was missing the|
+| | Authorization header or, if the header |
+| | was presented, the credentials were not |
+| | acceptable |
++------------------------+-------------------------------------------+
+| 403 | The request failed authorization. |
+| | Possible causes: |
+| | |
+| | * Request originated from an unauthorized |
+| | IP address |
+| | * Client certificate subject is not on |
+| | the API’s authorized list. |
+| | * X-ATT-DR-ON-BEHALF-OF identity is not |
+| | authorized to perform |
++------------------------+-------------------------------------------+
+| 404 | Not Found - The Request-URI does not point|
+| | to a resource that is known to the API. |
++------------------------+-------------------------------------------+
+| 405 | Method Not Allowed - The HTTP method in |
+| | the request is not supported for the |
+| | resource addressed by the Request-URI. |
++------------------------+-------------------------------------------+
+| 415 | Unsupported Media Type - The media type in|
+| | the requests Content-Type header is not |
+| | appropriate for the request. |
++------------------------+-------------------------------------------+
+| 500 | Internal Server Error - The DR API server |
+| | encountered an internal error and could |
+| | not complete the request. |
++------------------------+-------------------------------------------+
+| 503 | Service Unavailable - The DR API service |
+| | is currently unavailable |
++------------------------+-------------------------------------------+
+| -1 | Failed Delivery |
++------------------------+-------------------------------------------+
+
+Sample Body
+===========
+.. code-block:: json
+
+ {
+ "delivery" :{
+ "url" : "http://172.18.0.3:7070/",
+ "user" : "LOGIN",
+ "password" : "PASSWORD",
+ "use100" : true
+ },
+ "metadataOnly" : false,
+ "suspend" : false,
+ "groupid" : 29,
+ "subscriber" : "subscriber123"
+
+}
+
+Update subscription
+-------------------
+
+**Description**: Update a subscription to a feed.
+
+Request URL
+===========
+
+http[s]://{host}:{port}/subscribe/{feedId}
+
+Sample Request
+==============
+
+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}
+
+Request Parameters:
+===================
+
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| Name | Description | Param Type | Data Type | MaxLen | Required | Format | Valid/Example Values |
++========================+=================================+==================+============+==============+=============+=====================+======================================+
+| feedId | ID for the subscription you are | Path | String | | Y | | |
+| | updating | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| delivery | Address and credentials for | Body | Object | | Y | | |
+| | delivery | | | | | | |
++------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
+| follow_redirect | Set to true if feed redirection | Body | Boolean | | Y | | * true |
+| | is expected | | | | | | * false |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| metadata_only | Set to true if subscription is | Body | Boolean | | Y | | true |
-| | to receive per-file metadata | | | | | | false |
+| metadata_only | Set to true if subscription is | Body | Boolean | | Y | | * true |
+| | to receive per-file metadata | | | | | | * false |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
-| suspend | Set to true if the subscription | Body | Boolean | | N | | true |
-| | is in the suspended state | | | | | | false |
+| suspend | Set to true if the subscription | Body | Boolean | | N | | * true |
+| | is in the suspended state | | | | | | * false |
+------------------------+---------------------------------+------------------+------------+--------------+-------------+---------------------+--------------------------------------+
| group-id | | Body | Integer | | Y | | |
| | | | | | | | |
@@ -332,7 +618,7 @@ Sample Body "metadataOnly" : false,
"suspend" : false,
"groupid" : 29,
- "subscriber" : "sg481n"
+ "subscriber" : "subscriber123"
}
@@ -347,7 +633,7 @@ Request URL http[s]://{host}:{port}/subscribe/{subId}
-* {subId}: Id of the subscription you wish to see a representation of
+* {subId}: Id of the subscription you want to see a representation of
Sample Request
==============
@@ -398,6 +684,67 @@ Response/Error Codes | -1 | Failed Delivery |
+------------------------+-------------------------------------------+
+Delete a subscription
+---------------------
+
+**Description**: Deletes a specified subscription
+
+Request URL
+===========
+
+http[s]://{host}:{port}/feed/{feedId}
+
+* {feedId}: Id of the subscription you want to delete
+
+Sample Request
+==============
+
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/subscribe/{feedId}
+
+Response/Error Codes
+====================
+
++------------------------+-------------------------------------------+
+| Response statusCode | Response Description |
++========================+===========================================+
+| 204 | Successful query |
++------------------------+-------------------------------------------+
+| 401 | Indicates that the request was missing the|
+| | Authorization header or, if the header |
+| | was presented, the credentials were not |
+| | acceptable |
++------------------------+-------------------------------------------+
+| 403 | The request failed authorization. |
+| | Possible causes: |
+| | |
+| | * Request originated from an unauthorized |
+| | IP address |
+| | * Client certificate subject is not on |
+| | the API’s authorized list. |
+| | * X-ATT-DR-ON-BEHALF-OF identity is not |
+| | authorized to perform |
++------------------------+-------------------------------------------+
+| 404 | Not Found - The Request-URI does not point|
+| | to a resource that is known to the API. |
++------------------------+-------------------------------------------+
+| 405 | Method Not Allowed - The HTTP method in |
+| | the request is not supported for the |
+| | resource addressed by the Request-URI. |
++------------------------+-------------------------------------------+
+| 415 | Unsupported Media Type - The media type in|
+| | the request’s Content-Type header is not |
+| | appropriate for the request. |
++------------------------+-------------------------------------------+
+| 500 | Internal Server Error - The DR API server |
+| | encountered an internal error and could |
+| | not complete the request. |
++------------------------+-------------------------------------------+
+| 503 | Service Unavailable - The DR API service |
+| | is currently unavailable |
++------------------------+-------------------------------------------+
+| -1 | Failed Delivery |
++------------------------+-------------------------------------------+
+
Publish to Feed
---------------
@@ -460,7 +807,54 @@ Response/Error Codes Sample Request
==============
-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
+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
+
+Delete a Published file
+-----------------------
+
+**Description**: Deletes a specified published file
+
+Request URL
+===========
+
+http[s]://{host}:{port}/publish/{feedId}/{fileId}
+
+* {feedId}: Id of the feed you want to delete a published file from
+* {fileId}: Id of the published file you want to delete
+
+Sample Request
+==============
+
+curl -v -X DELETE -H "X-ATT-DR-ON-BEHALF-OF: {user}" --location-trusted -k https:/{host}:{port}/publish/{feedId}/{fileId}
+
+Response/Error Codes
+====================
+
++------------------------+---------------------------------+
+| Response statusCode | Response Description |
++========================+=================================+
+| 204 | Successful PUT or DELETE |
++------------------------+---------------------------------+
+| 400 | Failure - Malformed request |
++------------------------+---------------------------------+
+| 401 | Failure - Request was missing |
+| | authorization header, or |
+| | credentials were not accepted |
++------------------------+---------------------------------+
+| 403 | Failure - User could not be |
+| | authenticated, or was not |
+| | authorized to make the request |
++------------------------+---------------------------------+
+| 404 | Failure - Path in the request |
+| | URL did not point to a valid |
+| | feed publishing URL |
++------------------------+---------------------------------+
+| 500 | Failure - DR experienced an |
+| | internal problem |
++------------------------+---------------------------------+
+| 503 | Failure - DR is not currently |
+| | available |
++------------------------+---------------------------------+
Feed logging
------------
@@ -473,8 +867,8 @@ Request URL http[s]://{host}:{port}/feedlog/{feedId}?{queryParameter}
-* {feedId} is the id of the feed you wish to get logs from
-* {queryParameter} a parameter passed through to narrow the returned logs. multiple parameters can be passed
+* {feedId} : The id of the feed you want to get logs from
+* {queryParameter}: A parameter passed through to narrow the returned logs. multiple parameters can be passed
Request parameters
==================
@@ -623,8 +1017,8 @@ Request URL http[s]://{host}:{port}/sublog/{subId}?{queryParameter}
-* {subId} is the id of the feed you wish to get logs from
-* {queryParameter} a parameter passed through to narrow the returned logs. multiple parameters can be passed
+* {subId}: The id of the feed you want to get logs from
+* {queryParameter}: A parameter passed through to narrow the returned logs. multiple parameters can be passed
Request parameters
==================
|