mirror of https://github.com/apache/jclouds.git
Issue 5: add URLFetchServiceClient
git-svn-id: http://jclouds.googlecode.com/svn/trunk@115 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
9785a88d1e
commit
f40974f061
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
$HeadURL$
|
||||||
|
$Revision$
|
||||||
|
$Date$
|
||||||
|
|
||||||
|
Copyright (C) 2009 Adrian Cole <adriancole@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.html
|
||||||
|
|
||||||
|
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">
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-gae</artifactId>
|
||||||
|
<name>Google App Engine Components</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Google App Engine Components</description>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/gae</connection>
|
||||||
|
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/gae</developerConnection>
|
||||||
|
<url>http://jclouds.googlecode.com/svn/trunk/gae</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.appengine</groupId>
|
||||||
|
<artifactId>appengine-api</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,158 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adriancole@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.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.Logger;
|
||||||
|
import org.jclouds.command.FutureCommand;
|
||||||
|
import org.jclouds.http.HttpConstants;
|
||||||
|
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 implements HttpFutureCommandClient {
|
||||||
|
private final URL target;
|
||||||
|
private List<HttpRequestFilter> requestFilters = Collections.emptyList();
|
||||||
|
private final Logger logger;
|
||||||
|
private final URLFetchService urlFetchService;
|
||||||
|
|
||||||
|
public List<HttpRequestFilter> getRequestFilters() {
|
||||||
|
return requestFilters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
public void setRequestFilters(List<HttpRequestFilter> requestFilters) {
|
||||||
|
this.requestFilters = requestFilters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public URLFetchServiceClient(java.util.logging.Logger logger, URL target,
|
||||||
|
URLFetchService urlFetchService) throws MalformedURLException {
|
||||||
|
this.urlFetchService = urlFetchService;
|
||||||
|
this.logger = new Logger(logger);
|
||||||
|
this.target = target;
|
||||||
|
this.logger.info("configured to connect to target: %1s", target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <O extends FutureCommand> void submit(O operation) {
|
||||||
|
HttpRequest request = (HttpRequest) operation.getRequest();
|
||||||
|
HTTPResponse gaeResponse = null;
|
||||||
|
try {
|
||||||
|
for (HttpRequestFilter filter : getRequestFilters()) {
|
||||||
|
filter.filter(request);
|
||||||
|
}
|
||||||
|
logger.trace("%1s - converting request %2s", target, request);
|
||||||
|
HTTPRequest gaeRequest = convert(request);
|
||||||
|
logger.trace("%1s - submitting request %2s", target, gaeRequest);
|
||||||
|
gaeResponse = this.urlFetchService.fetch(gaeRequest);
|
||||||
|
logger.trace("%1s - received response %2s", target, gaeResponse);
|
||||||
|
HttpResponse response = convert(gaeResponse);
|
||||||
|
operation.getResponseFuture().setResponse(response);
|
||||||
|
operation.getResponseFuture().run();
|
||||||
|
} 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()));
|
||||||
|
}
|
||||||
|
operation.setException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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()));
|
||||||
|
response.setContentType(response
|
||||||
|
.getFirstHeaderOrNull(HttpConstants.CONTENT_TYPE));
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
.doNotFollowRedirects());
|
||||||
|
for (String header : request.getHeaders().keySet()) {
|
||||||
|
for (String value : request.getHeaders().get(header))
|
||||||
|
gaeRequest.addHeader(new HTTPHeader(header, value));
|
||||||
|
}
|
||||||
|
if (request.getContent() != null) {
|
||||||
|
gaeRequest.addHeader(new HTTPHeader(HttpConstants.CONTENT_TYPE,
|
||||||
|
request.getContentType()));
|
||||||
|
if (request.getContent() instanceof String) {
|
||||||
|
String string = (String) request.getContent();
|
||||||
|
gaeRequest.setPayload(string.getBytes());
|
||||||
|
} else if (request.getContent() instanceof InputStream) {
|
||||||
|
gaeRequest.setPayload(IOUtils.toByteArray((InputStream) request
|
||||||
|
.getContent()));
|
||||||
|
} else if (request.getContent() instanceof File) {
|
||||||
|
gaeRequest.setPayload(IOUtils.toByteArray(new FileInputStream(
|
||||||
|
(File) request.getContent())));
|
||||||
|
} else if (request.getContent() instanceof byte[]) {
|
||||||
|
gaeRequest.setPayload((byte[]) request.getContent());
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Content not supported "
|
||||||
|
+ request.getContent().getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return gaeRequest;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adriancole@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.config;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.jclouds.gae.URLFetchServiceClient;
|
||||||
|
import org.jclouds.http.HttpConstants;
|
||||||
|
import org.jclouds.http.HttpFutureCommandClient;
|
||||||
|
|
||||||
|
import com.google.appengine.api.urlfetch.URLFetchService;
|
||||||
|
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures {@link URLFetchServiceClient}.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class URLFetchServiceClientModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
// note this is not threadsafe, so it cannot be singleton
|
||||||
|
bind(HttpFutureCommandClient.class).to(URLFetchServiceClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
protected URL provideAddress(
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS) String address,
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_PORT) int port,
|
||||||
|
@Named(HttpConstants.PROPERTY_HTTP_SECURE) boolean isSecure)
|
||||||
|
throws MalformedURLException {
|
||||||
|
|
||||||
|
return new URL(isSecure ? "https" : "http", address, port, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
URLFetchService provideURLFetchService() {
|
||||||
|
return URLFetchServiceFactory.getURLFetchService();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adriancole@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 junit.framework.Assert.assertEquals;
|
||||||
|
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 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.HttpConstants;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
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(
|
||||||
|
createNiceMock(java.util.logging.Logger.class), 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(HttpConstants.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(HttpConstants.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(HttpConstants.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(HttpConstants.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.setContent("hoot!");
|
||||||
|
testHoot(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConvertRequestInputStreamContent() throws IOException {
|
||||||
|
HttpRequest request = new HttpRequest("GET", "foo");
|
||||||
|
request.setContent(IOUtils.toInputStream("hoot!"));
|
||||||
|
testHoot(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConvertRequestBytesContent() throws IOException {
|
||||||
|
HttpRequest request = new HttpRequest("GET", "foo");
|
||||||
|
request.setContent("hoot!".getBytes());
|
||||||
|
testHoot(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
void testConvertRequestBadContent() throws IOException {
|
||||||
|
HttpRequest request = new HttpRequest("GET", "foo");
|
||||||
|
request.setContent(new Date());
|
||||||
|
client.convert(request);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRequestFilters() {
|
||||||
|
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
|
||||||
|
filters.add(createNiceMock(HttpRequestFilter.class));
|
||||||
|
assertEquals(client.getRequestFilters().size(), 0);
|
||||||
|
client.setRequestFilters(filters);
|
||||||
|
assertEquals(client.getRequestFilters(), filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.setContent(file);
|
||||||
|
testHoot(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testHoot(HttpRequest request) throws IOException {
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
HTTPRequest gaeRequest = client.convert(request);
|
||||||
|
assertEquals(gaeRequest.getHeaders().get(0).getName(),
|
||||||
|
HttpConstants.CONTENT_TYPE);
|
||||||
|
assertEquals(gaeRequest.getHeaders().get(0).getValue(), "text/plain");
|
||||||
|
assertEquals(new String(gaeRequest.getPayload()), "hoot!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adriancole@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.config;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.gae.URLFetchServiceClient;
|
||||||
|
import org.jclouds.gae.config.URLFetchServiceClientModule;
|
||||||
|
import org.jclouds.http.HttpConstants;
|
||||||
|
import org.jclouds.http.HttpFutureCommandClient;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // TODO: Adrian: Document this!
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public class URLFetchServiceClientModuleTest {
|
||||||
|
|
||||||
|
public void testConfigureBindsClient() {
|
||||||
|
final Properties properties = new Properties();
|
||||||
|
properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost");
|
||||||
|
properties.put(HttpConstants.PROPERTY_HTTP_PORT, "8088");
|
||||||
|
properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false");
|
||||||
|
|
||||||
|
Injector i = Guice.createInjector(new URLFetchServiceClientModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
Names.bindProperties(binder(), properties);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
HttpFutureCommandClient client = i
|
||||||
|
.getInstance(HttpFutureCommandClient.class);
|
||||||
|
assert client instanceof URLFetchServiceClient;
|
||||||
|
}
|
||||||
|
}
|
1
pom.xml
1
pom.xml
|
@ -42,6 +42,7 @@
|
||||||
<module>core</module>
|
<module>core</module>
|
||||||
<module>extensions/httpnio</module>
|
<module>extensions/httpnio</module>
|
||||||
<module>extensions/s3nio</module>
|
<module>extensions/s3nio</module>
|
||||||
|
<module>gae</module>
|
||||||
<module>s3</module>
|
<module>s3</module>
|
||||||
<module>s3/perftest</module>
|
<module>s3/perftest</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -63,11 +63,23 @@
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-gae</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-s3</artifactId>
|
<artifactId>jclouds-s3</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-s3</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<type>test-jar</type>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.guice</groupId>
|
<groupId>com.google.code.guice</groupId>
|
||||||
<artifactId>guice-servlet</artifactId>
|
<artifactId>guice-servlet</artifactId>
|
||||||
|
@ -120,8 +132,8 @@
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.appengine</groupId>
|
<groupId>com.google.appengine</groupId>
|
||||||
<artifactId>tools-api</artifactId>
|
<artifactId>appengine-tools-api</artifactId>
|
||||||
<version>1.2</version>
|
<version>1.2.0</version>
|
||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${appengine.home}/lib/appengine-tools-api.jar</systemPath>
|
<systemPath>${appengine.home}/lib/appengine-tools-api.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
|
@ -24,8 +24,10 @@
|
||||||
package org.jclouds.samples.googleappengine;
|
package org.jclouds.samples.googleappengine;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -33,7 +35,7 @@ import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.aws.s3.S3Context;
|
||||||
import org.jclouds.aws.s3.domain.S3Bucket;
|
import org.jclouds.aws.s3.domain.S3Bucket;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
@ -47,7 +49,7 @@ import com.google.inject.Singleton;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class JCloudsServlet extends HttpServlet {
|
public class JCloudsServlet extends HttpServlet {
|
||||||
@Inject
|
@Inject
|
||||||
S3Connection client;
|
S3Context context;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest httpServletRequest,
|
protected void doGet(HttpServletRequest httpServletRequest,
|
||||||
|
@ -55,13 +57,12 @@ public class JCloudsServlet extends HttpServlet {
|
||||||
IOException {
|
IOException {
|
||||||
Writer writer = httpServletResponse.getWriter();
|
Writer writer = httpServletResponse.getWriter();
|
||||||
try {
|
try {
|
||||||
List<S3Bucket> myBuckets = client.getBuckets().get(10,
|
List<S3Bucket> myBuckets = context.getConnection().getBuckets()
|
||||||
TimeUnit.SECONDS);
|
.get(10, TimeUnit.SECONDS);
|
||||||
writer.write("List:\n");
|
writer.write("List:\n");
|
||||||
for (S3Bucket bucket : myBuckets) {
|
for (S3Bucket bucket : myBuckets) {
|
||||||
writer
|
writer.write(String.format(" %1s: %2s entries%n", bucket
|
||||||
.write(String.format(" Name: %1s%n", bucket
|
.getName(), context.createMapView(bucket).size()));
|
||||||
.getName()));
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServletException(e);
|
throw new ServletException(e);
|
||||||
|
|
|
@ -27,21 +27,18 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.aws.s3.S3Constants;
|
||||||
|
import org.jclouds.aws.s3.S3Context;
|
||||||
import org.jclouds.aws.s3.S3ContextFactory;
|
import org.jclouds.aws.s3.S3ContextFactory;
|
||||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
import org.jclouds.gae.config.URLFetchServiceClientModule;
|
||||||
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
import org.jclouds.lifecycle.Closer;
|
|
||||||
import org.jclouds.samples.googleappengine.JCloudsServlet;
|
import org.jclouds.samples.googleappengine.JCloudsServlet;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.name.Names;
|
|
||||||
import com.google.inject.servlet.GuiceServletContextListener;
|
import com.google.inject.servlet.GuiceServletContextListener;
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
|
@ -53,42 +50,40 @@ import com.google.inject.servlet.ServletModule;
|
||||||
*/
|
*/
|
||||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
public class GuiceServletConfig extends GuiceServletContextListener {
|
||||||
@Inject
|
@Inject
|
||||||
Closer closer;
|
S3Context context;
|
||||||
|
String accessKeyId;
|
||||||
ServletContext context;
|
String secretAccessKey;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
this.context = servletContextEvent.getServletContext();
|
Properties props = loadJCloudsProperties(servletContextEvent);
|
||||||
|
this.accessKeyId = props
|
||||||
|
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
|
||||||
|
this.secretAccessKey = props
|
||||||
|
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
|
||||||
super.contextInitialized(servletContextEvent);
|
super.contextInitialized(servletContextEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Properties loadJCloudsProperties(
|
||||||
protected Injector getInjector() {
|
ServletContextEvent servletContextEvent) {
|
||||||
return Guice.createInjector(
|
InputStream input = servletContextEvent.getServletContext()
|
||||||
new AbstractModule() {
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
Properties props = new Properties();
|
|
||||||
InputStream input = null;
|
|
||||||
try {
|
|
||||||
input = context
|
|
||||||
.getResourceAsStream("/WEB-INF/jclouds.properties");
|
.getResourceAsStream("/WEB-INF/jclouds.properties");
|
||||||
if (input != null)
|
Properties props = new Properties();
|
||||||
|
try {
|
||||||
props.load(input);
|
props.load(input);
|
||||||
else
|
|
||||||
throw new RuntimeException(
|
|
||||||
"not found in classloader");
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(input);
|
IOUtils.closeQuietly(input);
|
||||||
}
|
}
|
||||||
props.putAll(S3ContextFactory.DEFAULT_PROPERTIES);
|
return props;
|
||||||
Names.bindProperties(binder(), props);
|
|
||||||
}
|
}
|
||||||
}, new JavaUrlHttpFutureCommandClientModule(),
|
|
||||||
new S3ContextModule(), new ServletModule() {
|
@Override
|
||||||
|
protected Injector getInjector() {
|
||||||
|
return S3ContextFactory.createInjector(accessKeyId, secretAccessKey,
|
||||||
|
false, new URLFetchServiceClientModule(),
|
||||||
|
new ServletModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
serve("*.s3").with(JCloudsServlet.class);
|
serve("*.s3").with(JCloudsServlet.class);
|
||||||
|
@ -99,11 +94,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
try {
|
context.close();
|
||||||
closer.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
super.contextDestroyed(servletContextEvent);
|
super.contextDestroyed(servletContextEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue