Java tutorial
/** * * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. * ==================================================================== */ package org.jclouds.rest.internal; import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; import java.net.URLEncoder; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.Future; import javax.inject.Named; import javax.inject.Qualifier; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.HttpMethod; import javax.ws.rs.MatrixParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.apache.commons.io.IOUtils; import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x; import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnStringIf200; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.logging.Logger; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.InvocationContext; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.HostPrefixParam; import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.MapEntityParam; import org.jclouds.rest.annotations.MatrixParams; import org.jclouds.rest.annotations.OverrideRequestFilters; import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.binders.BindMapToMatrixParams; import org.jclouds.rest.binders.BindToJsonEntity; import org.jclouds.rest.binders.BindToStringEntity; import org.jclouds.rest.config.RestModule; import org.jclouds.util.DateService; import org.jclouds.util.Jsr330; import org.joda.time.DateTime; import org.mortbay.jetty.HttpHeaders; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; import com.google.inject.util.Types; /** * Tests behavior of {@code JaxrsAnnotationProcessor} * * @author Adrian Cole */ @Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest") public class RestAnnotationProcessorTest { @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @javax.ws.rs.HttpMethod("FOO") public @interface FOO { } @Retention(value = RetentionPolicy.RUNTIME) @Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) @Qualifier public @interface Localhost { } @Retention(value = RetentionPolicy.RUNTIME) @Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) @Qualifier public @interface Localhost2 { } @QueryParams(keys = "x-ms-version", values = "2009-07-17") @Endpoint(Localhost.class) public class TestQuery { @FOO @QueryParams(keys = "x-ms-rubbish", values = "bin") public void foo() { } @FOO @QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" }) public void foo2() { } @FOO @QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" }) public void foo3(@QueryParam("robbie") String robbie) { } } public void testUnEncodeQuery() { URI expects = URI.create( "http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-blobstore.testObjectOperations&metadata=chef:sushi&metadata=foo:bar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); URI start = URI.create( "http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-blobstore.testObjectOperations&metadata=chef%3Asushi&metadata=foo%3Abar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); URI value = RestAnnotationProcessor.replaceQuery(start, start.getQuery(), null, '/', ':'); assertEquals(value, expects); } public void testQuery() throws SecurityException, NoSuchMethodException { Method method = TestQuery.class.getMethod("foo"); GeneratedHttpRequest<?> httpMethod = factory(TestQuery.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getEndpoint().getQuery(), "x-ms-version=2009-07-17&x-ms-rubbish=bin"); assertEquals(httpMethod.getMethod(), "FOO"); } public void testQuery2() throws SecurityException, NoSuchMethodException { Method method = TestQuery.class.getMethod("foo2"); GeneratedHttpRequest<?> httpMethod = factory(TestQuery.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getEndpoint().getQuery(), "x-ms-version=2009-07-17&foo=bar&fooble=baz"); assertEquals(httpMethod.getMethod(), "FOO"); } public void testQuery3() throws SecurityException, NoSuchMethodException { Method method = TestQuery.class.getMethod("foo3", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestQuery.class).createRequest(method, new Object[] { "wonder" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getEndpoint().getQuery(), "x-ms-version=2009-07-17&foo=bar&fooble=baz&robbie=wonder"); assertEquals(httpMethod.getMethod(), "FOO"); } @Endpoint(Localhost.class) public interface TestEntityParamVarargs { @POST public void varargs(HttpRequestOptions... options); @POST public void post(HttpRequestOptions options); } public void testHttpRequestOptionsEntityParam() throws SecurityException, NoSuchMethodException { Method method = TestEntityParamVarargs.class.getMethod("post", HttpRequestOptions.class); verifyTestPostOptions(method); } public void testEntityParamVarargs() throws SecurityException, NoSuchMethodException { Method method = TestEntityParamVarargs.class.getMethod("varargs", Array.newInstance(HttpRequestOptions.class, 0).getClass()); verifyTestPostOptions(method); } private void verifyTestPostOptions(Method method) { GeneratedHttpRequest<?> httpMethod = factory(TestEntityParamVarargs.class).createRequest(method, new Object[] { new HttpRequestOptions() { public Multimap<String, String> buildMatrixParameters() { return LinkedHashMultimap.create(); } public String buildPathSuffix() { return null; } public Multimap<String, String> buildQueryParameters() { return LinkedHashMultimap.create(); } public Multimap<String, String> buildFormParameters() { return LinkedHashMultimap.create(); } public Multimap<String, String> buildRequestHeaders() { return LinkedHashMultimap.create(); } public String buildStringEntity() { return "fooya"; } } }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("fooya".getBytes().length + "")); assertEquals(httpMethod.getEntity(), "fooya"); } @Endpoint(Localhost.class) public class TestCustomMethod { @FOO public void foo() { } } public void testCustomMethod() throws SecurityException, NoSuchMethodException { Method method = TestCustomMethod.class.getMethod("foo"); GeneratedHttpRequest<?> httpMethod = factory(TestCustomMethod.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), "FOO"); } public interface Parent { public void foo(); } @Endpoint(Localhost.class) public class TestOverridden implements Parent { @POST public void foo() { } } public void testOverriddenMethod() throws SecurityException, NoSuchMethodException { Method method = TestOverridden.class.getMethod("foo"); GeneratedHttpRequest<?> httpMethod = factory(TestOverridden.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), "POST"); } @Endpoint(Localhost.class) public class TestOverriddenEndpoint implements Parent { @POST @Endpoint(Localhost2.class) public void foo() { } @POST public void foo(@Endpoint URI endpoint) { } } public void testOverriddenEndpointMethod() throws SecurityException, NoSuchMethodException { Method method = TestOverriddenEndpoint.class.getMethod("foo"); GeneratedHttpRequest<?> httpMethod = factory(TestOverriddenEndpoint.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPort(), 8081); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), "POST"); } public void testOverriddenEndpointParameter() throws SecurityException, NoSuchMethodException { Method method = TestOverriddenEndpoint.class.getMethod("foo", URI.class); GeneratedHttpRequest<?> httpMethod = factory(TestOverriddenEndpoint.class).createRequest(method, new Object[] { URI.create("http://wowsa:8001") }); assertEquals(httpMethod.getEndpoint().getHost(), "wowsa"); assertEquals(httpMethod.getEndpoint().getPort(), 8001); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), "POST"); } @Endpoint(Localhost.class) public class TestPost { @POST public void post(@BinderParam(BindToStringEntity.class) String content) { } @POST public void postAsJson(@BinderParam(BindToJsonEntity.class) String content) { } @POST @Path("{foo}") public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path, MapBinder content) { } @POST @Path("{foo}") @MapBinder(BindToJsonEntity.class) public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { } } public void testCreatePostRequest() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("post", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPost.class).createRequest(method, new Object[] { "data" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("data".getBytes().length + "")); assertEquals(httpMethod.getEntity(), "data"); } public void testCreatePostJsonRequest() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("postAsJson", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPost.class).createRequest(method, new Object[] { "data" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), ""); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/json")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("\"data\"".getBytes().length + "")); assertEquals(httpMethod.getEntity(), "\"data\""); } public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("postWithPath", String.class, MapBinder.class); GeneratedHttpRequest<?> httpMethod = factory(TestPost.class).createRequest(method, new Object[] { "data", new org.jclouds.rest.MapBinder() { public void bindToRequest(HttpRequest request, Map<String, String> postParams) { request.setEntity(postParams.get("fooble")); } public void bindToRequest(HttpRequest request, Object toBind) { throw new RuntimeException("this shouldn't be used in POST"); } } }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/data"); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 1); assertEquals(httpMethod.getEntity(), "data"); } public void testCreatePostWithMethodBinder() throws SecurityException, NoSuchMethodException { Method method = TestPost.class.getMethod("postWithMethodBinder", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPost.class).createRequest(method, new Object[] { "data", }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/data"); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/json")); String expected = "{\"fooble\":\"data\"}"; assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList(expected.getBytes().length + "")); assertEquals(httpMethod.getEntity(), expected); } @Endpoint(Localhost.class) public class TestPut { @PUT @Path("{foo}") @MapBinder(BindToJsonEntity.class) public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { } @PUT @Path("{foo}") @Produces(MediaType.TEXT_PLAIN) public void putWithMethodBinderProduces( @PathParam("foo") @BinderParam(BindToStringEntity.class) String path) { } @PUT @Path("{foo}") @MapBinder(BindToJsonEntity.class) @Consumes(MediaType.APPLICATION_JSON) public void putWithMethodBinderConsumes(@PathParam("foo") @MapEntityParam("fooble") String path) { } } public void testCreatePutWithMethodBinder() throws SecurityException, NoSuchMethodException { Method method = TestPut.class.getMethod("putWithMethodBinder", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPut.class).createRequest(method, new Object[] { "data", }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/data"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/json")); String expected = "{\"fooble\":\"data\"}"; assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList(expected.getBytes().length + "")); assertEquals(httpMethod.getEntity(), expected); } public void testCreatePutWithMethodProduces() throws SecurityException, NoSuchMethodException { Method method = TestPut.class.getMethod("putWithMethodBinderProduces", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPut.class).createRequest(method, new Object[] { "data", }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/data"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("text/plain")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("data".getBytes().length + "")); assertEquals(httpMethod.getEntity(), "data"); } public void testCreatePutWithMethodConsumes() throws SecurityException, NoSuchMethodException { Method method = TestPut.class.getMethod("putWithMethodBinderConsumes", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPut.class).createRequest(method, new Object[] { "data", }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/data"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 3); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/json")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.ACCEPT), Collections.singletonList("application/json")); String expected = "{\"fooble\":\"data\"}"; assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList(expected.getBytes().length + "")); assertEquals(httpMethod.getEntity(), expected); } static class TestRequestFilter1 implements HttpRequestFilter { public void filter(HttpRequest request) throws HttpException { } } static class TestRequestFilter2 implements HttpRequestFilter { public void filter(HttpRequest request) throws HttpException { } } @RequestFilters(TestRequestFilter1.class) @Endpoint(Localhost.class) static class TestRequestFilter { @GET @RequestFilters(TestRequestFilter2.class) public void get() { } @GET @OverrideRequestFilters @RequestFilters(TestRequestFilter2.class) public void getOverride() { } } @Test public void testRequestFilter() throws SecurityException, NoSuchMethodException { Method method = TestRequestFilter.class.getMethod("get"); GeneratedHttpRequest<?> httpMethod = factory(TestRequestFilter.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getFilters().size(), 2); assertEquals(httpMethod.getFilters().get(0).getClass(), TestRequestFilter1.class); assertEquals(httpMethod.getFilters().get(1).getClass(), TestRequestFilter2.class); } public void testRequestFilterOverride() throws SecurityException, NoSuchMethodException { Method method = TestRequestFilter.class.getMethod("getOverride"); GeneratedHttpRequest<?> httpMethod = factory(TestRequestFilter.class).createRequest(method, new Object[] {}); assertEquals(httpMethod.getFilters().size(), 1); assertEquals(httpMethod.getFilters().get(0).getClass(), TestRequestFilter2.class); } @SkipEncoding('/') @Endpoint(Localhost.class) public class TestEncoding { @GET @Path("{path1}/{path2}") public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2) { } } @Test public void testSkipEncoding() throws SecurityException, NoSuchMethodException { Method method = TestEncoding.class.getMethod("twoPaths", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestEncoding.class).createRequest(method, new Object[] { "1", "localhost" }); assertEquals(httpMethod.getEndpoint().getPath(), "/1/localhost"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } @Test public void testEncodingPath() throws SecurityException, NoSuchMethodException { Method method = TestEncoding.class.getMethod("twoPaths", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestEncoding.class).createRequest(method, new Object[] { "/", "localhost" }); assertEquals(httpMethod.getEndpoint().getPath(), "///localhost"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } @SkipEncoding('/') @Path("/v1/{account}") @Endpoint(Localhost.class) public interface TestConstantPathParam { @Named("testaccount") @PathParam("account") void setUsername(); @GET @Path("{path1}/{path2}") public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2); } @Test(enabled = false) public void testConstantPathParam() throws SecurityException, NoSuchMethodException, IOException { Method method = TestConstantPathParam.class.getMethod("twoPaths", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestConstantPathParam.class).createRequest(method, new Object[] { "1", "localhost" }); assertRequestLineEquals(httpMethod, "GET http://localhost:8080/v1/ralphie/1/localhost HTTP/1.1"); assertHeadersEqual(httpMethod, ""); assertEntityEquals(httpMethod, null); } @Endpoint(Localhost.class) public class TestPath { @GET @Path("{path}") public void onePath(@PathParam("path") String path) { } @GET @Path("{path1}/{path2}") public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2) { } @GET @Path("{path2}/{path1}") public void twoPathsOutOfOrder(@PathParam("path1") String path, @PathParam("path2") String path2) { } @GET @Path("{path}") public void onePathParamExtractor(@PathParam("path") @ParamParser(FirstCharacter.class) String path) { } @GET @Path("/") public void oneQueryParamExtractor(@QueryParam("one") @ParamParser(FirstCharacter.class) String one) { } @POST @Path("/") public void oneFormParamExtractor(@FormParam("one") @ParamParser(FirstCharacter.class) String one) { } @GET @Path("/") public void oneMatrixParamExtractor(@MatrixParam("one") @ParamParser(FirstCharacter.class) String one) { } @GET @Path("{path}") @PathParam("path") @ParamParser(FirstCharacterFirstElement.class) public void onePathParamExtractorMethod(String path) { } } @Test public void testPathParamExtractor() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPath.class.getMethod("onePathParamExtractor", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPath.class).createRequest(method, new Object[] { "localhost" }); assertRequestLineEquals(httpMethod, "GET http://localhost:8080/l HTTP/1.1"); assertHeadersEqual(httpMethod, ""); assertEntityEquals(httpMethod, null); } @Test public void testQueryParamExtractor() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPath.class.getMethod("oneQueryParamExtractor", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPath.class).createRequest(method, "localhost"); assertRequestLineEquals(httpMethod, "GET http://localhost:8080/?one=l HTTP/1.1"); assertHeadersEqual(httpMethod, ""); assertEntityEquals(httpMethod, null); } @Test public void testMatrixParamExtractor() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPath.class.getMethod("oneMatrixParamExtractor", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPath.class).createRequest(method, new Object[] { "localhost" }); assertRequestLineEquals(httpMethod, "GET http://localhost:8080/;one=l HTTP/1.1"); assertHeadersEqual(httpMethod, ""); assertEntityEquals(httpMethod, null); } @Test public void testFormParamExtractor() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPath.class.getMethod("oneFormParamExtractor", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPath.class).createRequest(method, new Object[] { "localhost" }); assertRequestLineEquals(httpMethod, "POST http://localhost:8080/ HTTP/1.1"); assertHeadersEqual(httpMethod, "Content-Length: 5\nContent-Type: application/x-www-form-urlencoded\n"); assertEntityEquals(httpMethod, "one=l"); } @Test public void testParamExtractorMethod() throws SecurityException, NoSuchMethodException { Method method = TestPath.class.getMethod("onePathParamExtractorMethod", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestPath.class).createRequest(method, new Object[] { "localhost" }); assertEquals(httpMethod.getEndpoint().getPath(), "/l"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } static class FirstCharacter implements Function<Object, String> { public String apply(Object from) { return from.toString().substring(0, 1); } } static class FirstCharacterFirstElement implements Function<Object, String> { public String apply(Object from) { return ((String) ((Object[]) from)[0]).substring(0, 1); } } @Endpoint(Localhost.class) public class TestHeader { @GET @Headers(keys = "x-amz-copy-source", values = "/{bucket}") public void oneHeader(@PathParam("bucket") String path) { } @GET @Headers(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) public void twoHeader(@PathParam("bucket") String path) { } @GET @Headers(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoHeaders(@PathParam("bucket") String path, @PathParam("key") String path2) { } @GET @Headers(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoHeadersOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) { } } @Test public void testBuildTwoHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("twoHeader", String.class); Multimap<String, String> headers = factory(TestHeader.class) .createRequest(oneHeader, new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 2); assertEquals(headers.get("slash"), Collections.singletonList("/robot")); assertEquals(headers.get("hyphen"), Collections.singletonList("-robot")); } @Headers(keys = "x-amz-copy-source", values = "/{bucket}") @Endpoint(Localhost.class) public class TestClassHeader { @GET public void oneHeader(@PathParam("bucket") String path) { } } @Test public void testBuildOneClassHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestClassHeader.class.getMethod("oneHeader", String.class); Multimap<String, String> headers = factory(TestClassHeader.class) .createRequest(oneHeader, new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @Test public void testBuildOneHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("oneHeader", String.class); Multimap<String, String> headers = factory(TestHeader.class) .createRequest(oneHeader, new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @Test public void testBuildTwoHeaders() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoHeaders = TestHeader.class.getMethod("twoHeaders", String.class, String.class); Multimap<String, String> headers = factory(TestHeader.class) .createRequest(twoHeaders, new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot/eggs")); } @Test public void testBuildTwoHeadersOutOfOrder() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoHeadersOutOfOrder = TestHeader.class.getMethod("twoHeadersOutOfOrder", String.class, String.class); Multimap<String, String> headers = factory(TestHeader.class) .createRequest(twoHeadersOutOfOrder, new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/eggs/robot")); } public class TestReplaceQueryOptions extends BaseHttpRequestOptions { public TestReplaceQueryOptions() { this.queryParameters.put("x-amz-copy-source", "/{bucket}"); } } @Test public void testQueryInOptions() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("queryInOptions", String.class, TestReplaceQueryOptions.class); String query = factory(TestQueryReplace.class) .createRequest(oneQuery, new Object[] { "robot", new TestReplaceQueryOptions() }).getEndpoint() .getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @Endpoint(Localhost.class) private interface TestMapMatrixParams { @POST @Path("objects/{id}/action/{action}") Future<String> action(@PathParam("id") String id, @PathParam("action") String action, @BinderParam(BindMapToMatrixParams.class) Map<String, String> options); } public void testTestMapMatrixParams() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method method = TestMapMatrixParams.class.getMethod("action", String.class, String.class, Map.class); GeneratedHttpRequest<TestMapMatrixParams> httpMethod = factory(TestMapMatrixParams.class) .createRequest(method, new Object[] { "robot", "kill", ImmutableMap.of("death", "slow") }); assertEquals(httpMethod.getRequestLine(), "POST http://localhost:8080/objects/robot/action/kill;death=slow HTTP/1.1"); assertEquals(httpMethod.getHeaders().size(), 0); } @Endpoint(Localhost.class) @SkipEncoding('/') public class TestQueryReplace { @GET public void queryInOptions(@PathParam("bucket") String path, TestReplaceQueryOptions options) { } @GET @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}") public void oneQuery(@PathParam("bucket") String path) { } @GET @QueryParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) public void twoQuery(@PathParam("bucket") String path) { } @GET @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoQuerys(@PathParam("bucket") String path, @PathParam("key") String path2) { } @GET @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoQuerysOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) { } } @Test public void testBuildTwoQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("twoQuery", String.class); String query = factory(TestQueryReplace.class).createRequest(oneQuery, new Object[] { "robot" }) .getEndpoint().getQuery(); assertEquals(query, "slash=/robot&hyphen=-robot"); } @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}") @Endpoint(Localhost.class) public class TestClassQuery { @GET public void oneQuery(@PathParam("bucket") String path) { } } @Test public void testBuildOneClassQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestClassQuery.class.getMethod("oneQuery", String.class); String query = factory(TestClassQuery.class).createRequest(oneQuery, new Object[] { "robot" }).getEndpoint() .getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @Test public void testBuildOneQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("oneQuery", String.class); String query = factory(TestQueryReplace.class).createRequest(oneQuery, new Object[] { "robot" }) .getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @Test public void testBuildTwoQuerys() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoQuerys = TestQueryReplace.class.getMethod("twoQuerys", String.class, String.class); String query = factory(TestQueryReplace.class).createRequest(twoQuerys, new Object[] { "robot", "eggs" }) .getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoQuerysOutOfOrder() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoQuerysOutOfOrder = TestQueryReplace.class.getMethod("twoQuerysOutOfOrder", String.class, String.class); String query = factory(TestQueryReplace.class) .createRequest(twoQuerysOutOfOrder, new Object[] { "robot", "eggs" }).getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/eggs/robot"); } public class TestReplaceMatrixOptions extends BaseHttpRequestOptions { public TestReplaceMatrixOptions() { this.matrixParameters.put("x-amz-copy-source", "/{bucket}"); } } @Test public void testMatrixInOptions() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("matrixInOptions", String.class, TestReplaceMatrixOptions.class); String path = factory(TestMatrixReplace.class) .createRequest(oneMatrix, new Object[] { "robot", new TestReplaceMatrixOptions() }).getEndpoint() .getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @Endpoint(Localhost.class) @Path("/") public class TestMatrixReplace { @GET public void matrixInOptions(@PathParam("bucket") String path, TestReplaceMatrixOptions options) { } @GET @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}") public void oneMatrix(@PathParam("bucket") String path) { } @GET @MatrixParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) public void twoMatrix(@PathParam("bucket") String path) { } @GET @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoMatrixs(@PathParam("bucket") String path, @PathParam("key") String path2) { } @GET @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoMatrixsOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) { } } @Test public void testBuildTwoMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("twoMatrix", String.class); String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, new Object[] { "robot" }) .getEndpoint().getPath(); assertEquals(path, "/;slash=/robot;hyphen=-robot"); } @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}") @Endpoint(Localhost.class) @Path("/") public class TestClassMatrix { @GET public void oneMatrix(@PathParam("bucket") String path) { } } @Test public void testBuildOneClassMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestClassMatrix.class.getMethod("oneMatrix", String.class); String path = factory(TestClassMatrix.class).createRequest(oneMatrix, new Object[] { "robot" }) .getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @Test public void testBuildOneMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("oneMatrix", String.class); String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, new Object[] { "robot" }) .getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @Test public void testBuildTwoMatrixs() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoMatrixs = TestMatrixReplace.class.getMethod("twoMatrixs", String.class, String.class); String path = factory(TestMatrixReplace.class).createRequest(twoMatrixs, new Object[] { "robot", "eggs" }) .getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoMatrixsOutOfOrder() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoMatrixsOutOfOrder = TestMatrixReplace.class.getMethod("twoMatrixsOutOfOrder", String.class, String.class); String path = factory(TestMatrixReplace.class) .createRequest(twoMatrixsOutOfOrder, new Object[] { "robot", "eggs" }).getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/eggs/robot"); } @Endpoint(Localhost.class) public interface TestTransformers { @GET public int noTransformer(); @GET @ResponseParser(ReturnStringIf200.class) public void oneTransformer(); @GET @ResponseParser(ReturnStringIf200Context.class) public void oneTransformerWithContext(); @GET public InputStream inputStream(); @GET public Future<InputStream> futureInputStream(); @GET public URI uri(); @GET public Future<URI> futureUri(); } @SuppressWarnings("static-access") public void testInputStream() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("inputStream"); Class<? extends Function<HttpResponse, ?>> transformer = factory(TestTransformers.class) .getParserOrThrowException(method); assertEquals(transformer, ReturnInputStream.class); } @SuppressWarnings("static-access") public void testInputStreamFuture() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("futureInputStream"); Class<? extends Function<HttpResponse, ?>> transformer = factory(TestTransformers.class) .getParserOrThrowException(method); assertEquals(transformer, ReturnInputStream.class); } @SuppressWarnings("static-access") public void testURI() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("uri"); Class<? extends Function<HttpResponse, ?>> transformer = factory(TestTransformers.class) .getParserOrThrowException(method); assertEquals(transformer, ParseURIFromListOrLocationHeaderIf20x.class); } @SuppressWarnings("static-access") public void testURIFuture() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("futureUri"); Class<? extends Function<HttpResponse, ?>> transformer = factory(TestTransformers.class) .getParserOrThrowException(method); assertEquals(transformer, ParseURIFromListOrLocationHeaderIf20x.class); } public static class ReturnStringIf200Context extends ReturnStringIf200 implements InvocationContext { public HttpRequest request; public void setContext(GeneratedHttpRequest<?> request) { this.request = request; } } @SuppressWarnings("static-access") @Test(expectedExceptions = { RuntimeException.class }) public void testNoTransformer() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("noTransformer"); factory(TestTransformers.class).getParserOrThrowException(method); } public void oneTransformerWithContext() throws SecurityException, NoSuchMethodException { RestAnnotationProcessor<TestTransformers> processor = factory(TestTransformers.class); Method method = TestTransformers.class.getMethod("oneTransformerWithContext"); GeneratedHttpRequest<TestTransformers> request = new GeneratedHttpRequest<TestTransformers>("GET", URI.create("http://localhost"), processor, TestTransformers.class, method); Function<HttpResponse, ?> transformer = processor.createResponseParser(method, request); assertEquals(transformer.getClass(), ReturnStringIf200Context.class); assertEquals(((ReturnStringIf200Context) transformer).request, request); } @SuppressWarnings("static-access") public void testOneTransformer() throws SecurityException, NoSuchMethodException { Method method = TestTransformers.class.getMethod("oneTransformer"); Class<? extends Function<HttpResponse, ?>> transformer = factory(TestTransformers.class) .getParserOrThrowException(method); assertEquals(transformer, ReturnStringIf200.class); } @Endpoint(Localhost.class) public class TestRequest { @GET @VirtualHost @Path("/{id}") public Future<String> get(@PathParam("id") String id, HttpRequestOptions options) { return null; } @GET @VirtualHost @Path("/{id}") public Future<String> get(@PathParam("id") String id, HttpRequestOptions... options) { return null; } @GET @Path("/{id}") @ResponseParser(ReturnStringIf200.class) public Future<String> get(@PathParam("id") String id, @HeaderParam(HttpHeaders.HOST) String host) { return null; } @GET @Path("/{id}") @QueryParams(keys = "max-keys", values = "0") public Future<String> getQuery(@PathParam("id") String id) { return null; } @GET @Path("/{id}") @QueryParams(keys = "acl") public Future<String> getQueryNull(@PathParam("id") String id) { return null; } @PUT @Path("/{id}") public Future<String> put(@PathParam("id") @ParamParser(FirstCharacter.class) String id, @BinderParam(BindToStringEntity.class) String payload) { return null; } @PUT @Path("/{id}") @VirtualHost public Future<String> putOptions(@PathParam("id") String id, HttpRequestOptions options) { return null; } @PUT @Path("/{id}") @Headers(keys = "foo", values = "--{id}--") @ResponseParser(ReturnTrueIf2xx.class) public Future<String> putHeader(@PathParam("id") String id, @BinderParam(BindToStringEntity.class) String payload) { return null; } } public void testCreateGetVarArgOptionsThatProducesHeaders() throws SecurityException, NoSuchMethodException { DateTime date = new DateTime(); GetOptions options = GetOptions.Builder.ifModifiedSince(date); HttpRequestOptions[] optionsHolder = new HttpRequestOptions[] {}; Method method = TestRequest.class.getMethod("get", String.class, optionsHolder.getClass()); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1", options }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), Collections.singletonList(dateService.rfc822DateFormat(date))); } public void testCreateGetOptionsThatProducesHeaders() throws SecurityException, NoSuchMethodException { DateTime date = new DateTime(); GetOptions options = GetOptions.Builder.ifModifiedSince(date); Method method = TestRequest.class.getMethod("get", String.class, HttpRequestOptions.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1", options }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), Collections.singletonList(dateService.rfc822DateFormat(date))); } @Endpoint(Localhost.class) public class PrefixOptions extends BaseHttpRequestOptions { public PrefixOptions withPrefix(String prefix) { queryParameters.put("prefix", checkNotNull(prefix, "prefix")); return this; } } public void testCreateGetOptionsThatProducesQuery() throws SecurityException, NoSuchMethodException, IOException { PrefixOptions options = new PrefixOptions().withPrefix("1"); Method method = TestRequest.class.getMethod("get", String.class, HttpRequestOptions.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1", options }); assertRequestLineEquals(httpMethod, "GET http://localhost:8080/1?prefix=1 HTTP/1.1"); assertHeadersEqual(httpMethod, "Host: localhost\n"); assertEntityEquals(httpMethod, null); } public void testCreateGetQuery() throws SecurityException, NoSuchMethodException { Method method = TestRequest.class.getMethod("getQuery", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getEndpoint().getQuery(), "max-keys=0"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } public void testCreateGetQueryNull() throws SecurityException, NoSuchMethodException { Method method = TestRequest.class.getMethod("getQueryNull", String.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getEndpoint().getQuery(), "acl"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } @Endpoint(Localhost.class) public class EntityOptions extends BaseHttpRequestOptions { @Override public String buildStringEntity() { return "foo"; } } public void testCreateGetOptionsThatProducesEntity() throws SecurityException, NoSuchMethodException { EntityOptions options = new EntityOptions(); Method method = TestRequest.class.getMethod("putOptions", String.class, HttpRequestOptions.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1", options }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 3); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); assertEquals(httpMethod.getEntity(), "foo"); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("foo".getBytes().length + "")); } @DataProvider(name = "strings") public Object[][] createData() { return new Object[][] { { "apples" }, { "sp ace" }, { "unicde" }, { "qu?stion" } }; } @Test(dataProvider = "strings") public void testCreateGetRequest(String key) throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method method = TestRequest.class.getMethod("get", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { key, "localhost" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); String expectedPath = "/" + URLEncoder.encode(key, "UTF-8").replaceAll("\\+", "%20"); assertEquals(httpMethod.getEndpoint().getRawPath(), expectedPath); assertEquals(httpMethod.getEndpoint().getPath(), "/" + key); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 1); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); } public void testCreatePutRequest() throws SecurityException, NoSuchMethodException { Method method = TestRequest.class.getMethod("put", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "111", "data" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("data".getBytes().length + "")); assertEquals(httpMethod.getEntity(), "data"); } public void testCreatePutHeader() throws SecurityException, NoSuchMethodException { Method method = TestRequest.class.getMethod("putHeader", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestRequest.class).createRequest(method, new Object[] { "1", "data" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 3); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("data".getBytes().length + "")); assertEquals(httpMethod.getHeaders().get("foo"), Collections.singletonList("--1--")); assertEquals(httpMethod.getEntity(), "data"); } @Endpoint(Localhost.class) public class TestVirtualHostMethod { @GET @Path("/{id}") @VirtualHost public Future<String> get(@PathParam("id") String id, String foo) { return null; } } @Test public void testVirtualHostMethod() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHostMethod.class.getMethod("get", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestVirtualHostMethod.class).createRequest(method, new Object[] { "1", "localhost" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 1); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); } @Endpoint(Localhost.class) public class TestVirtualHost { @GET @Path("/{id}") @VirtualHost public Future<String> get(@PathParam("id") String id, String foo) { return null; } @GET @Path("/{id}") public Future<String> getPrefix(@PathParam("id") String id, @HostPrefixParam("") String foo) { return null; } @GET @Path("/{id}") public Future<String> getPrefixDot(@PathParam("id") String id, @HostPrefixParam String foo) { return null; } } @Test public void testVirtualHost() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHost.class.getMethod("get", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestVirtualHost.class).createRequest(method, new Object[] { "1", "localhost" }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 1); assertEquals(httpMethod.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); } @Test public void testHostPrefix() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHost.class.getMethod("getPrefix", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestVirtualHost.class).createRequest(method, new Object[] { "1", "holy" }); assertEquals(httpMethod.getEndpoint().getHost(), "holylocalhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } @Test public void testHostPrefixDot() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHost.class.getMethod("getPrefixDot", String.class, String.class); GeneratedHttpRequest<?> httpMethod = factory(TestVirtualHost.class).createRequest(method, new Object[] { "1", "holy" }); assertEquals(httpMethod.getEndpoint().getHost(), "holy.localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/1"); assertEquals(httpMethod.getMethod(), HttpMethod.GET); assertEquals(httpMethod.getHeaders().size(), 0); } @Test(expectedExceptions = IllegalArgumentException.class) public void testHostPrefixDotEmpty() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHost.class.getMethod("getPrefixDot", String.class, String.class); factory(TestVirtualHost.class).createRequest(method, new Object[] { "1", "" }); } @Test(expectedExceptions = NullPointerException.class) public void testHostPrefixDotNull() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHost.class.getMethod("getPrefixDot", String.class, String.class); factory(TestVirtualHost.class).createRequest(method, new Object[] { "1", null }); } @Endpoint(Localhost.class) public class TestHeaders { @GET public void oneHeader(@HeaderParam("header") String header) { } @GET public void oneIntHeader(@HeaderParam("header") int header) { } @GET public void twoDifferentHeaders(@HeaderParam("header1") String header1, @HeaderParam("header2") String header2) { } @GET public void twoSameHeaders(@HeaderParam("header") String header1, @HeaderParam("header") String header2) { } } @Test public void testOneHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneHeader", String.class); Multimap<String, String> headers = factory(TestHeaders.class) .buildHeaders(ImmutableMultimap.<String, String>of().entries(), method, "robot"); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("robot")); } @Test public void testOneIntHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneIntHeader", int.class); Multimap<String, String> headers = factory(TestHeaders.class) .buildHeaders(ImmutableMultimap.<String, String>of().entries(), method, 1); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("1")); } @Test public void testTwoDifferentHeaders() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("twoDifferentHeaders", String.class, String.class); Multimap<String, String> headers = factory(TestHeaders.class) .buildHeaders(ImmutableMultimap.<String, String>of().entries(), method, "robot", "egg"); assertEquals(headers.size(), 2); assertEquals(headers.get("header1"), Collections.singletonList("robot")); assertEquals(headers.get("header2"), Collections.singletonList("egg")); } @Test public void testTwoSameHeaders() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("twoSameHeaders", String.class, String.class); Multimap<String, String> headers = factory(TestHeaders.class) .buildHeaders(ImmutableMultimap.<String, String>of().entries(), method, "robot", "egg"); assertEquals(headers.size(), 2); Collection<String> values = headers.get("header"); assert values.contains("robot"); assert values.contains("egg"); } @Endpoint(Localhost.class) public interface TestEntity { @PUT public void put(@BinderParam(BindToStringEntity.class) String content); @PUT @Path("{foo}") public Future<Void> putWithPath(@PathParam("foo") String path, @BinderParam(BindToStringEntity.class) String content); @PUT public void twoEntities(@BinderParam(BindToStringEntity.class) String entity1, @BinderParam(BindToStringEntity.class) String entity2); } @Test public void testPut() throws SecurityException, NoSuchMethodException { RestAnnotationProcessor<TestEntity> processor = factory(TestEntity.class); Method method = TestEntity.class.getMethod("put", String.class); GeneratedHttpRequest<TestEntity> request = new GeneratedHttpRequest<TestEntity>("GET", URI.create("http://localhost"), processor, TestEntity.class, method, "test"); processor.decorateRequest(request); assertEquals(request.getEntity(), "test"); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("test".getBytes().length + "")); assertEquals(processor.createResponseParser(method, request).getClass(), ReturnVoidIf2xx.class); } @Test public void putWithPath() throws SecurityException, NoSuchMethodException { RestAnnotationProcessor<TestEntity> processor = factory(TestEntity.class); Method method = TestEntity.class.getMethod("putWithPath", String.class, String.class); GeneratedHttpRequest<TestEntity> request = new GeneratedHttpRequest<TestEntity>("GET", URI.create("http://localhost"), processor, TestEntity.class, method, "rabble", "test"); processor.decorateRequest(request); assertEquals(request.getEntity(), "test"); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList("application/unknown")); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections.singletonList("test".getBytes().length + "")); } public class TestReplaceFormOptions extends BaseHttpRequestOptions { public TestReplaceFormOptions() { this.formParameters.put("x-amz-copy-source", "/{bucket}"); } } @Endpoint(Localhost.class) @SkipEncoding('/') public class TestFormReplace { @POST public void formInOptions(@PathParam("bucket") String path, TestReplaceFormOptions options) { } @POST @FormParams(keys = "x-amz-copy-source", values = "/{bucket}") public void oneForm(@PathParam("bucket") String path) { } @POST @FormParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) public void twoForm(@PathParam("bucket") String path) { } @POST @FormParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoForms(@PathParam("bucket") String path, @PathParam("key") String path2) { } @POST @FormParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") public void twoFormsOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) { } } @Test public void testBuildTwoForm() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneForm = TestFormReplace.class.getMethod("twoForm", String.class); String form = factory(TestFormReplace.class).createRequest(oneForm, new Object[] { "robot" }).getEntity() .toString(); assertEquals(form, "slash=/robot&hyphen=-robot"); } @FormParams(keys = "x-amz-copy-source", values = "/{bucket}") @Endpoint(Localhost.class) @SkipEncoding('/') public class TestClassForm { @POST public void oneForm(@PathParam("bucket") String path) { } } @Test public void testBuildOneClassForm() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneForm = TestClassForm.class.getMethod("oneForm", String.class); String form = factory(TestClassForm.class).createRequest(oneForm, new Object[] { "robot" }).getEntity() .toString(); assertEquals(form, "x-amz-copy-source=/robot"); } @Test public void testBuildOneForm() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneForm = TestFormReplace.class.getMethod("oneForm", String.class); String form = factory(TestFormReplace.class).createRequest(oneForm, new Object[] { "robot" }).getEntity() .toString(); assertEquals(form, "x-amz-copy-source=/robot"); } @Test public void testBuildTwoForms() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoForms = TestFormReplace.class.getMethod("twoForms", String.class, String.class); String form = factory(TestFormReplace.class).createRequest(twoForms, new Object[] { "robot", "eggs" }) .getEntity().toString(); assertEquals(form, "x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoFormsOutOfOrder() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoFormsOutOfOrder = TestFormReplace.class.getMethod("twoFormsOutOfOrder", String.class, String.class); String form = factory(TestFormReplace.class) .createRequest(twoFormsOutOfOrder, new Object[] { "robot", "eggs" }).getEntity().toString(); assertEquals(form, "x-amz-copy-source=/eggs/robot"); } @SuppressWarnings("unchecked") private <T> RestAnnotationProcessor<T> factory(Class<T> clazz) { return ((RestAnnotationProcessor<T>) injector.getInstance( Key.get(TypeLiteral.get(Types.newParameterizedType(RestAnnotationProcessor.class, clazz))))); } Injector injector; DateService dateService = new DateService(); @BeforeClass void setupFactory() { injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bindConstant().annotatedWith(Jsr330.named("testaccount")).to("ralphie"); bind(URI.class).annotatedWith(Localhost.class).toInstance(URI.create("http://localhost:8080")); bind(URI.class).annotatedWith(Localhost2.class).toInstance(URI.create("http://localhost:8081")); bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { public Logger getLogger(String category) { return Logger.NULL; } }); } }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); } protected void assertEntityEquals(GeneratedHttpRequest<?> httpMethod, String toMatch) throws IOException { if (httpMethod.getEntity() == null) { assertNull(toMatch); } else { String entity = (httpMethod.getEntity() instanceof String) ? httpMethod.getEntity().toString() : IOUtils.toString((InputStream) httpMethod.getEntity()); assertEquals(entity, toMatch); } } protected void assertHeadersEqual(GeneratedHttpRequest<?> httpMethod, String toMatch) { assertEquals(HttpUtils.sortAndConcatHeadersIntoString(httpMethod.getHeaders()), toMatch); } protected void assertRequestLineEquals(GeneratedHttpRequest<?> httpMethod, String toMatch) { assertEquals(httpMethod.getRequestLine(), toMatch); } }