package org.mapfish.print; import com.google.common.base.Predicate; import com.google.common.collect.Maps; import org.apache.http.client.methods.HttpRequestBase; import org.mapfish.print.config.Configuration; import org.mapfish.print.http.ConfigurableRequest; import org.mapfish.print.http.MfClientHttpRequestFactory; import org.mapfish.print.http.MfClientHttpRequestFactoryImpl; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.mock.http.client.MockClientHttpRequest; import org.springframework.mock.http.client.MockClientHttpResponse; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.util.Map; import static org.junit.Assert.fail; /** * Allows tests to provide canned responses to requests. */ public class TestHttpClientFactory extends MfClientHttpRequestFactoryImpl implements MfClientHttpRequestFactory { public TestHttpClientFactory() { super(20, 10); } private final Map<Predicate<URI>, Handler> handlers = Maps.newConcurrentMap(); public void registerHandler(Predicate<URI> matcher, Handler handler) { if (handlers.containsKey(matcher)) { throw new IllegalArgumentException(matcher + " has already been registered"); } handlers.put(matcher, handler); } @Override public ConfigurableRequest createRequest(URI uri, final HttpMethod httpMethod) throws IOException { for (Map.Entry<Predicate<URI>, Handler> entry : handlers.entrySet()) { if (entry.getKey().apply(uri)) { try { final MockClientHttpRequest httpRequest = entry.getValue().handleRequest(uri, httpMethod); return new TestConfigurableRequest(httpRequest); } catch (Exception e) { throw new RuntimeException(e); } } } throw new IllegalArgumentException(uri + " not registered with " + getClass().getName()); } @Override public void register(RequestConfigurator callback) { throw new UnsupportedOperationException("Not supported"); } public static abstract class Handler { public abstract MockClientHttpRequest handleRequest(URI uri, HttpMethod httpMethod) throws Exception; public MockClientHttpRequest ok(URI uri, byte[] bytes, HttpMethod httpMethod) { MockClientHttpRequest request = new MockClientHttpRequest(httpMethod, uri); ClientHttpResponse response = new MockClientHttpResponse(bytes, HttpStatus.OK); request.setResponse(response); return request; } public MockClientHttpRequest error404(URI uri, HttpMethod httpMethod) { MockClientHttpRequest request = new MockClientHttpRequest(httpMethod, uri); MockClientHttpResponse response = new MockClientHttpResponse(new byte[0], HttpStatus.NOT_FOUND); request.setResponse(response); return request; } public MockClientHttpRequest failOnExecute(final URI uri, final HttpMethod httpMethod) { MockClientHttpRequest request = new MockClientHttpRequest(httpMethod, uri) { @Override protected ClientHttpResponse executeInternal() throws IOException { fail("request should not be executed " + uri.toString()); throw new IOException(); } }; return request; } } private static class TestConfigurableRequest implements ConfigurableRequest { private final MockClientHttpRequest httpRequest; public TestConfigurableRequest(MockClientHttpRequest httpRequest) { this.httpRequest = httpRequest; } @Override public HttpRequestBase getUnderlyingRequest() { throw new UnsupportedOperationException("Not supported"); } @Override public void setConfiguration(Configuration configuration) { // ignore } @Override public ClientHttpResponse execute() throws IOException { return httpRequest.execute(); } @Override public OutputStream getBody() throws IOException { return httpRequest.getBody(); } @Override public HttpMethod getMethod() { return httpRequest.getMethod(); } @Override public URI getURI() { return httpRequest.getURI(); } @Override public HttpHeaders getHeaders() { return httpRequest.getHeaders(); } } }