1 // Copyright 2011 Google. All Rights Reserved.
2 package com
.google
.appengine
.tools
.remoteapi
;
4 import com
.google
.apphosting
.api
.ApiProxy
;
5 import com
.google
.apphosting
.api
.ApiProxy
.ApiConfig
;
6 import com
.google
.apphosting
.api
.ApiProxy
.Delegate
;
7 import com
.google
.apphosting
.api
.ApiProxy
.Environment
;
10 import java
.util
.concurrent
.ExecutionException
;
11 import java
.util
.concurrent
.Future
;
12 import java
.util
.concurrent
.TimeUnit
;
15 * {@link RemoteApiDelegate} implementation for use inside an App Engine
16 * container. We let the {@link #containerDelegate} handle calls to the url
17 * fetch service for local fulfillment since there's little to be gained from
18 * asking some other app to make the same outbound call. If a good reason for
19 * doing this pops up we can add a config option that will let people opt-in to
23 class HostedRemoteApiDelegate
extends RemoteApiDelegate
{
24 private final Delegate
<Environment
> containerDelegate
;
26 public HostedRemoteApiDelegate(RemoteRpc rpc
, RemoteApiOptions options
,
27 Delegate
<Environment
> containerDelegate
) {
29 if (containerDelegate
== null) {
30 throw new IllegalArgumentException("Options indicate we are running in an App Engine "
31 + "container but App Engine services are not available.");
33 this.containerDelegate
= containerDelegate
;
37 public byte[] makeSyncCall(Environment env
, String serviceName
, String methodName
,
39 if (serviceName
.equals("urlfetch")) {
40 return containerDelegate
.makeSyncCall(env
, serviceName
, methodName
, request
);
42 return makeDefaultSyncCall(serviceName
, methodName
, request
);
46 public Future
<byte[]> makeAsyncCall(Environment env
, String serviceName
,
47 String methodName
, byte[] request
, ApiConfig apiConfig
) {
49 return new FakeFuture
<byte[]>(makeSyncCall(env
, serviceName
, methodName
, request
));
50 } catch (Exception e
) {
51 return new FakeFuture
<byte[]>(e
);
56 public void log(Environment environment
, ApiProxy
.LogRecord record
) {
57 containerDelegate
.log(environment
, record
);
61 public List
<Thread
> getRequestThreads(Environment environment
) {
62 return containerDelegate
.getRequestThreads(environment
);
66 public void flushLogs(Environment environment
) {
67 containerDelegate
.flushLogs(environment
);
71 public void shutdown() {
75 * Wraps an already-resolved result in a {@link Future}.
76 * @param <T> The type of the Future.
78 private static class FakeFuture
<T
> implements Future
<T
> {
79 private final T result
;
80 private final Exception exception
;
82 FakeFuture(T result
) {
86 FakeFuture(Exception e
) {
90 private FakeFuture(T result
, Exception exception
) {
92 this.exception
= exception
;
96 public boolean cancel(boolean mayInterruptIfRunning
) {
101 public boolean isCancelled() {
106 public boolean isDone() {
111 public T
get() throws ExecutionException
{
112 if (exception
!= null) {
113 throw new ExecutionException(exception
);
119 public T
get(long timeout
, TimeUnit unit
) throws ExecutionException
{
120 if (exception
!= null) {
121 throw new ExecutionException(exception
);