Browse Subversion RepositoryView of /gaejtools/src/main/java/appengine/util/MakeSyncCallServletDelegate.java
Revision 85 -
(download)
(as text)
(annotate)
Mon Dec 7 16:35:18 2009 UTC (2 months ago) by shin1 File size: 6790 byte(s) 1.2.8への対応を行う。 package appengine.util;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;
/**
* MakeSyncCallを行うサーブレットへ処理を委譲する{@link ApiProxy.Delegate}の実装。
* @author shin1ogawa
*/
public class MakeSyncCallServletDelegate implements ApiProxy.Delegate<Environment> {
static final Logger logger = Logger.getLogger(MakeSyncCallServletDelegate.class.getName());
@SuppressWarnings("unchecked")
final ApiProxy.Delegate<Environment> original = ApiProxy.getDelegate();
final URI uri;
final HttpClient httpClient;
/**
* リモートに接続した状態で{@code runnable}を実行する。
* @param runnable
* @param uri
*/
public static void runInDelegate(Runnable runnable, URI uri) {
MakeSyncCallServletDelegate delegate = new MakeSyncCallServletDelegate(uri);
ApiProxy.setDelegate(delegate);
try {
runnable.run();
} finally {
ApiProxy.setDelegate(delegate.getOriginal());
}
}
/**
* 認証を行い、リモートに接続した状態で{@code runnable}を実行する。
* <p>{@code applicationUrl}と{@code servletName}を連結した文字列をmakeSyncCallServletへのURLとして使用する。</p>
* @param runnable
* @param email
* @param password
* @param applicationUrl
* @param servletName
* @throws NullPointerException
* @throws IOException
* @throws HttpException
*/
public static void runInDelegateWithAuth(Runnable runnable, String email, String password,
String applicationUrl, String servletName) throws NullPointerException, HttpException,
IOException {
MakeSyncCallServletDelegate delegate =
new MakeSyncCallServletDelegate(new URI(applicationUrl + servletName, false));
delegate.auth(email, password, applicationUrl, servletName);
ApiProxy.setDelegate(delegate);
try {
runnable.run();
} finally {
ApiProxy.setDelegate(delegate.getOriginal());
}
}
/**
* the constructor.
* @param uri
* @category constructor
*/
public MakeSyncCallServletDelegate(URI uri) {
this.uri = uri;
httpClient = new HttpClient();
}
public void log(Environment environment, LogRecord logRecord) {
getOriginal().log(environment, logRecord);
}
/**
* Google Account Authentication APIで認証する。
* @param email
* @param password
* @param applicationUri
* @param servletName
* @return {@link AccountAuthenticationApiUtil#auth(HttpClient, String, String, String)}
* @throws HttpException
* @throws IOException
*/
public String auth(String email, String password, String applicationUri, String servletName)
throws HttpException, IOException {
String authToken =
AccountAuthenticationApiUtil.auth(httpClient, email, password, ApiProxy
.getCurrentEnvironment().getAppId());
AccountAuthenticationApiUtil.getFromAdminServlet(httpClient, authToken, applicationUri,
servletName);
return authToken;
}
public byte[] makeSyncCall(Environment environment, String serviceName, String methodName,
byte[] request) throws ApiProxyException {
return protocolBufferOnHttp(environment, serviceName, methodName, request);
}
public Future<byte[]> makeAsyncCall(Environment arg0, String arg1, String arg2, byte[] arg3,
ApiConfig arg4) {
throw new UnsupportedOperationException();
}
private byte[] protocolBufferOnHttp(Environment environment, String serviceName,
String methodName, final byte[] request) {
PostMethod method = new PostMethod();
try {
method.setURI(uri);
} catch (URIException e) {
throw new MakeSyncCallServletFailureException(e);
}
method.addRequestHeader("serviceName", serviceName);
method.addRequestHeader("methodName", methodName);
method.addRequestHeader("applicationId", environment.getAppId());
method.setRequestEntity(new RequestEntity() {
public void writeRequest(OutputStream outputstream) throws IOException {
outputstream.write(request);
}
public boolean isRepeatable() {
return false;
}
public String getContentType() {
return "application/octet-stream";
}
public long getContentLength() {
return request.length;
}
});
try {
httpClient.executeMethod(method);
int statusCode = method.getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
if (StringUtils.isNotEmpty(method.getStatusText())) {
logger.log(Level.WARNING, statusCode + ": " + method.getStatusText());
throw new MakeSyncCallServletFailureException(statusCode + ": "
+ method.getStatusText());
} else {
logger.log(Level.WARNING, statusCode + ": "
+ new String(IOUtils.toByteArray(method.getResponseBodyAsStream())));
throw new MakeSyncCallServletFailureException(statusCode + ": "
+ new String(IOUtils.toByteArray(method.getResponseBodyAsStream())));
}
}
return IOUtils.toByteArray(method.getResponseBodyAsStream());
} catch (HttpException e) {
throw new MakeSyncCallServletFailureException(e);
} catch (IOException e) {
throw new MakeSyncCallServletFailureException(e);
} finally {
method.releaseConnection();
}
}
/**
* @return 元々ApiProxyに設定されていた{@link ApiProxy.Delegate}のインスタンス
*/
public ApiProxy.Delegate<Environment> getOriginal() {
return original;
}
/**
* {@link MakeSyncCallServletDelegate#makeSyncCall(Environment, String, String, byte[])}
* を実行中に{@link Exception}が発生した場合にそれをラップして投げ直す{@link RuntimeException}.
* @author shin1ogawa
*/
public static class MakeSyncCallServletFailureException extends RuntimeException {
private static final long serialVersionUID = -6963701246227196182L;
/**
* the constructor.
* @param message
* @category constructor
*/
public MakeSyncCallServletFailureException(String message) {
super(message);
}
/**
* the constructor.
* @param cause
* @category constructor
*/
public MakeSyncCallServletFailureException(Throwable cause) {
super(cause);
}
}
}
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||