added a custom error handler

This commit is contained in:
Alex Yarmula 2010-02-27 13:40:23 -08:00
parent b88b6beb9f
commit 2b41b83f0c
8 changed files with 195 additions and 10 deletions

View File

@ -0,0 +1,35 @@
package org.jclouds.gogrid;
import org.jclouds.gogrid.domain.internal.ErrorResponse;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import static java.lang.String.format;
/**
* @author Oleksiy Yarmula
*/
public class GoGridResponseException extends HttpResponseException {
private static final long serialVersionUID = 1924589L;
private ErrorResponse error;
public GoGridResponseException(HttpCommand command, HttpResponse response, ErrorResponse error) {
super(format("command %s failed with code %s, error [%s]: %s",
command.toString(), response.getStatusCode(), error.getErrorCode(),
error.getMessage()),
command, response);
this.setError(error);
}
public ErrorResponse getError() {
return error;
}
public void setError(ErrorResponse error) {
this.error = error;
}
}

View File

@ -54,9 +54,14 @@ import org.jclouds.date.DateService;
import org.jclouds.date.TimeStamp;
import org.jclouds.gogrid.GoGridAsyncClient;
import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.handlers.GoGridErrorHandler;
import org.jclouds.gogrid.services.GridServerAsyncClient;
import org.jclouds.gogrid.services.GridServerClient;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory;
@ -125,7 +130,12 @@ public class GoGridRestClientModule extends AbstractModule {
}
protected void bindErrorHandlers() {
// TODO
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
GoGridErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
GoGridErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
GoGridErrorHandler.class);
}
protected void bindRetryHandlers() {

View File

@ -0,0 +1,29 @@
package org.jclouds.gogrid.domain.internal;
/**
* @author Oleksiy Yarmula
*/
public class ErrorResponse {
private String message;
private String errorCode;
/**
* A no-args constructor is required for deserialization
*/
public ErrorResponse() {
}
public ErrorResponse(String message, String errorCode) {
this.message = message;
this.errorCode = errorCode;
}
public String getMessage() {
return message;
}
public String getErrorCode() {
return errorCode;
}
}

View File

@ -1,11 +1,15 @@
package org.jclouds.gogrid.domain.internal;
import com.google.common.base.Throwables;
import java.lang.reflect.Field;
import java.util.SortedSet;
/**
* General format of GoGrid's response.
*
* This is the wrapper for most responses, and the actual
* result (or error) will be set to {@link #list}.
* Note that even the single returned item will be set to
* {@link #list} per GoGrid's design.
*
* @author Oleksiy Yarmula
*/
public class GenericResponseContainer<T> {

View File

@ -0,0 +1,42 @@
package org.jclouds.gogrid.functions;
import com.google.common.collect.Iterables;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Singleton;
import org.jclouds.gogrid.domain.internal.ErrorResponse;
import org.jclouds.gogrid.domain.internal.GenericResponseContainer;
import org.jclouds.http.functions.ParseJson;
import javax.inject.Inject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import static com.google.common.base.Preconditions.checkState;
/**
* @author Oleksiy Yarmula
*/
@Singleton
public class ParseErrorFromJsonResponse extends ParseJson<ErrorResponse> {
@Inject
public ParseErrorFromJsonResponse(Gson gson) {
super(gson);
}
public ErrorResponse apply(InputStream stream) {
Type setType = new TypeToken<GenericResponseContainer<ErrorResponse>>() {
}.getType();
GenericResponseContainer<ErrorResponse> response;
try {
response = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}
checkState(response.getList() != null && response.getList().size() == 1,
/*or throw*/ "Expected exactly 1 error object in response");
return Iterables.getOnlyElement(response.getList());
}
}

View File

@ -0,0 +1,53 @@
package org.jclouds.gogrid.handlers;
import com.google.common.io.Closeables;
import com.google.inject.Inject;
import org.jclouds.gogrid.GoGridResponseException;
import org.jclouds.gogrid.domain.internal.ErrorResponse;
import org.jclouds.gogrid.functions.ParseErrorFromJsonResponse;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import java.io.InputStream;
/**
* @author Oleksiy Yarmula
*/
public class GoGridErrorHandler implements HttpErrorHandler {
private final ParseErrorFromJsonResponse errorParser;
@Inject
public GoGridErrorHandler(ParseErrorFromJsonResponse errorParser) {
this.errorParser = errorParser;
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Override
public void handleError(HttpCommand command, HttpResponse response) {
Exception exception;
ErrorResponse error = parseErrorFromContentOrNull(response.getContent());
switch (response.getStatusCode()) {
case 403:
exception = new AuthorizationException(command.getRequest(),
error.getMessage());
break;
default:
exception = error != null ?
new GoGridResponseException(command, response, error) :
new HttpResponseException(command, response);
}
command.setException(exception);
Closeables.closeQuietly(response.getContent());
}
ErrorResponse parseErrorFromContentOrNull(InputStream content) {
if (content != null) {
return errorParser.apply(content);
}
return null;
}
}

View File

@ -44,4 +44,17 @@ public interface GridServerClient {
Set<Server> getServerList();
//Set<Server> getServersByName(String... names);
/**
* Retrieves the server(s) by unique id(s).
*
* Given an id or a set of ids, finds one or
* multiple servers.
* @param id
* @return
*/
// Set<Server> getServersById(Long... ids);
}

View File

@ -22,12 +22,11 @@ import static org.testng.Assert.assertEquals;
import static com.google.common.util.concurrent.Executors.sameThreadExecutor;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.gogrid.handlers.GoGridErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.http.functions.config.ParserModule.CDateAdapter;
import org.jclouds.http.functions.config.ParserModule.DateAdapter;
import org.jclouds.http.handlers.CloseContentAndSetExceptionErrorHandler;
import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.handlers.RedirectionRetryHandler;
@ -86,7 +85,7 @@ public class GoGridContextModuleTest {
void testServerErrorHandler() {
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
assertEquals(handler.getServerErrorHandler().getClass(),
CloseContentAndSetExceptionErrorHandler.class);
GoGridErrorHandler.class);
}
@Test
@ -99,7 +98,7 @@ public class GoGridContextModuleTest {
void testClientErrorHandler() {
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
assertEquals(handler.getClientErrorHandler().getClass(),
CloseContentAndSetExceptionErrorHandler.class);
GoGridErrorHandler.class);
}
@Test