diff --git a/gae/pom.xml b/gae/pom.xml new file mode 100644 index 0000000000..5f434c8e79 --- /dev/null +++ b/gae/pom.xml @@ -0,0 +1,68 @@ + + + + + org.jclouds + jclouds-project + 1.0-SNAPSHOT + ../project/pom.xml + + 4.0.0 + org.jclouds + jclouds-gae + Google App Engine Components + jar + Google App Engine Components + + + scm:svn:http://jclouds.googlecode.com/svn/trunk/gae + scm:svn:https://jclouds.googlecode.com/svn/trunk/gae + http://jclouds.googlecode.com/svn/trunk/gae + + + + + com.google.appengine + appengine-api + 1.2.0 + + + ${project.groupId} + jclouds-core + ${project.version} + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + diff --git a/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java b/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java new file mode 100644 index 0000000000..dac5f64e6e --- /dev/null +++ b/gae/src/main/java/org/jclouds/gae/URLFetchServiceClient.java @@ -0,0 +1,158 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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 requestFilters = Collections.emptyList(); + private final Logger logger; + private final URLFetchService urlFetchService; + + public List getRequestFilters() { + return requestFilters; + } + + @Inject(optional = true) + public void setRequestFilters(List 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 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; + } +} diff --git a/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java b/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java new file mode 100644 index 0000000000..5545bc5933 --- /dev/null +++ b/gae/src/main/java/org/jclouds/gae/config/URLFetchServiceClientModule.java @@ -0,0 +1,69 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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(); + } + +} \ No newline at end of file diff --git a/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java b/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java new file mode 100644 index 0000000000..3d24cf07fa --- /dev/null +++ b/gae/src/test/java/org/jclouds/gae/URLFetchServiceClientTest.java @@ -0,0 +1,196 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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 headers = new ArrayList(); + 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 headers = new ArrayList(); + 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 filters = new ArrayList(); + 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!"); + } + +} diff --git a/gae/src/test/java/org/jclouds/gae/config/URLFetchServiceClientModuleTest.java b/gae/src/test/java/org/jclouds/gae/config/URLFetchServiceClientModuleTest.java new file mode 100644 index 0000000000..f4b3837c8a --- /dev/null +++ b/gae/src/test/java/org/jclouds/gae/config/URLFetchServiceClientModuleTest.java @@ -0,0 +1,63 @@ +/** + * + * Copyright (C) 2009 Adrian Cole + * + * ==================================================================== + * 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; + } +} diff --git a/pom.xml b/pom.xml index 80bc03e86d..0966e0c0d6 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ core extensions/httpnio extensions/s3nio + gae s3 s3/perftest diff --git a/samples/googleappengine/pom.xml b/samples/googleappengine/pom.xml index 20f422d031..a33784e9d8 100644 --- a/samples/googleappengine/pom.xml +++ b/samples/googleappengine/pom.xml @@ -63,11 +63,23 @@ + + ${project.groupId} + jclouds-gae + ${project.version} + ${project.groupId} jclouds-s3 ${project.version} + + ${project.groupId} + jclouds-s3 + ${project.version} + test + test-jar + com.google.code.guice guice-servlet @@ -120,8 +132,8 @@ com.google.appengine - tools-api - 1.2 + appengine-tools-api + 1.2.0 system ${appengine.home}/lib/appengine-tools-api.jar diff --git a/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/JCloudsServlet.java b/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/JCloudsServlet.java index 792c835328..451a757ae5 100644 --- a/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/JCloudsServlet.java +++ b/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/JCloudsServlet.java @@ -24,8 +24,10 @@ package org.jclouds.samples.googleappengine; import java.io.IOException; +import java.io.InputStream; import java.io.Writer; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; @@ -33,7 +35,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; 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 com.google.inject.Inject; @@ -47,7 +49,7 @@ import com.google.inject.Singleton; @Singleton public class JCloudsServlet extends HttpServlet { @Inject - S3Connection client; + S3Context context; @Override protected void doGet(HttpServletRequest httpServletRequest, @@ -55,13 +57,12 @@ public class JCloudsServlet extends HttpServlet { IOException { Writer writer = httpServletResponse.getWriter(); try { - List myBuckets = client.getBuckets().get(10, - TimeUnit.SECONDS); + List myBuckets = context.getConnection().getBuckets() + .get(10, TimeUnit.SECONDS); writer.write("List:\n"); for (S3Bucket bucket : myBuckets) { - writer - .write(String.format(" Name: %1s%n", bucket - .getName())); + writer.write(String.format(" %1s: %2s entries%n", bucket + .getName(), context.createMapView(bucket).size())); } } catch (Exception e) { throw new ServletException(e); diff --git a/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java b/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java index 57bf8cffb8..122329d402 100644 --- a/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java +++ b/samples/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java @@ -27,21 +27,18 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; 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.config.S3ContextModule; +import org.jclouds.gae.config.URLFetchServiceClientModule; import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule; -import org.jclouds.lifecycle.Closer; 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.Injector; -import com.google.inject.name.Names; import com.google.inject.servlet.GuiceServletContextListener; import com.google.inject.servlet.ServletModule; @@ -53,42 +50,40 @@ import com.google.inject.servlet.ServletModule; */ public class GuiceServletConfig extends GuiceServletContextListener { @Inject - Closer closer; - - ServletContext context; + S3Context context; + String accessKeyId; + String secretAccessKey; @Override 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); } + private Properties loadJCloudsProperties( + ServletContextEvent servletContextEvent) { + InputStream input = servletContextEvent.getServletContext() + .getResourceAsStream("/WEB-INF/jclouds.properties"); + Properties props = new Properties(); + try { + props.load(input); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + IOUtils.closeQuietly(input); + } + return props; + } + @Override protected Injector getInjector() { - return Guice.createInjector( - new AbstractModule() { - @Override - protected void configure() { - Properties props = new Properties(); - InputStream input = null; - try { - input = context - .getResourceAsStream("/WEB-INF/jclouds.properties"); - if (input != null) - props.load(input); - else - throw new RuntimeException( - "not found in classloader"); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - IOUtils.closeQuietly(input); - } - props.putAll(S3ContextFactory.DEFAULT_PROPERTIES); - Names.bindProperties(binder(), props); - } - }, new JavaUrlHttpFutureCommandClientModule(), - new S3ContextModule(), new ServletModule() { + return S3ContextFactory.createInjector(accessKeyId, secretAccessKey, + false, new URLFetchServiceClientModule(), + new ServletModule() { @Override protected void configureServlets() { serve("*.s3").with(JCloudsServlet.class); @@ -99,11 +94,7 @@ public class GuiceServletConfig extends GuiceServletContextListener { @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { - try { - closer.close(); - } catch (Exception e) { - e.printStackTrace(); - } + context.close(); super.contextDestroyed(servletContextEvent); } } \ No newline at end of file