Remove Google appengine driver

This has an incompatibility with JAXB motivating this removal.
jclouds GAE has not seen any development or issues in recent years and
uses a very old appengine-api-1.0-sdk dependency.  Further it appears
to have modern Guava incompatibilities as seen in JCLOUDS-836.
This commit is contained in:
Andrew Gaul 2021-07-15 10:21:19 +09:00 committed by Andrew Gaul
parent a4a301fd7c
commit 1321043c02
14 changed files with 0 additions and 962 deletions

View File

@ -1,6 +0,0 @@
#
# A driver to run jclouds on Google App Engine (http://code.google.com/appengine/).
#
# Expects the joda-time JAR (see drivers/joda) to be present on your application's classpath.
#
# TODO: Usage example.

View File

@ -1,2 +0,0 @@
Export-Package: \
org.jclouds.gae.*;version="${project.version}";-noimport:=true

View File

@ -1,89 +0,0 @@
<?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>
<parent>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>2.4.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-gae</artifactId>
<name>jclouds Google App Engine Components</name>
<description>Google App Engine Components</description>
<dependencies>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-tls</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!--
gae runs two tests, this should prevent them from executing on the
same tcp port
-->
<threadCount>1</threadCount>
<parallel>classes</parallel>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,121 +0,0 @@
/*
* 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.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.io.ContentMetadataCodec;
import org.jclouds.io.Payload;
import org.jclouds.util.Closeables2;
import com.google.appengine.api.urlfetch.FetchOptions;
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.repackaged.com.google.common.base.Throwables;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
@Singleton
public class ConvertToGaeRequest implements Function<HttpRequest, HTTPRequest> {
public static final String USER_AGENT = "jclouds/1.0 urlfetch/1.4.3";
// http://code.google.com/appengine/docs/java/urlfetch/overview.html
public final Set<String> prohibitedHeaders = ImmutableSet.of("Accept-Encoding", "Content-Length", "Host", "Var",
"X-Forwarded-For");
protected final HttpUtils utils;
protected final ContentMetadataCodec contentMetadataCodec;
@Inject
ConvertToGaeRequest(HttpUtils utils, ContentMetadataCodec contentMetadataCodec) {
this.utils = utils;
this.contentMetadataCodec = contentMetadataCodec;
}
/**
* byte [] content is replayable and the only content type supportable by GAE. As such, we
* convert the original request content to a byte array.
*/
@Override
public HTTPRequest apply(HttpRequest request) {
URL url = null;
try {
url = request.getEndpoint().toURL();
} catch (MalformedURLException e) {
Throwables.propagate(e);
}
FetchOptions options = disallowTruncate();
options.doNotFollowRedirects();
if (utils.relaxHostname() || utils.trustAllCerts())
options.doNotFollowRedirects();
options.setDeadline(10.0);
HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod.valueOf(request.getMethod().toString()), options);
for (Entry<String, String> entry : request.getHeaders().entries()) {
String header = entry.getKey();
if (!prohibitedHeaders.contains(header))
gaeRequest.addHeader(new HTTPHeader(header, entry.getValue()));
}
gaeRequest.addHeader(new HTTPHeader(HttpHeaders.USER_AGENT, USER_AGENT));
/**
* byte [] content is replayable and the only content type supportable by GAE. As such, we
* convert the original request content to a byte array.
*/
if (request.getPayload() != null) {
InputStream input = request.getPayload().getInput();
try {
byte[] array = ByteStreams.toByteArray(input);
if (!request.getPayload().isRepeatable()) {
Payload oldPayload = request.getPayload();
request.setPayload(array);
HttpUtils.copy(oldPayload.getContentMetadata(), request.getPayload().getContentMetadata());
}
gaeRequest.setPayload(array);
if (array.length > 0) {
gaeRequest.setHeader(new HTTPHeader("Expect", "100-continue"));
}
} catch (IOException e) {
Throwables.propagate(e);
} finally {
Closeables2.closeQuietly(input);
}
for (Entry<String, String> header : contentMetadataCodec.toHeaders(
request.getPayload().getContentMetadata()).entries()) {
if (!prohibitedHeaders.contains(header.getKey()))
gaeRequest.setHeader(new HTTPHeader(header.getKey(), header.getValue()));
}
}
return gaeRequest;
}
}

View File

@ -1,66 +0,0 @@
/*
* 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.jclouds.http.HttpUtils.filterOutContentHeaders;
import javax.inject.Singleton;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.ContentMetadataCodec;
import org.jclouds.io.Payload;
import org.jclouds.io.Payloads;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.common.base.Function;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
@Singleton
public class ConvertToJcloudsResponse implements Function<HTTPResponse, HttpResponse> {
private final ContentMetadataCodec contentMetadataCodec;
@Inject
public ConvertToJcloudsResponse(ContentMetadataCodec contentMetadataCodec) {
this.contentMetadataCodec = contentMetadataCodec;
}
@Override
public HttpResponse apply(HTTPResponse gaeResponse) {
Payload payload = gaeResponse.getContent() != null ? Payloads.newByteArrayPayload(gaeResponse.getContent())
: null;
Multimap<String, String> headers = LinkedHashMultimap.create();
String message = null;
for (HTTPHeader header : gaeResponse.getHeaders()) {
if (header.getName() == null)
message = header.getValue();
else
headers.put(header.getName(), header.getValue());
}
if (payload != null) {
contentMetadataCodec.fromHeaders(payload.getContentMetadata(), headers);
}
return HttpResponse.builder()
.statusCode(gaeResponse.getResponseCode())
.message(message)
.payload(payload)
.headers(filterOutContentHeaders(headers)).build();
}
}

View File

@ -1,91 +0,0 @@
/*
* 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.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.JcloudsVersion;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.IOExceptionRetryHandler;
import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.internal.BaseHttpCommandExecutorService;
import org.jclouds.http.internal.HttpWire;
import org.jclouds.io.ContentMetadataCodec;
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;
/**
* Google App Engine version of {@link HttpCommandExecutorService}
*/
@SingleThreaded
@Singleton
public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorService<HTTPRequest> {
//TODO: look up gae version
public static final String USER_AGENT = String.format("jclouds/%s urlfetch/%s", JcloudsVersion.get(), "1.6.5");
private final URLFetchService urlFetchService;
private final ConvertToGaeRequest convertToGaeRequest;
private final ConvertToJcloudsResponse convertToJcloudsResponse;
@Inject
public GaeHttpCommandExecutorService(URLFetchService urlFetchService, HttpUtils utils,
ContentMetadataCodec contentMetadataCodec,
IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, ConvertToGaeRequest convertToGaeRequest,
ConvertToJcloudsResponse convertToJcloudsResponse,
@Named(PROPERTY_IDEMPOTENT_METHODS) String idempotentMethods) {
super(utils, contentMetadataCodec, retryHandler, ioRetryHandler, errorHandler, wire, idempotentMethods);
this.urlFetchService = urlFetchService;
this.convertToGaeRequest = convertToGaeRequest;
this.convertToJcloudsResponse = convertToJcloudsResponse;
}
@VisibleForTesting
protected HttpResponse convert(HTTPResponse gaeResponse) {
return convertToJcloudsResponse.apply(gaeResponse);
}
@VisibleForTesting
protected HTTPRequest convert(HttpRequest request) throws IOException {
return convertToGaeRequest.apply(request);
}
/**
* nothing to clean up.
*/
@Override
protected void cleanup(HTTPRequest nativeRequest) {
}
@Override
protected HttpResponse invoke(HTTPRequest request) throws IOException {
return convert(urlFetchService.fetch(request));
}
}

View File

@ -1,105 +0,0 @@
/*
* 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 static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.concurrent.DynamicExecutors.newScalingThreadPool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.WithSubmissionTrace;
import com.google.appengine.api.ThreadManager;
import com.google.apphosting.api.ApiProxy;
import com.google.common.annotations.Beta;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@Beta
@ConfiguresExecutorService
public class CurrentRequestExecutorServiceModule extends AbstractModule {
private final Supplier<ListeningExecutorService> memoizedCurrentRequestExecutorService;
public CurrentRequestExecutorServiceModule() {
this(memoizedCurrentRequestExecutorService());
}
/**
* Used when you are creating multiple contexts in the same app.
*
* @param memoizedCurrentRequestExecutorService
* @see #memoizedCurrentRequestExecutorService
*/
public CurrentRequestExecutorServiceModule(Supplier<ListeningExecutorService> memoizedCurrentRequestExecutorService) {
this.memoizedCurrentRequestExecutorService = memoizedCurrentRequestExecutorService;
}
/**
* Used when you are creating multiple contexts in the same app.
*
* @param currentRequestExecutorService
* @see #currentRequestExecutorService
*/
public CurrentRequestExecutorServiceModule(ListeningExecutorService currentRequestExecutorService) {
this.memoizedCurrentRequestExecutorService = Suppliers.ofInstance(currentRequestExecutorService);
}
@Override
protected void configure() {
}
public static Supplier<ListeningExecutorService> memoizedCurrentRequestExecutorService() {
return Suppliers.memoize(new Supplier<ListeningExecutorService>() {
// important that these are lazy bound vs in configure, as GAE may not
// quite be initialized, yet!
@Override
public ListeningExecutorService get() {
return currentRequestExecutorService();
}
});
}
public static ListeningExecutorService currentRequestExecutorService() {
ThreadFactory factory = checkNotNull(ThreadManager.currentRequestThreadFactory(),
"ThreadManager.currentRequestThreadFactory()");
// GAE requests cannot exceed 10 threads per request
int maxThreads = 10;
long keepAlive = ApiProxy.getCurrentEnvironment().getRemainingMillis();
ExecutorService pool = newScalingThreadPool(0, maxThreads, keepAlive, factory);
return WithSubmissionTrace.wrap(MoreExecutors.listeningDecorator(pool));
}
@Provides
@Singleton
@Named(Constants.PROPERTY_USER_THREADS)
protected final ListeningExecutorService userExecutor() {
return memoizedCurrentRequestExecutorService.get();
}
}

View File

@ -1,86 +0,0 @@
/*
* 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 static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.gae.GaeHttpCommandExecutorService;
import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.predicates.SocketOpenUnsupported;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.common.base.Supplier;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.Scopes;
/**
* Configures {@link GaeHttpCommandExecutorService}.
*/
@ConfiguresHttpCommandExecutorService
@ConfiguresExecutorService
@SingleThreaded
public class GoogleAppEngineConfigurationModule extends AbstractModule {
private final Module userExecutorModule;
public GoogleAppEngineConfigurationModule() {
this(new ExecutorServiceModule(newDirectExecutorService()));
}
/**
* Used when you are creating multiple contexts in the same app.
*
* @see CurrentRequestExecutorServiceModule#currentRequestExecutorService
*/
public GoogleAppEngineConfigurationModule(Module userExecutorModule) {
this.userExecutorModule = userExecutorModule;
}
/**
* Used when you are creating multiple contexts in the same app.
*
* @param memoizedCurrentRequestExecutorService
* @see CurrentRequestExecutorServiceModule#memoizedCurrentRequestExecutorService
*/
public GoogleAppEngineConfigurationModule(Supplier<ListeningExecutorService> memoizedCurrentRequestExecutorService) {
this.userExecutorModule = new CurrentRequestExecutorServiceModule(memoizedCurrentRequestExecutorService);
}
@Override
protected void configure() {
install(userExecutorModule);
bind(SocketOpen.class).to(SocketOpenUnsupported.class).in(Scopes.SINGLETON);
bindHttpCommandExecutorService();
}
protected void bindHttpCommandExecutorService() {
bind(HttpCommandExecutorService.class).to(GaeHttpCommandExecutorService.class);
}
@Provides
protected final URLFetchService provideURLFetchService() {
return URLFetchServiceFactory.getURLFetchService();
}
}

View File

