EMMA Coverage Report (generated Wed Aug 10 12:30:04 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 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * 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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
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