mirror of https://github.com/apache/jclouds.git
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:
parent
a4a301fd7c
commit
1321043c02
|
@ -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.
|
|
@ -1,2 +0,0 @@
|
|||
Export-Package: \
|
||||
org.jclouds.gae.*;version="${project.version}";-noimport:=true
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue