Revision: 10366
Author: b...@google.com
Date: Fri Jun 17 03:59:15 2011
Log: Cherry-pick r10343 into GWT 2.4 branch.
http://code.google.com/p/google-web-toolkit/source/detail?r=10366
Added:
/releases/2.4/user/src/com/google/web/bindery/requestfactory/vm/testing
/releases/2.4/user/src/com/google/web/bindery/requestfactory/vm/testing/UrlRequestTransport.java
/releases/2.4/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryTestServer.java
Modified:
/releases/2.4/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
/releases/2.4/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
/releases/2.4/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
=======================================
--- /dev/null
+++
/releases/2.4/user/src/com/google/web/bindery/requestfactory/vm/testing/UrlRequestTransport.java
Fri Jun 17 03:59:15 2011
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed 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 com.google.web.bindery.requestfactory.vm.testing;
+
+import com.google.web.bindery.requestfactory.shared.RequestFactory;
+import com.google.web.bindery.requestfactory.shared.RequestTransport;
+import com.google.web.bindery.requestfactory.shared.ServerFailure;
+
+import org.json.Cookie;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.InflaterInputStream;
+
+/**
+ * A trivial implementation of RequestTransport that uses a
+ * {@link HttpURLConnection}. Details of the connection can be amended by
+ * overriding {@link #configureConnection(HttpURLConnection)}.
+ * <p>
+ * This implementation only supports {@code http} and {@code https} URLs.
It has
+ * primitive support for recording and playing back cookies, but does not
+ * implement expiration processing.
+ * <p>
+ * Developers who wish to build a more production-ready client should
consider
+ * using a RequestTRansport based around Apache HttpClient instead.
+ */
+public class UrlRequestTransport implements RequestTransport {
+ private static final int CONNECT_TIMEOUT = 30000;
+ private static final int READ_TIMEOUT = 60000;
+
+ private final Map<String, String> cookies = new HashMap<String,
String>();
+ private final URL url;
+
+ /**
+ * Construct a new UrlRequestTransport.
+ *
+ * @param url the URL to connect to
+ * @throws IllegalArgumentException if the url's protocol is not {@code
http}
+ * or {@code https}
+ */
+ public UrlRequestTransport(URL url) {
+ this.url = url;
+ String proto = url.getProtocol().toLowerCase();
+ if (!proto.equals("http") && !proto.equals("https")) {
+ throw new IllegalArgumentException("Only http and https URLs
supported");
+ }
+ }
+
+ /**
+ * Provides access to the cookies that will be sent for subsequent
requests.
+ */
+ public Map<String, String> getCookies() {
+ return cookies;
+ }
+
+ @Override
+ public void send(String payload, TransportReceiver receiver) {
+ HttpURLConnection connection = null;
+ try {
+ connection = (HttpURLConnection) url.openConnection();
+ configureConnection(connection);
+
+ OutputStream out = connection.getOutputStream();
+ out.write(payload.getBytes("UTF-8"));
+ out.close();
+
+ int status = connection.getResponseCode();
+ if (status != HttpURLConnection.HTTP_OK) {
+ ServerFailure failure = new ServerFailure(status + " " +
connection.getResponseMessage());
+ receiver.onTransportFailure(failure);
+ return;
+ }
+
+ List<String> cookieHeaders =
connection.getHeaderFields().get("Set-Cookie");
+ if (cookieHeaders != null) {
+ for (String header : cookieHeaders) {
+ try {
+ JSONObject cookie = Cookie.toJSONObject(header);
+ String name = cookie.getString("name");
+ String value = cookie.getString("value");
+ String domain = cookie.optString("Domain");
+ if (domain == null || url.getHost().endsWith(domain)) {
+ String path = cookie.optString("Path");
+ if (path == null || url.getPath().startsWith(path)) {
+ cookies.put(name, value);
+ }
+ }
+ } catch (JSONException ignored) {
+ }
+ }
+ }
+
+ String encoding = connection.getContentEncoding();
+ InputStream in = connection.getInputStream();
+ if ("gzip".equalsIgnoreCase(encoding)) {
+ in = new GZIPInputStream(in);
+ } else if ("deflate".equalsIgnoreCase(encoding)) {
+ in = new InflaterInputStream(in);
+ } else if (encoding != null) {
+ receiver.onTransportFailure(new ServerFailure("Unknown server
encoding " + encoding));
+ return;
+ }
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ byte[] buffer = new byte[4096];
+ int read = in.read(buffer);
+ while (read != -1) {
+ bytes.write(buffer, 0, read);
+ read = in.read(buffer);
+ }
+ in.close();
+
+ String received = new String(bytes.toByteArray(), "UTF-8");
+ receiver.onTransportSuccess(received);
+ } catch (IOException e) {
+ ServerFailure failure = new ServerFailure(e.getMessage(),
e.getClass().getName(), null, true);
+ receiver.onTransportFailure(failure);
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ }
+
+ protected void configureConnection(HttpURLConnection connection) throws
IOException {
+ connection.setDoInput(true);
+ connection.setDoOutput(true);
+ connection.setRequestMethod("POST");
+ connection.setUseCaches(false);
+ connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
+ connection.setRequestProperty("Content-Type",
RequestFactory.JSON_CONTENT_TYPE_UTF8);
+ connection.setRequestProperty("Host", url.getHost());
+ connection.setRequestProperty("User-Agent",
UrlRequestTransport.class.getCanonicalName());
+ connection.setConnectTimeout(CONNECT_TIMEOUT);
+ connection.setReadTimeout(READ_TIMEOUT);
+
+ if (!cookies.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ boolean needsSemi = false;
+ for (Map.Entry<String, String> entry : cookies.entrySet()) {
+ if (needsSemi) {
+ sb.append("; ");
+ } else {
+ needsSemi = true;
+ }
+ sb.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+ connection.setRequestProperty("Cookie", sb.toString());
+ }
+ }
+}
=======================================
--- /dev/null
+++
/releases/2.4/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryTestServer.java
Fri Jun 17 03:59:15 2011
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed 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 com.google.web.bindery.requestfactory.server;
+
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.bio.SocketConnector;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.SessionHandler;
+import org.mortbay.servlet.GzipFilter;
+
+/**
+ * A utility class for hosting an instance of {@link
RequestFactoryServlet}.
+ */
+public class RequestFactoryTestServer {
+ public static void main(String[] args) {
+ Server server = new Server();
+
+ SocketConnector connector = new SocketConnector();
+ connector.setPort(9999);
+ server.addConnector(connector);
+
+ Context ctx = new Context();
+ ctx.addServlet(RequestFactoryServlet.class, "/gwtRequest");
+ ctx.addFilter(GzipFilter.class, "*", Handler.DEFAULT);
+ SessionHandler sessionHandler = new SessionHandler();
+ sessionHandler.getSessionManager().setMaxInactiveInterval(5);
+ ctx.setSessionHandler(sessionHandler);
+ server.addHandler(ctx);
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+}
=======================================
---
/releases/2.4/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
Thu Jun 9 11:31:51 2011
+++
/releases/2.4/user/src/com/google/web/bindery/requestfactory/server/RequestFactoryJarExtractor.java
Fri Jun 17 03:59:15 2011
@@ -64,6 +64,7 @@
import com.google.web.bindery.requestfactory.shared.WriteOperation;
import com.google.web.bindery.requestfactory.vm.RequestFactorySource;
import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
+import
com.google.web.bindery.requestfactory.vm.testing.UrlRequestTransport;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -649,6 +650,7 @@
List<Class<?>> clientClasses = new ArrayList<Class<?>>();
clientClasses.addAll(sharedClasses);
clientClasses.add(RfApt.class);
+ clientClasses.add(UrlRequestTransport.class);
List<Class<?>> serverClasses = new ArrayList<Class<?>>();
serverClasses.addAll(Arrays.<Class<?>> asList(SERVER_CLASSES));
=======================================
---
/releases/2.4/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
Thu Jun 9 11:31:51 2011
+++
/releases/2.4/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryJreTest.java
Fri Jun 17 03:59:15 2011
@@ -27,20 +27,34 @@
import com.google.web.bindery.requestfactory.vm.RequestFactorySource;
import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;
+import
com.google.web.bindery.requestfactory.vm.testing.UrlRequestTransport;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
/**
* Runs the RequestFactory tests in-process.
*/
public class RequestFactoryJreTest extends RequestFactoryTest {
+ private static final String TEST_SERVER_ADDRESS = System
+ .getProperty("RequestFactory.testUrl");
public static <T extends RequestFactory> T createInProcess(Class<T>
clazz) {
EventBus eventBus = new SimpleEventBus();
T req = RequestFactorySource.create(clazz);
- ServiceLayer serviceLayer = ServiceLayer.create();
- SimpleRequestProcessor processor = new
SimpleRequestProcessor(serviceLayer);
- req.initialize(eventBus, new InProcessRequestTransport(processor));
+ if (TEST_SERVER_ADDRESS != null) {
+ try {
+ UrlRequestTransport transport = new UrlRequestTransport(new
URL(TEST_SERVER_ADDRESS));
+ req.initialize(eventBus, transport);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ ServiceLayer serviceLayer = ServiceLayer.create();
+ SimpleRequestProcessor processor = new
SimpleRequestProcessor(serviceLayer);
+ req.initialize(eventBus, new InProcessRequestTransport(processor));
+ }
return req;
}
=======================================
---
/releases/2.4/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
Fri Jun 10 11:06:22 2011
+++
/releases/2.4/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java
Fri Jun 17 03:59:15 2011
@@ -30,6 +30,7 @@
import
com.google.web.bindery.requestfactory.shared.impl.SimpleEntityProxyIdTest;
import junit.framework.Test;
+import junit.framework.TestResult;
import junit.framework.TestSuite;
/**
@@ -61,6 +62,37 @@
* Used to test the JVM-only client package.
*/
public static void main(String[] args) {
- junit.textui.TestRunner.run(suite());
+ int count;
+ boolean keepRunning;
+ switch (args.length) {
+ case 0:
+ keepRunning = false;
+ count = 1;
+ break;
+ case 1:
+ keepRunning = false;
+ count = Integer.parseInt(args[0], 10);
+ break;
+ case 2:
+ if ("-k".equals(args[0])) {
+ keepRunning = true;
+ count = Integer.parseInt(args[1], 10);
+ break;
+ }
+ // Fall-through intentional
+ default:
+ System.err.println(RequestFactoryJreSuite.class.getName() + " [-k]
<number of cycles>");
+ System.err.println(" -k: keep running");
+ System.err.println(" -1 cycles means run forever");
+ System.exit(-1);
+ return;
+ }
+ final Test suite = suite();
+ for (int i = 0; i < count || count == -1; i++) {
+ TestResult run = junit.textui.TestRunner.run(suite);
+ if (!keepRunning && (run.errorCount() + run.failureCount()) > 0) {
+ System.exit(-1);
+ }
+ }
}
}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors