You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by bl...@apache.org on 2010/11/03 22:38:09 UTC
svn commit: r1030701 - in /incubator/wink/trunk: ./
wink-client-asynchttpclient/ wink-client-asynchttpclient/src/
wink-client-asynchttpclient/src/main/
wink-client-asynchttpclient/src/main/java/
wink-client-asynchttpclient/src/main/java/org/ wink-clien...
Author: bluk
Date: Wed Nov 3 21:38:09 2010
New Revision: 1030701
URL: http://svn.apache.org/viewvc?rev=1030701&view=rev
Log:
Add Wink asynchronous HTTP client support
See [WINK-326]
Thanks to Jean-Francois Arcand and
Jason Dillon for the contribution.
Added:
incubator/wink/trunk/wink-client-asynchttpclient/
incubator/wink/trunk/wink-client-asynchttpclient/pom.xml
incubator/wink/trunk/wink-client-asynchttpclient/src/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConfiguration.java
incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConnectionHandler.java
incubator/wink/trunk/wink-client-asynchttpclient/src/test/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/AsyncClientTest.java
incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/ClientTestSupport.java
Modified:
incubator/wink/trunk/pom.xml
Modified: incubator/wink/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/pom.xml?rev=1030701&r1=1030700&r2=1030701&view=diff
==============================================================================
--- incubator/wink/trunk/pom.xml (original)
+++ incubator/wink/trunk/pom.xml Wed Nov 3 21:38:09 2010
@@ -42,6 +42,7 @@
<module>wink-server</module>
<module>wink-client</module>
<module>wink-client-apache-httpclient</module>
+ <module>wink-client-asynchttpclient</module>
<module>wink-spring-support</module>
<module>wink-webdav</module>
<module>wink-json4j</module>
@@ -490,6 +491,11 @@
</dependency>
<dependency>
<groupId>org.apache.wink</groupId>
+ <artifactId>wink-client-asynchttpclient</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wink</groupId>
<artifactId>wink-abdera-provider</artifactId>
<version>${project.version}</version>
</dependency>
Added: incubator/wink/trunk/wink-client-asynchttpclient/pom.xml
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-asynchttpclient/pom.xml?rev=1030701&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client-asynchttpclient/pom.xml (added)
+++ incubator/wink/trunk/wink-client-asynchttpclient/pom.xml Wed Nov 3 21:38:09 2010
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>wink-client-asynchttpclient</artifactId>
+ <name>Apache Wink Client :: Async Http Client</name>
+ <parent>
+ <groupId>org.apache.wink</groupId>
+ <artifactId>wink</artifactId>
+ <version>1.1.2-incubating-SNAPSHOT</version>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.wink</groupId>
+ <artifactId>wink-client</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.ning</groupId>
+ <artifactId>async-http-client</artifactId>
+ <version>1.3.3</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.wink</groupId>
+ <artifactId>wink-component-test-support</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jmock</groupId>
+ <artifactId>jmock-junit3</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Added: incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConfiguration.java?rev=1030701&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConfiguration.java (added)
+++ incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConfiguration.java Wed Nov 3 21:38:09 2010
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.sonatype.wink.client;
+
+import com.ning.http.client.AsyncHttpClient;
+import org.apache.wink.client.ClientConfig;
+import org.apache.wink.client.handlers.ConnectionHandler;
+
+/**
+ * Configure the {@link AsyncHttpClient}
+ */
+public class AsyncHttpClientConfiguration
+ extends ClientConfig
+{
+ private AsyncHttpClient client;
+
+ public AsyncHttpClientConfiguration() {
+ this(null);
+ }
+
+ public AsyncHttpClientConfiguration(final AsyncHttpClient client) {
+ this.client = client;
+ }
+
+ @Override
+ protected ConnectionHandler getConnectionHandler() {
+ return new AsyncHttpClientConnectionHandler(client);
+ }
+}
Added: incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConnectionHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConnectionHandler.java?rev=1030701&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConnectionHandler.java (added)
+++ incubator/wink/trunk/wink-client-asynchttpclient/src/main/java/org/sonatype/wink/client/AsyncHttpClientConnectionHandler.java Wed Nov 3 21:38:09 2010
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * 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.sonatype.wink.client;
+
+import com.ning.http.client.AsyncCompletionHandlerBase;
+import com.ning.http.client.AsyncHttpClient;
+import com.ning.http.client.AsyncHttpClientConfig;
+import com.ning.http.client.FluentCaseInsensitiveStringsMap;
+import com.ning.http.client.ProxyServer;
+import com.ning.http.client.Request;
+import com.ning.http.client.RequestBuilder;
+import com.ning.http.client.Response;
+import org.apache.wink.client.ClientConfig;
+import org.apache.wink.client.ClientRequest;
+import org.apache.wink.client.ClientResponse;
+import org.apache.wink.client.handlers.HandlerContext;
+import org.apache.wink.client.internal.handlers.AbstractConnectionHandler;
+import org.apache.wink.client.internal.handlers.ClientResponseImpl;
+import org.apache.wink.common.internal.WinkConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Extends {@link AbstractConnectionHandler} and uses {@link AsyncHttpClient} to perform HTTP request execution.
+ */
+public class AsyncHttpClientConnectionHandler
+ extends AbstractConnectionHandler
+{
+ private static final Logger logger = LoggerFactory.getLogger(AsyncHttpClientConnectionHandler.class);
+
+ private AsyncHttpClient asyncHttpClient;
+
+ public AsyncHttpClientConnectionHandler(final AsyncHttpClient asyncHttpClient) {
+ this.asyncHttpClient = asyncHttpClient;
+ }
+
+ public ClientResponse handle(final ClientRequest request, final HandlerContext context) throws Exception {
+ Response response = processRequest(request, context);
+ return processResponse(request, context, response);
+ }
+
+ private Response processRequest(final ClientRequest cr, final HandlerContext context) throws IOException {
+ AsyncHttpClient asyncHttpClient = openConnection(cr);
+ NonCloseableOutputStream ncos = new NonCloseableOutputStream();
+ OutputStream os = adaptOutputStream(ncos, cr, context.getOutputStreamAdapters());
+
+ Request request = setupHttpRequest(cr, ncos, os);
+ Response response;
+
+ try {
+ response = asyncHttpClient.executeRequest(request, new AsyncCompletionHandlerBase()
+ {
+ @Override
+ public Response onCompleted(final Response response) throws Exception {
+ logger.debug("Response received: {}", response);
+ return super.onCompleted(response);
+ }
+
+ public void onThrowable(Throwable t) {
+ logger.error(AsyncCompletionHandlerBase.class.getName(), t);
+ }
+ }).get();
+ }
+ catch (InterruptedException e) {
+ throw (IOException)new IOException().initCause(e);
+ }
+ catch (ExecutionException e) {
+ throw (IOException)new IOException().initCause(e);
+ }
+
+ return response;
+ }
+
+ private Request setupHttpRequest(final ClientRequest cr, final NonCloseableOutputStream ncos, final OutputStream adaptedOutputStream) {
+ URI uri = cr.getURI();
+ String method = cr.getMethod();
+ RequestBuilder builder = new RequestBuilder(method);
+ builder.setUrl(uri.toString());
+
+ MultivaluedMap<String, String> headers = cr.getHeaders();
+ for (String header : headers.keySet()) {
+ List<String> values = headers.get(header);
+ for (String value : values) {
+ if (value != null) {
+ builder.addHeader(header, value);
+ }
+ }
+ }
+
+ if (method.equalsIgnoreCase("PUT") || method.equalsIgnoreCase("POST")) {
+ builder.setBody(new Request.EntityWriter()
+ {
+ public void writeEntity(OutputStream os) throws IOException {
+ ncos.setOutputStream(os);
+ AsyncHttpClientConnectionHandler.this.writeEntity(cr, adaptedOutputStream);
+ }
+ });
+ }
+
+ return builder.build();
+ }
+
+ private AsyncHttpClient openConnection(final ClientRequest request) {
+ if (asyncHttpClient != null) {
+ return asyncHttpClient;
+ }
+
+ // cast is safe because we're on the client
+ ClientConfig config = (ClientConfig) request.getAttribute(WinkConfiguration.class);
+
+ AsyncHttpClientConfig.Builder c = new AsyncHttpClientConfig.Builder();
+ c.setConnectionTimeoutInMs(config.getConnectTimeout());
+ c.setRequestTimeoutInMs(config.getReadTimeout());
+ c.setFollowRedirects(config.isFollowRedirects());
+
+ // setup proxy
+ if (config.getProxyHost() != null) {
+ c.setProxyServer(new ProxyServer(config.getProxyHost(), config.getProxyPort()));
+ }
+
+ return new AsyncHttpClient(c.build());
+ }
+
+ private ClientResponse processResponse(final ClientRequest request, final HandlerContext context, final Response response)
+ throws IllegalStateException, IOException
+ {
+ ClientResponse cr = createResponse(request, response);
+ InputStream is = adaptInputStream(response.getResponseBodyAsStream(), cr, context.getInputStreamAdapters());
+ cr.setEntity(is);
+ return cr;
+ }
+
+ private ClientResponse createResponse(final ClientRequest request, final Response response) {
+ final ClientResponseImpl cr = new ClientResponseImpl();
+ cr.setStatusCode(response.getStatusCode());
+ cr.setMessage(response.getStatusText());
+ cr.getAttributes().putAll(request.getAttributes());
+
+ // FIXME: Should we use a constant here to avoid creating this dummy runnable every time?
+ cr.setContentConsumer(new Runnable()
+ {
+ public void run() {
+ // empty
+ }
+ });
+
+ processResponseHeaders(cr, response);
+
+ return cr;
+ }
+
+ private void processResponseHeaders(final ClientResponse cr, final Response response) {
+ FluentCaseInsensitiveStringsMap headers = response.getHeaders();
+ for (Map.Entry<String, List<String>> header : headers) {
+ for (String value : header.getValue()) {
+ cr.getHeaders().add(header.getKey(), value);
+ }
+ }
+ }
+
+ // TODO: move this class to the base class
+
+ private static class NonCloseableOutputStream
+ extends OutputStream
+ {
+ OutputStream os;
+
+ public NonCloseableOutputStream() {
+ }
+
+ public void setOutputStream(final OutputStream os) {
+ this.os = os;
+ }
+
+ @Override
+ public void close() throws IOException {
+ // do nothing
+ }
+
+ @Override
+ public void flush() throws IOException {
+ os.flush();
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ os.write(b, off, len);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ os.write(b);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ os.write(b);
+ }
+ }
+}
Added: incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/AsyncClientTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/AsyncClientTest.java?rev=1030701&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/AsyncClientTest.java (added)
+++ incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/AsyncClientTest.java Wed Nov 3 21:38:09 2010
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.apache.wink.client;
+
+import org.sonatype.wink.client.AsyncHttpClientConfiguration;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class AsyncClientTest
+ extends ClientTestSupport
+{
+ protected RestClient getRestClient() {
+ return new RestClient(new AsyncHttpClientConfiguration().applications(new Application() {
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> set = new HashSet<Class<?>>();
+ set.add(TestGenericsProvider.class);
+ return set;
+ }
+
+ }));
+ }
+}
Added: incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/ClientTestSupport.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/ClientTestSupport.java?rev=1030701&view=auto
==============================================================================
--- incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/ClientTestSupport.java (added)
+++ incubator/wink/trunk/wink-client-asynchttpclient/src/test/java/org/apache/wink/client/ClientTestSupport.java Wed Nov 3 21:38:09 2010
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * 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.apache.wink.client;
+
+import org.apache.wink.client.MockHttpServer.MockHttpServerResponse;
+import org.apache.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.WinkConfiguration;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
+import org.apache.wink.common.utils.ProviderUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.text.MessageFormat;
+
+/**
+ * Support for client tests.
+ */
+public abstract class ClientTestSupport
+ extends BaseTest
+{
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ Mockery mockery = new Mockery();
+ final RuntimeContext context = mockery.mock(RuntimeContext.class);
+ mockery.checking(new Expectations() {{
+ allowing(context).getAttribute(WinkConfiguration.class); will(returnValue(null));
+ }});
+
+ RuntimeContextTLS.setRuntimeContext(context);
+ }
+
+ @Override
+ public void tearDown() {
+ RuntimeContextTLS.setRuntimeContext(null);
+ }
+
+ public static class TestGenerics<T> {
+ private T t;
+
+ public TestGenerics() {
+ }
+
+ public T getT() {
+ return t;
+ }
+
+ public void setT(T t) {
+ this.t = t;
+ }
+ }
+
+ @Provider
+ public static class TestGenericsProvider
+ implements MessageBodyWriter<TestGenerics<String>>,MessageBodyReader<TestGenerics<String>>
+ {
+ public long getSize(TestGenerics<String> t,
+ Class<?> type,
+ Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType) {
+ return t.getT().length();
+ }
+
+ public boolean isWriteable(Class<?> type,
+ Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType) {
+ return isTestGenericsString(type, genericType);
+ }
+
+ private boolean isTestGenericsString(Class<?> type, Type genericType) {
+ return type.equals(TestGenerics.class) && genericType instanceof ParameterizedType
+ && ((ParameterizedType)genericType).getActualTypeArguments()[0]
+ .equals(String.class);
+ }
+
+ public void writeTo(TestGenerics<String> t,
+ Class<?> type,
+ Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders,
+ OutputStream entityStream) throws IOException, WebApplicationException {
+ String string = t.getT();
+ ProviderUtils.writeToStream(string, entityStream, mediaType);
+ }
+
+ public boolean isReadable(Class<?> type,
+ Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType) {
+ return isTestGenericsString(type, genericType);
+ }
+
+ public TestGenerics<String> readFrom(Class<TestGenerics<String>> type,
+ Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders,
+ InputStream entityStream) throws IOException,
+ WebApplicationException {
+ TestGenerics<String> tg = new TestGenerics<String>();
+ String string = ProviderUtils.readFromStreamAsString(entityStream, mediaType);
+ tg.setT(string);
+ return tg;
+ }
+ }
+
+ protected abstract RestClient getRestClient();
+
+ public void testResourceGet() {
+ MockHttpServerResponse response1 = new MockHttpServerResponse();
+ response1.setMockResponseCode(200);
+ MockHttpServerResponse response2 = new MockHttpServerResponse();
+ response2.setMockResponseCode(200);
+ MockHttpServerResponse response3 = new MockHttpServerResponse();
+ response3.setMockResponseCode(200);
+ server.setMockHttpServerResponses(response1, response2, response3);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL);
+
+ String string = resource.get(String.class);
+ assertEquals(RECEIVED_MESSAGE, string);
+
+ // do get with response
+ ClientResponse clientResponse = resource.get();
+ assertEquals(RECEIVED_MESSAGE, clientResponse.getEntity(String.class));
+
+ // test generic entity
+ TestGenerics<String> tg = resource.get(new EntityType<TestGenerics<String>>() {});
+ assertEquals(RECEIVED_MESSAGE, tg.getT());
+ }
+
+ public void testResourcePut() throws IOException {
+ MockHttpServerResponse response1 = new MockHttpServerResponse();
+ response1.setMockResponseCode(200);
+ MockHttpServerResponse response2 = new MockHttpServerResponse();
+ response2.setMockResponseCode(200);
+ MockHttpServerResponse response3 = new MockHttpServerResponse();
+ response3.setMockResponseCode(200);
+ server.setMockHttpServerResponses(response1, response2, response3);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL + "/testResourcePut");
+ String response =
+ resource.contentType("text/plain").accept("text/plain").put(String.class, SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, response);
+ assertEquals(SENT_MESSAGE, server.getRequestContentAsString());
+
+ // do put with response
+ ClientResponse clientResponse = resource.put(SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, clientResponse.getEntity(String.class));
+
+ // test generic entity
+ TestGenerics<String> tg = resource.put(new EntityType<TestGenerics<String>>() {
+ }, SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, tg.getT());
+
+ }
+
+ public void testResourcePost() throws IOException {
+ MockHttpServerResponse response1 = new MockHttpServerResponse();
+ response1.setMockResponseCode(200);
+ MockHttpServerResponse response2 = new MockHttpServerResponse();
+ response2.setMockResponseCode(200);
+ MockHttpServerResponse response3 = new MockHttpServerResponse();
+ response3.setMockResponseCode(200);
+ server.setMockHttpServerResponses(response1, response2, response3);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL + "/testResourcePost");
+ String response =
+ resource.contentType("text/plain").accept("text/plain")
+ .post(String.class, SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, response);
+ assertEquals(SENT_MESSAGE, server.getRequestContentAsString());
+
+ // do post with response
+ ClientResponse clientResponse = resource.post(SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, clientResponse.getEntity(String.class));
+
+ // test generic entity
+ TestGenerics<String> tg = resource.post(new EntityType<TestGenerics<String>>() {
+ }, SENT_MESSAGE);
+ assertEquals(RECEIVED_MESSAGE, tg.getT());
+ }
+
+ public void testResourceDelete() {
+ MockHttpServerResponse response1 = new MockHttpServerResponse();
+ response1.setMockResponseCode(200);
+ MockHttpServerResponse response2 = new MockHttpServerResponse();
+ response2.setMockResponseCode(200);
+ MockHttpServerResponse response3 = new MockHttpServerResponse();
+ response3.setMockResponseCode(200);
+ server.setMockHttpServerResponses(response1, response2, response3);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL);
+ String response = resource.accept(MediaType.TEXT_PLAIN_TYPE).delete(String.class);
+ assertEquals(RECEIVED_MESSAGE, response);
+
+ // do delete with response
+ ClientResponse clientResponse = resource.delete();
+ assertEquals(RECEIVED_MESSAGE, clientResponse.getEntity(String.class));
+
+ // test generic entity
+ TestGenerics<String> tg = resource.delete(new EntityType<TestGenerics<String>>() {
+ });
+ assertEquals(RECEIVED_MESSAGE, tg.getT());
+ }
+
+ public void testInvoke() {
+ MockHttpServerResponse response1 = new MockHttpServerResponse();
+ response1.setMockResponseCode(200);
+ MockHttpServerResponse response2 = new MockHttpServerResponse();
+ response2.setMockResponseCode(200);
+ server.setMockHttpServerResponses(response1, response2);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL);
+
+ String string = resource.invoke("GET", String.class, null);
+ assertEquals(RECEIVED_MESSAGE, string);
+
+ // test generic entity
+ TestGenerics<String> tg = resource.invoke("GET", new EntityType<TestGenerics<String>>() {
+ }, null);
+ assertEquals(RECEIVED_MESSAGE, tg.getT());
+ }
+
+ public void testHttpErrorNoResponse() throws IOException {
+ server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL);
+ try {
+ resource.accept("text/plain").invoke("GET", String.class, null);
+ fail("ClientWebException must be thrown");
+ } catch (ClientWebException e) {
+ assertTrue(e.getResponse().getStatusCode() == 400);
+ }
+ }
+
+ public void testHttpErrorWithResponse() throws IOException {
+ server.getMockHttpServerResponses().get(0).setMockResponseCode(400);
+
+ RestClient client = getRestClient();
+ Resource resource = client.resource(serviceURL);
+ try {
+ ClientResponse res = resource.accept("text/plain").get();
+ assertTrue(res.getStatusCode() == 400);
+ } catch (Exception e) {
+ fail("Exception must not be thrown");
+ }
+ }
+
+ public void testResponseCharset() throws IOException {
+
+ MockHttpServer server = new MockHttpServer(34567);
+ server.getMockHttpServerResponses().get(0).setMockResponseCode(200);
+ server.getMockHttpServerResponses().get(0).setMockResponseContent("REQUEST".getBytes("UTF-16"));
+ server.getMockHttpServerResponses().get(0).setMockResponseContentType("text/plain; charset=UTF-16");
+
+ server.startServer();
+ try {
+ RestClient client = getRestClient();
+ Resource resource =
+ client.resource(MessageFormat.format(SERVICE_URL, String.valueOf(server
+ .getServerPort())));
+ String response = resource.accept(MediaType.TEXT_PLAIN_TYPE).get(String.class);
+ assertEquals("REQUEST", response);
+
+ } finally {
+ server.stopServer();
+ }
+ }
+}