Skip to content

Commit

Permalink
[PT-694] Do not throw exception for successful http codes and remove …
Browse files Browse the repository at this point in the history
…redundant cases
  • Loading branch information
Harman Singh committed May 17, 2021
1 parent 6f4f35a commit 85c1c1b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 45 deletions.
53 changes: 8 additions & 45 deletions src/main/com/sailthru/client/http/SailthruHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,19 @@

import com.sailthru.client.LastRateLimitInfo;
import com.sailthru.client.exceptions.ApiException;
import com.sailthru.client.exceptions.ResourceNotFoundException;
import com.sailthru.client.exceptions.UnAuthorizedException;
import com.sailthru.client.handler.SailthruResponseHandler;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author Prajwal Tuladhar <praj@sailthru.com>
*/
public class SailthruHandler implements ResponseHandler<Object> {
Expand All @@ -31,58 +26,26 @@ public class SailthruHandler implements ResponseHandler<Object> {
// key used to store rate limit info, for use and removal by the parent SailthruClient
public static final String RATE_LIMIT_INFO_KEY = "x_rate_limit_info";

/* Supported HTTP Status codes */
public static final int STATUS_OK = 200;
public static final int STATUS_BAD_REQUEST = 400;
public static final int STATUS_UNAUTHORIZED = 401;
public static final int STATUS_FORBIDDEN = 403;
public static final int STATUS_NOT_FOUND = 404;
public static final int STATUS_METHOD_NOT_FOUND = 405;
public static final int STATUS_INTERNAL_SERVER_ERROR = 500;

public SailthruHandler(SailthruResponseHandler handler) {
super();
this.handler = handler;
}

public Object handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
logger.debug("Received Response: {}", httpResponse.toString());
public Object handleResponse(HttpResponse httpResponse) throws IOException {
logger.debug("Received Response: {}", httpResponse);

StatusLine statusLine = httpResponse.getStatusLine();
int statusCode = statusLine.getStatusCode();

String jsonString = null;
jsonString = EntityUtils.toString(httpResponse.getEntity());
Object parseObject = handler.parseResponse(jsonString);
String jsonString = EntityUtils.toString(httpResponse.getEntity());
Object parseObject = handler.parseResponse(jsonString);

addRateLimitInfoToResponseObject(httpResponse, parseObject);

switch (statusCode) {
case STATUS_OK:
break;

case STATUS_BAD_REQUEST:
throw ApiException.create(statusLine, parseObject);

case STATUS_UNAUTHORIZED:
throw UnAuthorizedException.create(statusLine, parseObject);

case STATUS_FORBIDDEN:
throw ApiException.create(statusLine, parseObject);

case STATUS_NOT_FOUND:
throw ResourceNotFoundException.create(statusLine, parseObject);

case STATUS_METHOD_NOT_FOUND:
throw ApiException.create(statusLine, parseObject);

case STATUS_INTERNAL_SERVER_ERROR:
throw ApiException.create(statusLine, parseObject);

default:
throw ApiException.create(statusLine, parseObject);
// if status is not successful (i.e. 2xx) throw exception
int statusCode = statusLine.getStatusCode();
if (statusCode / 100 != 2) {
throw ApiException.create(statusLine, parseObject);
}

return parseObject;
}

Expand Down
92 changes: 92 additions & 0 deletions src/test/com/sailthru/client/http/SailthruHandlerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.sailthru.client.http;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.gson.Gson;
import com.sailthru.client.SailthruUtil;
import com.sailthru.client.exceptions.ApiException;
import com.sailthru.client.handler.JsonHandler;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.apache.http.HttpStatus;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.message.BasicStatusLine;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class SailthruHandlerTest {
private final SailthruHandler handler = new SailthruHandler(new JsonHandler());
private final Gson gson = SailthruUtil.createGson();
private static final String EXAMPLE_RESPONSE = "{\"sample_response\":true}";

@Test
public void testHandlingSuccessfulResponse() throws IOException {
CloseableHttpResponse httpOkResponse = getMockHttpResponseWithStatus(HttpStatus.SC_OK, "OK");
Object okResponse = handler.handleResponse(httpOkResponse);
Assert.assertEquals(EXAMPLE_RESPONSE, gson.toJson(okResponse));

CloseableHttpResponse httpCreatedResponse = getMockHttpResponseWithStatus(HttpStatus.SC_CREATED, "Created");
Object createdResponse = handler.handleResponse(httpCreatedResponse);
Assert.assertEquals(EXAMPLE_RESPONSE, gson.toJson(createdResponse));
}

@Test
public void testHandlingClientErrorResponse() throws IOException {
CloseableHttpResponse httpBadResponse = getMockHttpResponseWithStatus(HttpStatus.SC_BAD_REQUEST, "Bad Request");
try {
handler.handleResponse(httpBadResponse);
Assert.fail("Expected an APIException to be thrown");
} catch (ApiException apiException) {
Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, apiException.getStatusCode());
}

CloseableHttpResponse httpUnauthorizedResponse = getMockHttpResponseWithStatus(HttpStatus.SC_UNAUTHORIZED, "Unauthorized");
try {
handler.handleResponse(httpUnauthorizedResponse);
Assert.fail("Expected an APIException to be thrown");
} catch (ApiException apiException) {
Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, apiException.getStatusCode());
}
}

@Test
public void testHandlingServerErrorResponse() throws IOException {
CloseableHttpResponse httCreatedResponse = getMockHttpResponseWithStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
try {
Object okResponse = handler.handleResponse(httCreatedResponse);
Assert.fail("Expected an APIException to be thrown");
} catch (ApiException apiException) {
Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, apiException.getStatusCode());
}

CloseableHttpResponse httpCreatedResponse = getMockHttpResponseWithStatus(HttpStatus.SC_BAD_GATEWAY, "Bad Gateway");
try {
Object okResponse = handler.handleResponse(httpCreatedResponse);
Assert.fail("Expected an APIException to be thrown");
} catch (ApiException apiException) {
Assert.assertEquals(HttpStatus.SC_BAD_GATEWAY, apiException.getStatusCode());
}
}

private CloseableHttpResponse getMockHttpResponseWithStatus(int statusCode, String reasonPhrase) {
CloseableHttpResponse mockHttpResponse = mock(CloseableHttpResponse.class);

BasicHttpEntity fakeEntity = new BasicHttpEntity();
fakeEntity.setContent(new ByteArrayInputStream(EXAMPLE_RESPONSE.getBytes()));
when(mockHttpResponse.getEntity()).thenReturn(fakeEntity);

when(mockHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), statusCode, reasonPhrase));

when(mockHttpResponse.getFirstHeader("X-Rate-Limit-Limit")).thenReturn(null);
when(mockHttpResponse.getFirstHeader("X-Rate-Limit-Remaining")).thenReturn(null);
when(mockHttpResponse.getFirstHeader("X-Rate-Limit-Reset")).thenReturn(null);

return mockHttpResponse;
}
}

0 comments on commit 85c1c1b

Please sign in to comment.