Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not throw exception for successful http codes and remove redundant cases #68

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
// check if status is not successful (i.e. 2xx)
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;
}
}