Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / conversion / ConversionServiceImpl.java
blob5f134c8716ea09ef73f3d99ec900860f37c51dcc
1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com.google.appengine.api.conversion;
5 import com.google.appengine.api.conversion.ConversionServicePb.ConversionOutput;
6 import com.google.appengine.api.conversion.ConversionServicePb.ConversionRequest;
7 import com.google.appengine.api.conversion.ConversionServicePb.ConversionResponse;
8 import com.google.appengine.api.utils.FutureWrapper;
9 import com.google.apphosting.api.ApiProxy;
10 import com.google.common.base.Throwables;
11 import com.google.common.collect.Lists;
13 import java.io.IOException;
14 import java.util.Arrays;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18 import java.util.logging.Logger;
20 /**
21 * A {@code ConversionService} which performs conversions by making RPCs to
22 * the backend service.
25 class ConversionServiceImpl implements ConversionService {
26 static final String CONVERSION_SERVICE = "conversion";
28 static final String CONVERT_METHOD = "Convert";
30 Logger logger = Logger.getLogger(getClass().getName());
32 private final ConversionRequestProtoConverter conversionRequestProtoConverter =
33 new ConversionRequestProtoConverter();
34 private final ConversionResultProtoConverter conversionResultProtoConverter =
35 new ConversionResultProtoConverter();
37 /**
38 * The number of seconds allowing conversion request to run,
39 * or null for the default deadline.
40 */ private final Double deadline;
42 /**
43 * Constructs a {@link ConversionServiceImpl} with default deadline.
45 ConversionServiceImpl() {
46 this.deadline = null;
49 /**
50 * Constructs a {@link ConversionServiceImpl} with specified deadline.
52 ConversionServiceImpl(double deadline) {
53 this.deadline = deadline;
56 @Override
57 public ConversionResult convert(Conversion conversion) {
58 List<ConversionResult> results = convert(Arrays.asList(conversion));
59 return results.get(0);
62 @Override
63 public List<ConversionResult> convert(List<Conversion> conversions) {
64 try {
65 return convertAsync(conversions).get();
66 } catch (ExecutionException e) {
67 Throwables.propagateIfInstanceOf(e.getCause(), ConversionServiceException.class);
68 throw new ConversionServiceException(ConversionErrorCode.INTERNAL_ERROR, e);
69 } catch (InterruptedException e) {
70 throw new ConversionServiceException(ConversionErrorCode.INTERNAL_ERROR, e);
74 @Override
75 public Future<ConversionResult> convertAsync(Conversion conversion) {
76 logger.warning("The Conversion API will be decommissioned in November 2012 "
77 + "and all calls to it will return an error.");
78 final ConversionRequest request =
79 conversionRequestProtoConverter.convert(Arrays.asList(conversion));
81 Future<byte[]> responseBytes = ApiProxy.makeAsyncCall(
82 CONVERSION_SERVICE, CONVERT_METHOD, request.toByteArray(), createApiConfig(deadline));
83 return new ConversionFutureWrapper<byte[], ConversionResult>(responseBytes) {
84 @Override
85 protected ConversionResult wrap(byte[] responseBytes) throws IOException {
86 ConversionResponse.Builder response = ConversionResponse.newBuilder()
87 .mergeFrom(responseBytes);
88 return conversionResultProtoConverter.reverse(response.getResultList().get(0));
93 @Override
94 public Future<List<ConversionResult>> convertAsync(List<Conversion> conversions) {
95 logger.warning("The Conversion API will be decommissioned in November 2012 "
96 + "and all calls to it will return an error.");
97 final ConversionRequest request =
98 conversionRequestProtoConverter.convert(conversions);
100 Future<byte[]> responseBytes = ApiProxy.makeAsyncCall(
101 CONVERSION_SERVICE, CONVERT_METHOD, request.toByteArray(), createApiConfig(deadline));
102 return new ConversionFutureWrapper<byte[], List<ConversionResult>>(responseBytes) {
103 @Override
104 protected List<ConversionResult> wrap(byte[] responseBytes) throws IOException {
105 ConversionResponse.Builder response = ConversionResponse.newBuilder()
106 .mergeFrom(responseBytes);
107 List<ConversionResult> results = Lists.newArrayList();
108 for (ConversionOutput result : response.getResultList()) {
109 results.add(conversionResultProtoConverter.reverse(result));
111 return results;
117 * Inner FutureWrapper subclass providing our own convertException
118 * implementation.
120 private abstract static class ConversionFutureWrapper<K, V> extends FutureWrapper<K, V> {
121 ConversionFutureWrapper(Future<K> parent) {
122 super(parent);
125 @Override
126 protected Throwable convertException(Throwable cause) {
127 if (cause instanceof ApiProxy.ApplicationException) {
128 ApiProxy.ApplicationException e = (ApiProxy.ApplicationException) cause;
129 return new ConversionServiceException(
130 ConversionErrorCode.intToEnum(e.getApplicationError()), e.getErrorDetail());
131 } else if (cause instanceof ApiProxy.ApiDeadlineExceededException) {
132 return new ConversionServiceException(ConversionErrorCode.TIMEOUT, cause.getMessage());
134 return cause;
139 * Creates and returns an ApiConfig instance with deadline setting.
141 private ApiProxy.ApiConfig createApiConfig( Double deadline) {
142 ApiProxy.ApiConfig apiConfig = new ApiProxy.ApiConfig();
143 apiConfig.setDeadlineInSeconds(deadline);
144 return apiConfig;