EMMA Coverage Report (generated Mon Oct 17 05:41:20 EDT 2011)
[all classes][org.jclouds.gae]

COVERAGE SUMMARY FOR SOURCE FILE [ConvertToGaeRequest.java]

nameclass, %method, %block, %line, %
ConvertToGaeRequest.java100% (1/1)100% (2/2)90%  (179/198)84%  (33.5/40)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ConvertToGaeRequest100% (1/1)100% (2/2)90%  (179/198)84%  (33.5/40)
apply (HttpRequest): HTTPRequest 100% (1/1)90%  (165/184)82%  (29.5/36)
ConvertToGaeRequest (HttpUtils): void 100% (1/1)100% (14/14)100% (4/4)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.jclouds.gae;
20 
21import static com.google.appengine.api.urlfetch.FetchOptions.Builder.disallowTruncate;
22 
23import java.io.ByteArrayOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.net.MalformedURLException;
27import java.net.URL;
28import java.util.Map.Entry;
29import java.util.Set;
30 
31import javax.inject.Inject;
32import javax.inject.Singleton;
33import javax.ws.rs.core.HttpHeaders;
34 
35import org.jclouds.http.HttpRequest;
36import org.jclouds.http.HttpUtils;
37import org.jclouds.io.Payload;
38 
39import com.google.appengine.api.urlfetch.FetchOptions;
40import com.google.appengine.api.urlfetch.HTTPHeader;
41import com.google.appengine.api.urlfetch.HTTPMethod;
42import com.google.appengine.api.urlfetch.HTTPRequest;
43import com.google.appengine.repackaged.com.google.common.base.Throwables;
44import com.google.common.base.Function;
45import com.google.common.collect.ImmutableSet;
46import com.google.common.io.Closeables;
47 
48/**
49 * 
50 * @author Adrian Cole
51 */
52@Singleton
53public class ConvertToGaeRequest implements Function<HttpRequest, HTTPRequest> {
54   public static final String USER_AGENT = "jclouds/1.0 urlfetch/1.4.3";
55   protected final HttpUtils utils;
56   // http://code.google.com/appengine/docs/java/urlfetch/overview.html
57   public final Set<String> prohibitedHeaders = ImmutableSet.of("Accept-Encoding", "Content-Length", "Host", "Var",
58         "X-Forwarded-For");
59 
60   @Inject
61   ConvertToGaeRequest(HttpUtils utils) {
62      this.utils = utils;
63   }
64 
65   /**
66    * byte [] content is replayable and the only content type supportable by GAE. As such, we
67    * convert the original request content to a byte array.
68    */
69   @Override
70   public HTTPRequest apply(HttpRequest request) {
71      URL url = null;
72      try {
73         url = request.getEndpoint().toURL();
74      } catch (MalformedURLException e) {
75         Throwables.propagate(e);
76      }
77 
78      FetchOptions options = disallowTruncate();
79      options.doNotFollowRedirects();
80      if (utils.relaxHostname() || utils.trustAllCerts())
81         options.doNotFollowRedirects();
82      options.setDeadline(10.0);
83 
84      HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod.valueOf(request.getMethod().toString()), options);
85 
86      for (String header : request.getHeaders().keySet()) {
87         for (String value : request.getHeaders().get(header)) {
88            if (!prohibitedHeaders.contains(header))
89               gaeRequest.addHeader(new HTTPHeader(header, value));
90         }
91      }
92      gaeRequest.addHeader(new HTTPHeader(HttpHeaders.USER_AGENT, USER_AGENT));
93      /**
94       * byte [] content is replayable and the only content type supportable by GAE. As such, we
95       * convert the original request content to a byte array.
96       */
97      if (request.getPayload() != null) {
98         InputStream input = request.getPayload().getInput();
99         try {
100            ByteArrayOutputStream out = new ByteArrayOutputStream();
101            request.getPayload().writeTo(out);
102            byte[] array = out.toByteArray();
103            if (!request.getPayload().isRepeatable()) {
104               Payload oldPayload = request.getPayload();
105               request.setPayload(array);
106               HttpUtils.copy(oldPayload.getContentMetadata(), request.getPayload().getContentMetadata());
107            }
108            gaeRequest.setPayload(array);
109            if (array.length > 0) {
110               gaeRequest.setHeader(new HTTPHeader("Expect", "100-continue"));
111            }
112         } catch (IOException e) {
113            Throwables.propagate(e);
114         } finally {
115            Closeables.closeQuietly(input);
116         }
117 
118         for (Entry<String, String> header : HttpUtils.getContentHeadersFromMetadata(
119               request.getPayload().getContentMetadata()).entries()) {
120            if (!prohibitedHeaders.contains(header.getKey()))
121               gaeRequest.setHeader(new HTTPHeader(header.getKey(), header.getValue()));
122         }
123      }
124      return gaeRequest;
125   }
126}

[all classes][org.jclouds.gae]
EMMA 2.0.5312 (C) Vladimir Roubtsov