View Javadoc

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   */
19  package org.jclouds.trmk.vcloud_0_8.config;
20  
21  import static com.google.common.base.Preconditions.checkNotNull;
22  import static com.google.common.base.Preconditions.checkState;
23  import static com.google.common.base.Throwables.propagate;
24  import static com.google.common.collect.Iterables.concat;
25  import static com.google.common.collect.Iterables.getLast;
26  import static com.google.common.collect.Iterables.transform;
27  import static com.google.common.collect.Maps.transformValues;
28  import static com.google.common.collect.Maps.uniqueIndex;
29  import static org.jclouds.Constants.PROPERTY_API_VERSION;
30  import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
31  import static org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
32  
33  import java.io.IOException;
34  import java.net.URI;
35  import java.util.Map;
36  import java.util.Map.Entry;
37  import java.util.SortedMap;
38  import java.util.concurrent.ExecutionException;
39  import java.util.concurrent.TimeUnit;
40  import java.util.concurrent.TimeoutException;
41  import java.util.concurrent.atomic.AtomicReference;
42  
43  import javax.inject.Inject;
44  import javax.inject.Named;
45  import javax.inject.Singleton;
46  
47  import org.jclouds.domain.Location;
48  import org.jclouds.http.HttpErrorHandler;
49  import org.jclouds.http.annotation.ClientError;
50  import org.jclouds.http.annotation.Redirection;
51  import org.jclouds.http.annotation.ServerError;
52  import org.jclouds.predicates.RetryablePredicate;
53  import org.jclouds.rest.AsyncClientFactory;
54  import org.jclouds.rest.AuthorizationException;
55  import org.jclouds.rest.config.RestClientModule;
56  import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
57  import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudAsyncClient;
58  import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
59  import org.jclouds.trmk.vcloud_0_8.VCloudToken;
60  import org.jclouds.trmk.vcloud_0_8.compute.functions.FindLocationForResource;
61  import org.jclouds.trmk.vcloud_0_8.domain.Catalog;
62  import org.jclouds.trmk.vcloud_0_8.domain.CatalogItem;
63  import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType;
64  import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate;
65  import org.jclouds.trmk.vcloud_0_8.domain.VCloudSession;
66  import org.jclouds.trmk.vcloud_0_8.domain.VDC;
67  import org.jclouds.trmk.vcloud_0_8.endpoints.Keys;
68  import org.jclouds.trmk.vcloud_0_8.endpoints.Org;
69  import org.jclouds.trmk.vcloud_0_8.endpoints.OrgList;
70  import org.jclouds.trmk.vcloud_0_8.functions.AllCatalogItemsInCatalog;
71  import org.jclouds.trmk.vcloud_0_8.functions.AllCatalogItemsInOrg;
72  import org.jclouds.trmk.vcloud_0_8.functions.AllCatalogsInOrg;
73  import org.jclouds.trmk.vcloud_0_8.functions.AllVDCsInOrg;
74  import org.jclouds.trmk.vcloud_0_8.functions.OrgsForLocations;
75  import org.jclouds.trmk.vcloud_0_8.functions.OrgsForNames;
76  import org.jclouds.trmk.vcloud_0_8.functions.VAppTemplatesForCatalogItems;
77  import org.jclouds.trmk.vcloud_0_8.handlers.ParseTerremarkVCloudErrorFromHttpResponse;
78  import org.jclouds.trmk.vcloud_0_8.internal.TerremarkVCloudLoginAsyncClient;
79  import org.jclouds.trmk.vcloud_0_8.internal.TerremarkVCloudVersionsAsyncClient;
80  import org.jclouds.trmk.vcloud_0_8.predicates.TaskSuccess;
81  import org.jclouds.util.Strings2;
82  
83  import com.google.common.base.Function;
84  import com.google.common.base.Predicate;
85  import com.google.common.base.Supplier;
86  import com.google.common.base.Suppliers;
87  import com.google.common.collect.ImmutableMap;
88  import com.google.common.collect.ImmutableMap.Builder;
89  import com.google.common.collect.Maps;
90  import com.google.inject.Injector;
91  import com.google.inject.Provides;
92  import com.google.inject.TypeLiteral;
93  
94  public class TerremarkVCloudRestClientModule<S extends TerremarkVCloudClient, A extends TerremarkVCloudAsyncClient>
95        extends RestClientModule<S, A> {
96  
97     public TerremarkVCloudRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
98        super(syncClientType, asyncClientType);
99     }
100 
101    public TerremarkVCloudRestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
102          Map<Class<?>, Class<?>> delegateMap) {
103       super(syncClientType, asyncClientType, delegateMap);
104    }
105 
106    @Override
107    protected void configure() {
108       super.configure();
109       bind(new TypeLiteral<Function<Iterable<? extends CatalogItem>, Iterable<? extends VAppTemplate>>>() {
110       }).to(new TypeLiteral<VAppTemplatesForCatalogItems>() {
111       });
112       // Ensures we don't retry on authorization failures
113       bind(new TypeLiteral<AtomicReference<AuthorizationException>>() {
114       }).toInstance(new AtomicReference<AuthorizationException>());
115       installDefaultVCloudEndpointsModule();
116       bind(new TypeLiteral<Function<ReferenceType, Location>>() {
117       }).to(new TypeLiteral<FindLocationForResource>() {
118       });
119       bind(new TypeLiteral<Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends Catalog>>>() {
120       }).to(new TypeLiteral<AllCatalogsInOrg>() {
121       });
122       bind(new TypeLiteral<Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends VDC>>>() {
123       }).to(new TypeLiteral<AllVDCsInOrg>() {
124       });
125       bind(new TypeLiteral<Function<Iterable<String>, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Org>>>() {
126       }).to(new TypeLiteral<OrgsForNames>() {
127       });
128       bind(
129             new TypeLiteral<Function<Iterable<? extends Location>, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Org>>>() {
130             }).to(new TypeLiteral<OrgsForLocations>() {
131       });
132       bind(new TypeLiteral<Function<Catalog, Iterable<? extends CatalogItem>>>() {
133       }).to(new TypeLiteral<AllCatalogItemsInCatalog>() {
134       });
135       bind(new TypeLiteral<Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends CatalogItem>>>() {
136       }).to(new TypeLiteral<AllCatalogItemsInOrg>() {
137       });
138    }
139 
140    @Provides
141    @Singleton
142    @org.jclouds.trmk.vcloud_0_8.endpoints.VDC
143    protected Supplier<Map<String, String>> provideVDCtoORG(
144          Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgNameToOrgSuppier) {
145       return Suppliers.compose(
146             new Function<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>, Map<String, String>>() {
147 
148                @Override
149                public Map<String, String> apply(Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org> arg0) {
150                   Builder<String, String> returnVal = ImmutableMap.<String, String> builder();
151                   for (Entry<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org> orgr : arg0.entrySet()) {
152                      for (String vdc : orgr.getValue().getVDCs().keySet()) {
153                         returnVal.put(vdc, orgr.getKey());
154                      }
155                   }
156                   return returnVal.build();
157                }
158             }, orgNameToOrgSuppier);
159 
160    }
161 
162    @Provides
163    @Singleton
164    protected Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> provideOrgMapCache(
165          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
166          OrgMapSupplier supplier) {
167       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>>(
168             authException, seconds, supplier);
169    }
170 
171    @Provides
172    @Singleton
173    @OrgList
174    URI provideOrgListURI(Supplier<VCloudSession> sessionSupplier) {
175       VCloudSession session = sessionSupplier.get();
176       return URI.create(getLast(session.getOrgs().values()).getHref().toASCIIString().replaceAll("org/.*", "org"));
177    }
178 
179    @Singleton
180    public static class OrgMapSupplier implements
181          Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> {
182       protected final Supplier<VCloudSession> sessionSupplier;
183       protected final Function<Iterable<String>, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> organizationsForNames;
184 
185       @Inject
186       protected OrgMapSupplier(Supplier<VCloudSession> sessionSupplier,
187             Function<Iterable<String>, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> organizationsForNames) {
188          this.sessionSupplier = sessionSupplier;
189          this.organizationsForNames = organizationsForNames;
190       }
191 
192       @Override
193       public Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org> get() {
194          return uniqueIndex(organizationsForNames.apply(sessionSupplier.get().getOrgs().keySet()), name);
195       }
196    }
197 
198    protected void installDefaultVCloudEndpointsModule() {
199       install(new DefaultVCloudReferencesModule());
200    }
201 
202    @Singleton
203    public static class OrgCatalogSupplier implements
204          Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>> {
205       protected final Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgSupplier;
206       protected final Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>> allCatalogsInOrg;
207 
208       @Inject
209       protected OrgCatalogSupplier(
210             Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgSupplier,
211             Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>> allCatalogsInOrg) {
212          this.orgSupplier = orgSupplier;
213          this.allCatalogsInOrg = allCatalogsInOrg;
214       }
215 
216       @Override
217       public Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>> get() {
218          return transformValues(
219                transformValues(orgSupplier.get(), allCatalogsInOrg),
220                new Function<Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>() {
221 
222                   @Override
223                   public Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog> apply(
224                         Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog> from) {
225                      return uniqueIndex(from, name);
226                   }
227 
228                });
229       }
230    }
231 
232    @VCloudToken
233    @Provides
234    String provideVCloudToken(Supplier<VCloudSession> cache) {
235       return checkNotNull(cache.get().getVCloudToken(), "No token present in session");
236    }
237 
238    @Provides
239    @org.jclouds.trmk.vcloud_0_8.endpoints.Org
240    @Singleton
241    protected Supplier<Map<String, ReferenceType>> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
242          AtomicReference<AuthorizationException> authException, OrgNameToOrgSupplier supplier) {
243       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(
244             authException, seconds, supplier);
245    }
246 
247    @Provides
248    @Singleton
249    protected Supplier<Map<URI, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> provideURIToVDC(
250          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
251          URItoVDC supplier) {
252       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<URI, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>(
253             authException, seconds, supplier);
254    }
255 
256    @Singleton
257    public static class URItoVDC implements Supplier<Map<URI, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> {
258       private final Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>> orgVDCMap;
259 
260       @Inject
261       URItoVDC(Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>> orgVDCMap) {
262          this.orgVDCMap = orgVDCMap;
263       }
264 
265       @Override
266       public Map<URI, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC> get() {
267          return uniqueIndex(
268                concat(transform(
269                      orgVDCMap.get().values(),
270                      new Function<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>() {
271 
272                         @Override
273                         public Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC> apply(
274                               Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC> from) {
275                            return from.values();
276                         }
277 
278                      })), new Function<org.jclouds.trmk.vcloud_0_8.domain.VDC, URI>() {
279 
280                   @Override
281                   public URI apply(org.jclouds.trmk.vcloud_0_8.domain.VDC from) {
282                      return from.getHref();
283                   }
284 
285                });
286       }
287 
288    }
289 
290    final static Function<ReferenceType, String> name = new Function<ReferenceType, String>() {
291 
292       @Override
293       public String apply(ReferenceType from) {
294          return from.getName();
295       }
296 
297    };
298 
299    @Provides
300    @Singleton
301    @org.jclouds.trmk.vcloud_0_8.endpoints.VCloudLogin
302    protected URI provideAuthenticationURI(TerremarkVCloudVersionsAsyncClient versionService,
303          @Named(PROPERTY_API_VERSION) String version) throws InterruptedException, ExecutionException, TimeoutException {
304       SortedMap<String, URI> versions = versionService.getSupportedVersions().get(180, TimeUnit.SECONDS);
305       checkState(versions.size() > 0, "No versions present");
306       checkState(versions.containsKey(version), "version " + version + " not present in: " + versions);
307       return versions.get(version);
308    }
309 
310    @Singleton
311    private static class OrgNameToOrgSupplier implements Supplier<Map<String, ReferenceType>> {
312       private final Supplier<VCloudSession> sessionSupplier;
313 
314       @SuppressWarnings("unused")
315       @Inject
316       OrgNameToOrgSupplier(Supplier<VCloudSession> sessionSupplier) {
317          this.sessionSupplier = sessionSupplier;
318       }
319 
320       @Override
321       public Map<String, ReferenceType> get() {
322          return sessionSupplier.get().getOrgs();
323       }
324 
325    }
326 
327    @Provides
328    @Singleton
329    protected TerremarkVCloudVersionsAsyncClient provideVCloudVersions(AsyncClientFactory factory) {
330       return factory.create(TerremarkVCloudVersionsAsyncClient.class);
331    }
332 
333    @Provides
334    @Singleton
335    protected org.jclouds.trmk.vcloud_0_8.domain.Org provideOrg(
336          Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgSupplier,
337          @org.jclouds.trmk.vcloud_0_8.endpoints.Org ReferenceType defaultOrg) {
338       return orgSupplier.get().get(defaultOrg.getName());
339    }
340 
341    @Provides
342    @Singleton
343    protected Predicate<URI> successTester(Injector injector,
344          @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
345       return new RetryablePredicate<URI>(injector.getInstance(TaskSuccess.class), completed);
346    }
347 
348    @Provides
349    @Singleton
350    protected Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>> provideOrgCatalogItemMapSupplierCache(
351          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
352          OrgCatalogSupplier supplier) {
353       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>>(
354             authException, seconds, supplier);
355    }
356 
357    @Provides
358    @Singleton
359    protected Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>> provideOrgVDCSupplierCache(
360          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
361          OrgVDCSupplier supplier) {
362       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>>(
363             authException, seconds, supplier);
364    }
365 
366    @Singleton
367    public static class OrgVDCSupplier implements
368          Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>> {
369       protected final Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgSupplier;
370       private final Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> allVDCsInOrg;
371 
372       @Inject
373       protected OrgVDCSupplier(
374             Supplier<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Org>> orgSupplier,
375             Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> allVDCsInOrg) {
376          this.orgSupplier = orgSupplier;
377          this.allVDCsInOrg = allVDCsInOrg;
378       }
379 
380       @Override
381       public Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>> get() {
382          return transformValues(
383                transformValues(orgSupplier.get(), allVDCsInOrg),
384                new Function<Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC>>() {
385 
386                   @Override
387                   public Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.VDC> apply(
388                         Iterable<? extends org.jclouds.trmk.vcloud_0_8.domain.VDC> from) {
389                      return uniqueIndex(from, name);
390                   }
391 
392                });
393       }
394    }
395 
396    @Singleton
397    public static class OrgCatalogItemSupplier implements
398          Supplier<Map<String, Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>>> {
399       protected final Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>> catalogSupplier;
400       protected final Function<org.jclouds.trmk.vcloud_0_8.domain.Catalog, Iterable<? extends CatalogItem>> allCatalogItemsInCatalog;
401 
402       @Inject
403       protected OrgCatalogItemSupplier(
404             Supplier<Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>>> catalogSupplier,
405             Function<org.jclouds.trmk.vcloud_0_8.domain.Catalog, Iterable<? extends CatalogItem>> allCatalogItemsInCatalog) {
406          this.catalogSupplier = catalogSupplier;
407          this.allCatalogItemsInCatalog = allCatalogItemsInCatalog;
408       }
409 
410       @Override
411       public Map<String, Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>> get() {
412          return transformValues(
413                catalogSupplier.get(),
414                new Function<Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog>, Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>>() {
415 
416                   @Override
417                   public Map<String, Map<String, ? extends CatalogItem>> apply(
418                         Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.Catalog> from) {
419                      return transformValues(
420                            from,
421                            new Function<org.jclouds.trmk.vcloud_0_8.domain.Catalog, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>() {
422 
423                               @Override
424                               public Map<String, ? extends CatalogItem> apply(
425                                     org.jclouds.trmk.vcloud_0_8.domain.Catalog from) {
426                                  return uniqueIndex(allCatalogItemsInCatalog.apply(from), name);
427                               }
428                            });
429 
430                   }
431                });
432       }
433    }
434 
435    @Provides
436    @Singleton
437    protected Supplier<Map<String, Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>>> provideOrgCatalogItemSupplierCache(
438          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
439          OrgCatalogItemSupplier supplier) {
440       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, Map<String, ? extends org.jclouds.trmk.vcloud_0_8.domain.CatalogItem>>>>(
441             authException, seconds, supplier);
442    }
443 
444    /**
445     * 
446     * @return a listing of all orgs that the current user has access to.
447     */
448    @Provides
449    @Org
450    Map<String, ReferenceType> listOrgs(Supplier<VCloudSession> sessionSupplier) {
451       return sessionSupplier.get().getOrgs();
452    }
453 
454    @Provides
455    @Singleton
456    protected TerremarkVCloudLoginAsyncClient provideVCloudLogin(AsyncClientFactory factory) {
457       return factory.create(TerremarkVCloudLoginAsyncClient.class);
458    }
459 
460    @Provides
461    @Singleton
462    protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
463          AtomicReference<AuthorizationException> authException, final TerremarkVCloudLoginAsyncClient login) {
464       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
465             new Supplier<VCloudSession>() {
466 
467                @Override
468                public VCloudSession get() {
469                   try {
470                      return login.login().get(10, TimeUnit.SECONDS);
471                   } catch (Exception e) {
472                      propagate(e);
473                      assert false : e;
474                      return null;
475                   }
476                }
477 
478             });
479    }
480 
481    @Singleton
482    @Provides
483    @Named("CreateInternetService")
484    String provideCreateInternetService() throws IOException {
485       return Strings2.toStringAndClose(getClass().getResourceAsStream("/CreateInternetService.xml"));
486    }
487 
488    @Singleton
489    @Provides
490    @Named("CreateNodeService")
491    String provideCreateNodeService() throws IOException {
492       return Strings2.toStringAndClose(getClass().getResourceAsStream("/CreateNodeService.xml"));
493    }
494 
495    @Override
496    protected void bindErrorHandlers() {
497       bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseTerremarkVCloudErrorFromHttpResponse.class);
498       bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseTerremarkVCloudErrorFromHttpResponse.class);
499       bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseTerremarkVCloudErrorFromHttpResponse.class);
500    }
501 
502    @Singleton
503    public static class OrgNameToKeysListSupplier implements Supplier<Map<String, ReferenceType>> {
504       protected final Supplier<VCloudSession> sessionSupplier;
505       private final TerremarkVCloudClient client;
506 
507       @Inject
508       protected OrgNameToKeysListSupplier(Supplier<VCloudSession> sessionSupplier, TerremarkVCloudClient client) {
509          this.sessionSupplier = sessionSupplier;
510          this.client = client;
511       }
512 
513       @Override
514       public Map<String, ReferenceType> get() {
515          return Maps.transformValues(sessionSupplier.get().getOrgs(), new Function<ReferenceType, ReferenceType>() {
516 
517             @Override
518             public ReferenceType apply(ReferenceType from) {
519                return client.findOrgNamed(from.getName()).getKeys();
520             }
521 
522          });
523       }
524    }
525 
526    @Provides
527    @Singleton
528    @Keys
529    protected Supplier<Map<String, ReferenceType>> provideOrgToKeysListCache(
530          @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,
531          OrgNameToKeysListSupplier supplier) {
532       return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(
533             authException, seconds, supplier);
534    }
535 
536    @Singleton
537    @Provides
538    @Named("CreateKey")
539    String provideCreateKey() throws IOException {
540       return Strings2.toStringAndClose(getClass().getResourceAsStream("/CreateKey.xml"));
541    }
542 }