mirror of https://github.com/apache/jclouds.git
moved gae to extensions
git-svn-id: http://jclouds.googlecode.com/svn/trunk@639 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
d103d1a637
commit
88b34e6a9f
|
@ -31,7 +31,7 @@
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
<artifactId>jclouds-project</artifactId>
|
<artifactId>jclouds-project</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../project/pom.xml</relativePath>
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
<description>Google App Engine Components</description>
|
<description>Google App Engine Components</description>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/gae</connection>
|
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/extensions/gae</connection>
|
||||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/gae</developerConnection>
|
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/extensions/gae</developerConnection>
|
||||||
<url>http://jclouds.googlecode.com/svn/trunk/gae</url>
|
<url>http://jclouds.googlecode.com/svn/trunk/extensions/gae</url>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
|
@ -1,169 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* 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.gae;
|
|
||||||
|
|
||||||
import static com.google.appengine.api.urlfetch.FetchOptions.Builder.disallowTruncate;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.http.BaseHttpFutureCommandClient;
|
|
||||||
import org.jclouds.http.HttpFutureCommand;
|
|
||||||
import org.jclouds.http.HttpFutureCommandClient;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPHeader;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPMethod;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPRequest;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPResponse;
|
|
||||||
import com.google.appengine.api.urlfetch.URLFetchService;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Google App Engine version of {@link HttpFutureCommandClient}
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
|
|
||||||
private final URLFetchService urlFetchService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public URLFetchServiceClient(URL target, URLFetchService urlFetchService)
|
|
||||||
throws MalformedURLException {
|
|
||||||
super(target);
|
|
||||||
this.urlFetchService = urlFetchService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void submit(HttpFutureCommand<?> command) {
|
|
||||||
HttpRequest request = command.getRequest();
|
|
||||||
HTTPResponse gaeResponse = null;
|
|
||||||
try {
|
|
||||||
for (HttpRequestFilter filter : requestFilters) {
|
|
||||||
filter.filter(request);
|
|
||||||
}
|
|
||||||
HttpResponse response = null;
|
|
||||||
for (;;) {
|
|
||||||
logger.trace("%1s - converting request %2s", target, request);
|
|
||||||
HTTPRequest gaeRequest = convert(request);
|
|
||||||
if (logger.isTraceEnabled())
|
|
||||||
logger.trace("%1s - submitting request %2s, headers: %3s",
|
|
||||||
target, gaeRequest.getURL(),
|
|
||||||
headersAsString(gaeRequest.getHeaders()));
|
|
||||||
gaeResponse = this.urlFetchService.fetch(gaeRequest);
|
|
||||||
if (logger.isTraceEnabled())
|
|
||||||
logger.trace(
|
|
||||||
"%1s - received response code %2s, headers: %3s",
|
|
||||||
target, gaeResponse.getResponseCode(),
|
|
||||||
headersAsString(gaeResponse.getHeaders()));
|
|
||||||
response = convert(gaeResponse);
|
|
||||||
if (isRetryable(command, response))
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
handleResponse(command, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (gaeResponse != null && gaeResponse.getContent() != null) {
|
|
||||||
logger.error(e,
|
|
||||||
"error encountered during the execution: %1s%n%2s",
|
|
||||||
gaeResponse, new String(gaeResponse.getContent()));
|
|
||||||
}
|
|
||||||
command.setException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String headersAsString(List<HTTPHeader> headers) {
|
|
||||||
StringBuilder builder = new StringBuilder("");
|
|
||||||
for (HTTPHeader header : headers)
|
|
||||||
builder.append("[").append(header.getName()).append("=").append(
|
|
||||||
header.getValue()).append("],");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* byte [] content is replayable and the only content type supportable by
|
|
||||||
* GAE. As such, we convert the original request content to a byte array.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
void changeRequestContentToBytes(HttpRequest request) throws IOException {
|
|
||||||
Object content = request.getPayload();
|
|
||||||
if (content == null || content instanceof byte[]) {
|
|
||||||
return;
|
|
||||||
} else if (content instanceof String) {
|
|
||||||
String string = (String) content;
|
|
||||||
request.setPayload(string.getBytes());
|
|
||||||
} else if (content instanceof InputStream || content instanceof File) {
|
|
||||||
InputStream i = content instanceof InputStream ? (InputStream) content
|
|
||||||
: new FileInputStream((File) content);
|
|
||||||
try {
|
|
||||||
request.setPayload(IOUtils.toByteArray(i));
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Content not supported "
|
|
||||||
+ content.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
HttpResponse convert(HTTPResponse gaeResponse) {
|
|
||||||
HttpResponse response = new HttpResponse();
|
|
||||||
response.setStatusCode(gaeResponse.getResponseCode());
|
|
||||||
for (HTTPHeader header : gaeResponse.getHeaders()) {
|
|
||||||
response.getHeaders().put(header.getName(), header.getValue());
|
|
||||||
}
|
|
||||||
if (gaeResponse.getContent() != null) {
|
|
||||||
response.setContent(new ByteArrayInputStream(gaeResponse
|
|
||||||
.getContent()));
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
HTTPRequest convert(HttpRequest request) throws IOException {
|
|
||||||
URL url = new URL(target, request.getUri());
|
|
||||||
HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod
|
|
||||||
.valueOf(request.getMethod()), disallowTruncate());
|
|
||||||
for (String header : request.getHeaders().keySet()) {
|
|
||||||
for (String value : request.getHeaders().get(header))
|
|
||||||
gaeRequest.addHeader(new HTTPHeader(header, value));
|
|
||||||
}
|
|
||||||
if (request.getPayload() != null) {
|
|
||||||
changeRequestContentToBytes(request);
|
|
||||||
gaeRequest.setPayload((byte[]) request.getPayload());
|
|
||||||
}
|
|
||||||
return gaeRequest;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,185 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* 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.gae;
|
|
||||||
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
|
||||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.jclouds.http.HttpHeaders;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.testng.annotations.BeforeTest;
|
|
||||||
import org.testng.annotations.Parameters;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPHeader;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPRequest;
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPResponse;
|
|
||||||
import com.google.appengine.api.urlfetch.URLFetchService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public class URLFetchServiceClientTest {
|
|
||||||
URLFetchServiceClient client;
|
|
||||||
URL url;
|
|
||||||
|
|
||||||
@BeforeTest
|
|
||||||
void setupClient() throws MalformedURLException {
|
|
||||||
url = new URL("http://localhost:80");
|
|
||||||
client = new URLFetchServiceClient(url,
|
|
||||||
createNiceMock(URLFetchService.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertWithHeaders() {
|
|
||||||
HTTPResponse gaeResponse = createMock(HTTPResponse.class);
|
|
||||||
expect(gaeResponse.getResponseCode()).andReturn(200);
|
|
||||||
List<HTTPHeader> headers = new ArrayList<HTTPHeader>();
|
|
||||||
headers.add(new HTTPHeader(HttpHeaders.CONTENT_TYPE, "text/xml"));
|
|
||||||
expect(gaeResponse.getHeaders()).andReturn(headers);
|
|
||||||
expect(gaeResponse.getContent()).andReturn(null).atLeastOnce();
|
|
||||||
replay(gaeResponse);
|
|
||||||
HttpResponse response = client.convert(gaeResponse);
|
|
||||||
assertEquals(response.getStatusCode(), 200);
|
|
||||||
assertEquals(response.getContent(), null);
|
|
||||||
assertEquals(response.getHeaders().size(), 1);
|
|
||||||
assertEquals(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),
|
|
||||||
"text/xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertWithContent() throws IOException {
|
|
||||||
HTTPResponse gaeResponse = createMock(HTTPResponse.class);
|
|
||||||
expect(gaeResponse.getResponseCode()).andReturn(200);
|
|
||||||
List<HTTPHeader> headers = new ArrayList<HTTPHeader>();
|
|
||||||
headers.add(new HTTPHeader(HttpHeaders.CONTENT_TYPE, "text/xml"));
|
|
||||||
expect(gaeResponse.getHeaders()).andReturn(headers);
|
|
||||||
expect(gaeResponse.getContent()).andReturn("hello".getBytes())
|
|
||||||
.atLeastOnce();
|
|
||||||
replay(gaeResponse);
|
|
||||||
HttpResponse response = client.convert(gaeResponse);
|
|
||||||
assertEquals(response.getStatusCode(), 200);
|
|
||||||
assertEquals(IOUtils.toString(response.getContent()), "hello");
|
|
||||||
assertEquals(response.getHeaders().size(), 1);
|
|
||||||
assertEquals(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),
|
|
||||||
"text/xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestGetsTargetAndUri() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
HTTPRequest gaeRequest = client.convert(request);
|
|
||||||
assertEquals(gaeRequest.getURL().getPath(), "/foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestSetsFetchOptions() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
HTTPRequest gaeRequest = client.convert(request);
|
|
||||||
assert gaeRequest.getFetchOptions() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestSetsHeaders() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.getHeaders().put("foo", "bar");
|
|
||||||
HTTPRequest gaeRequest = client.convert(request);
|
|
||||||
assertEquals(gaeRequest.getHeaders().get(0).getName(), "foo");
|
|
||||||
assertEquals(gaeRequest.getHeaders().get(0).getValue(), "bar");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestNoContent() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
HTTPRequest gaeRequest = client.convert(request);
|
|
||||||
assert gaeRequest.getPayload() == null;
|
|
||||||
assertEquals(gaeRequest.getHeaders().size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestStringContent() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.setPayload("hoot!");
|
|
||||||
testHoot(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestInputStreamContent() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.setPayload(IOUtils.toInputStream("hoot!"));
|
|
||||||
testHoot(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConvertRequestBytesContent() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.setPayload("hoot!".getBytes());
|
|
||||||
testHoot(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
|
||||||
void testConvertRequestBadContent() throws IOException {
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.setPayload(new Date());
|
|
||||||
client.convert(request);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Parameters("basedir")
|
|
||||||
void testConvertRequestFileContent(String basedir) throws IOException {
|
|
||||||
File file = new File(basedir, "target/testfiles/hoot");
|
|
||||||
file.getParentFile().mkdirs();
|
|
||||||
IOUtils.write("hoot!", new FileOutputStream(file));
|
|
||||||
HttpRequest request = new HttpRequest("GET", "foo");
|
|
||||||
request.setPayload(file);
|
|
||||||
testHoot(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testHoot(HttpRequest request) throws IOException {
|
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE,"text/plain");
|
|
||||||
HTTPRequest gaeRequest = client.convert(request);
|
|
||||||
assertEquals(gaeRequest.getHeaders().get(0).getName(),
|
|
||||||
HttpHeaders.CONTENT_TYPE);
|
|
||||||
assertEquals(gaeRequest.getHeaders().get(0).getValue(), "text/plain");
|
|
||||||
assertEquals(new String(gaeRequest.getPayload()), "hoot!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue