EMMA Coverage Report (generated Fri Aug 26 14:14:05 EDT 2011)
[all classes][org.jclouds.aws.util]

COVERAGE SUMMARY FOR SOURCE FILE [AWSUtils.java]

nameclass, %method, %block, %line, %
AWSUtils.java50%  (1/2)18%  (2/11)21%  (86/410)27%  (16/59)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AWSUtils$GetRegionFromLocation0%   (0/1)0%   (0/2)0%   (0/16)0%   (0/3)
AWSUtils$GetRegionFromLocation (): void 0%   (0/1)0%   (0/3)0%   (0/1)
apply (Location): String 0%   (0/1)0%   (0/13)0%   (0/2)
     
class AWSUtils100% (1/1)22%  (2/9)22%  (86/394)29%  (16/56)
findRegionInArgsOrNull (GeneratedHttpRequest): String 0%   (0/1)0%   (0/24)0%   (0/7)
getRegionFromLocationOrNull (Location): String 0%   (0/1)0%   (0/11)0%   (0/1)
indexIterableToFormValuesWithPrefix (HttpRequest, String, Object): HttpRequest 0%   (0/1)0%   (0/75)0%   (0/8)
indexStringArrayToFormValuesWithPrefix (HttpRequest, String, Object): HttpReq... 0%   (0/1)0%   (0/72)0%   (0/7)
indexStringArrayToFormValuesWithStringFormat (HttpRequest, String, Object): H... 0%   (0/1)0%   (0/71)0%   (0/7)
isRegion (String): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
parseHandle (String): String [] 0%   (0/1)0%   (0/24)0%   (0/2)
parseAWSErrorFromContent (HttpRequest, HttpResponse): AWSError 100% (1/1)65%  (51/78)53%  (8/15)
AWSUtils (String, RequestSigner, ParseSax$Factory, Provider): void 100% (1/1)100% (35/35)100% (8/8)

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.aws.util;
20 
21import static com.google.common.base.Preconditions.checkArgument;
22import static com.google.common.base.Preconditions.checkNotNull;
23import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
24 
25import javax.annotation.Resource;
26import javax.inject.Inject;
27import javax.inject.Named;
28import javax.inject.Provider;
29import javax.inject.Singleton;
30 
31import org.jclouds.aws.domain.AWSError;
32import org.jclouds.aws.domain.Region;
33import org.jclouds.aws.xml.ErrorHandler;
34import org.jclouds.domain.Location;
35import org.jclouds.domain.LocationScope;
36import org.jclouds.http.HttpRequest;
37import org.jclouds.http.HttpResponse;
38import org.jclouds.http.functions.ParseSax;
39import org.jclouds.http.functions.ParseSax.Factory;
40import org.jclouds.http.utils.ModifyRequest;
41import org.jclouds.logging.Logger;
42import org.jclouds.rest.RequestSigner;
43import org.jclouds.rest.internal.GeneratedHttpRequest;
44 
45import com.google.common.base.Function;
46import com.google.common.collect.ImmutableMultimap;
47import com.google.common.collect.ImmutableMultimap.Builder;
48 
49/**
50 * Needed to sign and verify requests and responses.
51 * 
52 * @author Adrian Cole
53 */
54@Singleton
55public class AWSUtils {
56   @Singleton
57   public static class GetRegionFromLocation implements Function<Location, String> {
58      public String apply(Location location) {
59         String region = location.getScope() == LocationScope.REGION ? location.getId() : location.getParent().getId();
60         return region;
61      }
62   }
63 
64   private final RequestSigner signer;
65   private final ParseSax.Factory factory;
66   private final Provider<ErrorHandler> errorHandlerProvider;
67   private final String requestId;
68   private final String requestToken;
69   @Resource
70   protected Logger logger = Logger.NULL;
71 
72   @Inject
73   AWSUtils(@Named(PROPERTY_HEADER_TAG) String headerTag, RequestSigner signer, Factory factory,
74         Provider<ErrorHandler> errorHandlerProvider) {
75      this.signer = signer;
76      this.factory = factory;
77      this.errorHandlerProvider = errorHandlerProvider;
78      this.requestId = String.format("x-%s-request-id", headerTag);
79      this.requestToken = String.format("x-%s-id-2", headerTag);
80   }
81 
82   public AWSError parseAWSErrorFromContent(HttpRequest request, HttpResponse response) {
83      // HEAD has no content
84      if (response.getPayload() == null)
85         return null;
86      // Eucalyptus and Walrus occasionally return text/plain
87      if (response.getPayload().getContentMetadata().getContentType() != null
88            && response.getPayload().getContentMetadata().getContentType().indexOf("text/plain") != -1)
89         return null;
90      try {
91         AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).setContext(request).apply(response);
92         if (error.getRequestId() == null)
93            error.setRequestId(response.getFirstHeaderOrNull(requestId));
94         error.setRequestToken(response.getFirstHeaderOrNull(requestToken));
95         if ("SignatureDoesNotMatch".equals(error.getCode())) {
96            error.setStringSigned(signer.createStringToSign(request));
97            error.setSignature(signer.sign(error.getStringSigned()));
98         }
99         return error;
100      } catch (RuntimeException e) {
101         logger.warn(e, "error parsing error");
102         return null;
103      }
104   }
105 
106   public static <R extends HttpRequest> R indexStringArrayToFormValuesWithStringFormat(R request, String format,
107         Object input) {
108      checkArgument(checkNotNull(input, "input") instanceof String[], "this binder is only valid for String[] : "
109            + input.getClass());
110      String[] values = (String[]) input;
111      Builder<String, String> builder = ImmutableMultimap.<String, String> builder();
112      for (int i = 0; i < values.length; i++) {
113         builder.put(String.format(format, (i + 1)), checkNotNull(values[i], format.toLowerCase() + "s[" + i + "]"));
114      }
115      ImmutableMultimap<String, String> forms = builder.build();
116      return forms.size() == 0 ? request : ModifyRequest.putFormParams(request, forms);
117   }
118 
119   // TODO: make this more dynamic
120   public static boolean isRegion(String regionName) {
121      return Region.DEFAULT_REGIONS.contains(regionName);
122   }
123 
124   public static <R extends HttpRequest> R indexIterableToFormValuesWithPrefix(R request, String prefix, Object input) {
125      checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable<?>: "
126            + input.getClass());
127      Iterable<?> values = (Iterable<?>) input;
128      Builder<String, String> builder = ImmutableMultimap.<String, String> builder();
129      int i = 0;
130      for (Object o : values) {
131         builder.put(prefix + "." + (i++ + 1), checkNotNull(o.toString(), prefix.toLowerCase() + "s[" + i + "]"));
132      }
133      ImmutableMultimap<String, String> forms = builder.build();
134      return forms.size() == 0 ? request : ModifyRequest.putFormParams(request, forms);
135   }
136 
137   public static <R extends HttpRequest> R indexStringArrayToFormValuesWithPrefix(R request, String prefix, Object input) {
138      checkArgument(checkNotNull(input, "input") instanceof String[], "this binder is only valid for String[] : "
139            + input.getClass());
140      String[] values = (String[]) input;
141      Builder<String, String> builder = ImmutableMultimap.<String, String> builder();
142      for (int i = 0; i < values.length; i++) {
143         builder.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase() + "s[" + i + "]"));
144      }
145      ImmutableMultimap<String, String> forms = builder.build();
146      return forms.size() == 0 ? request : ModifyRequest.putFormParams(request, forms);
147   }
148 
149   public static String getRegionFromLocationOrNull(Location location) {
150      return location.getScope() == LocationScope.ZONE ? location.getParent().getId() : location.getId();
151   }
152 
153   // there may not be a region, and in this case we do-not encode it into the string
154   public static String[] parseHandle(String id) {
155      String[] parts = checkNotNull(id, "id").split("/");
156      return (parts.length == 1) ? new String[] { null, id } : parts;
157   }
158 
159   public static String findRegionInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
160      for (Object arg : gRequest.getArgs()) {
161         if (arg instanceof String) {
162            String regionName = (String) arg;
163            // TODO regions may not be amazon regions!
164            // take from a configured value
165            if (isRegion(regionName))
166               return regionName;
167         }
168      }
169      return null;
170   }
171}

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