@ -1,175 +0,0 @@
/*
* 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.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Date;
import javax.ws.rs.HttpMethod;
import org.jclouds.crypto.Crypto;
import org.jclouds.date.internal.DateServiceDateCodecFactory;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.encryption.internal.JCECrypto;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
import org.jclouds.io.Payloads;
import org.jclouds.util.Strings2;
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.repackaged.com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.common.io.Files;
import com.google.common.net.HttpHeaders;
@Test
public class ConvertToGaeRequestTest {
ConvertToGaeRequest req;
URI endPoint;
protected static volatile Crypto crypto;
static {
try {
crypto = new JCECrypto();
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
}
}
@BeforeTest
void setupClient() {
endPoint = URI.create("http://localhost:80/foo");
req = new ConvertToGaeRequest(new HttpUtils(0, 0, 0, 0), new DefaultContentMetadataCodec(
new DateServiceDateCodecFactory(new SimpleDateFormatDateService())));
}
@Test
void testConvertRequestGetsTargetAndUri() throws IOException {
HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(endPoint).build();
HTTPRequest gaeRequest = req.apply(request);
assertEquals(gaeRequest.getURL().getPath(), "/foo");
}
@Test
void testConvertRequestSetsFetchOptions() throws IOException {
HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(endPoint).build();
HTTPRequest gaeRequest = req.apply(request);
assert gaeRequest.getFetchOptions() != null;
}
@Test
void testConvertRequestSetsHeaders() throws IOException {
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.addHeader("foo", "bar").build();
HTTPRequest gaeRequest = req.apply(request);
assertEquals(gaeRequest.getHeaders().get(0).getName(), "foo");
assertEquals(gaeRequest.getHeaders().get(0).getValue(), "bar");
}
@Test
void testConvertRequestNoContent() throws IOException {
HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(endPoint).build();
HTTPRequest gaeRequest = req.apply(request);
assert gaeRequest.getPayload() == null;
assertEquals(gaeRequest.getHeaders().size(), 1); // user agent
assertEquals(gaeRequest.getHeaders().get(0).getName(), HttpHeaders.USER_AGENT);
assertEquals(gaeRequest.getHeaders().get(0).getValue(), "jclouds/1.0 urlfetch/1.4.3");
}
@Test
void testConvertRequestStringContent() throws IOException {
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.payload("hoot!").build();
testHoot(request);
}
@Test
void testConvertRequestInputStreamContent() throws IOException {
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.payload(Strings2.toInputStream("hoot!")).build();
request.getPayload().getContentMetadata().setContentLength(5L);
testHoot(request);
}
@Test
void testConvertRequestBytesContent() throws IOException {
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.payload("hoot!".getBytes()).build();
testHoot(request);
}
@Test(expectedExceptions = UnsupportedOperationException.class)
void testConvertRequestBadContent() throws IOException {
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.payload(Payloads.newPayload(new Date())).build();
req.apply(request);
}
@Test
@Parameters("basedir")
void testConvertRequestFileContent(String basedir) throws IOException {
File file = new File(basedir, "target/testfiles/hoot");
file.getParentFile().mkdirs();
Files.write("hoot!".getBytes(Charsets.UTF_8), file);
HttpRequest request = HttpRequest.builder()
.method(HttpMethod.GET)
.endpoint(endPoint)
.payload(file).build();
testHoot(request);
}
private void testHoot(HttpRequest request) throws IOException {
request.getPayload().getContentMetadata().setContentType("text/plain");
request.getPayload().getContentMetadata().setContentMD5(new byte[16]);
HTTPRequest gaeRequest = req.apply(request);
StringBuilder builder = new StringBuilder();
for (HTTPHeader header : gaeRequest.getHeaders()) {
builder.append(header.getName()).append(": ").append(header.getValue()).append("\n");
}
assertEquals(builder.toString(),
// note content-length is prohibited in gae
"User-Agent: jclouds/1.0 urlfetch/1.4.3\n" +
"Expect: 100-continue\n" +
"Content-Type: text/plain\n" +
"Content-MD5: AAAAAAAAAAAAAAAAAAAAAA==\n");
assertEquals(new String(gaeRequest.getPayload()), "hoot!");
}
}

View File

@ -1,105 +0,0 @@
/*
* 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.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.List;
import org.jclouds.crypto.Crypto;
import org.jclouds.date.internal.DateServiceDateCodecFactory;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.encryption.internal.JCECrypto;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
import org.jclouds.util.Strings2;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.net.HttpHeaders;
@Test
public class ConvertToJcloudsResponseTest {
ConvertToJcloudsResponse req;
URI endPoint;
protected static volatile Crypto crypto;
static {
try {
crypto = new JCECrypto();
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
}
}
@BeforeTest
void setupClient() {
endPoint = URI.create("http://localhost:80/foo");
req = new ConvertToJcloudsResponse(new DefaultContentMetadataCodec(new DateServiceDateCodecFactory(
new SimpleDateFormatDateService())));
}
@Test
void testConvertHostHeaderToEndPoint() {
// TODO
}
@Test
void testConvertWithHeaders() throws IOException {
HTTPResponse gaeResponse = createMock(HTTPResponse.class);
expect(gaeResponse.getResponseCode()).andReturn(200);
List<HTTPHeader> headers = Lists.newArrayList();
headers.add(new HTTPHeader(HttpHeaders.CONTENT_TYPE, "text/xml"));
expect(gaeResponse.getHeaders()).andReturn(headers);
expect(gaeResponse.getContent()).andReturn(null).atLeastOnce();
replay(gaeResponse);
HttpResponse response = req.apply(gaeResponse);
assertEquals(response.getStatusCode(), 200);
assertEquals(response.getPayload(), null);
assertEquals(response.getHeaders().size(), 0);
}
@Test
void testConvertWithContent() throws IOException {
HTTPResponse gaeResponse = createMock(HTTPResponse.class);
expect(gaeResponse.getResponseCode()).andReturn(200);
List<HTTPHeader> headers = Lists.newArrayList();
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 = req.apply(gaeResponse);
assertEquals(response.getStatusCode(), 200);
assertEquals(Strings2.toStringAndClose(response.getPayload().openStream()), "hello");
assertEquals(response.getHeaders().size(), 0);
assertEquals(response.getPayload().getContentMetadata().getContentType(), "text/xml");
}
}

View File

@ -1,73 +0,0 @@
/*
* 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 java.io.IOException;
import java.util.Properties;
import org.jclouds.gae.config.GoogleAppEngineConfigurationModule;
import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest;
import org.testng.SkipException;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalURLFetchServiceTestConfig;
import com.google.inject.Module;
/**
*
* Integration test for the URLFetchService
*/
@Test
public class GaeHttpCommandExecutorServiceIntegrationTest extends BaseHttpCommandExecutorServiceIntegrationTest {
@BeforeMethod
public void setupApiProxy() {
LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalURLFetchServiceTestConfig());
helper.setUp();
}
@Override
public void testPostAsInputStream() {
throw new SkipException("streams aren't supported");
}
@Override
public void testPostAsInputStreamDoesNotRetryOnFailure() throws Exception {
throw new SkipException("streams aren't supported");
}
@Override
public void testGetBigFile() {
throw new SkipException("test data is too big for GAE");
}
@Override
public void testUploadBigFile() throws IOException {
throw new SkipException("test data is too big for GAE");
}
protected Module createConnectionModule() {
setupApiProxy();
return new GoogleAppEngineConfigurationModule();
}
@Override
protected void addOverrideProperties(Properties props) {
}
}

View File

@ -1,42 +0,0 @@
/*
* 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.jclouds.providers.AnonymousProviderMetadata.forApiOnEndpoint;
import org.jclouds.Context;
import org.jclouds.ContextBuilder;
import org.jclouds.gae.config.GoogleAppEngineConfigurationModule;
import org.jclouds.http.IntegrationTestClient;
import org.jclouds.predicates.SocketOpen;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HostAndPort;
public class GaeSocketOpenTest {
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testSocketOpenThrowsUnsupported() {
Context context = ContextBuilder.newBuilder(forApiOnEndpoint(IntegrationTestClient.class, "dummyurl"))
.modules(ImmutableSet.of(new GoogleAppEngineConfigurationModule()))
.build();
SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class);
socketOpen.apply(HostAndPort.fromParts("localhost", 22));
}
}

View File

@ -32,7 +32,6 @@
<module>apachehc</module>
<module>bouncycastle</module>
<module>enterprise</module>
<module>gae</module>
<module>joda</module>
<module>jsch</module>
<module>log4j</module>