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.ec2.compute.config; |
20 | |
21 | import static com.google.common.collect.Iterables.toArray; |
22 | import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; |
23 | import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; |
24 | |
25 | import java.util.Set; |
26 | import java.util.concurrent.ExecutionException; |
27 | import java.util.concurrent.atomic.AtomicReference; |
28 | |
29 | import javax.inject.Named; |
30 | import javax.inject.Singleton; |
31 | |
32 | import org.jclouds.compute.ComputeServiceContext; |
33 | import org.jclouds.compute.config.BaseComputeServiceContextModule; |
34 | import org.jclouds.compute.domain.Image; |
35 | import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier; |
36 | import org.jclouds.ec2.compute.EC2ComputeService; |
37 | import org.jclouds.ec2.compute.domain.RegionAndName; |
38 | import org.jclouds.ec2.compute.loaders.RegionAndIdToImage; |
39 | import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; |
40 | import org.jclouds.rest.AuthorizationException; |
41 | import org.jclouds.rest.suppliers.SetAndThrowAuthorizationExceptionSupplier; |
42 | |
43 | import com.google.common.base.Splitter; |
44 | import com.google.common.base.Supplier; |
45 | import com.google.common.base.Suppliers; |
46 | import com.google.common.base.Throwables; |
47 | import com.google.common.cache.CacheLoader; |
48 | import com.google.common.cache.LoadingCache; |
49 | import com.google.common.collect.ImmutableSet; |
50 | import com.google.inject.Injector; |
51 | import com.google.inject.Key; |
52 | import com.google.inject.Provides; |
53 | import com.google.inject.TypeLiteral; |
54 | import com.google.inject.name.Names; |
55 | |
56 | /** |
57 | * Configures the {@link ComputeServiceContext}; requires {@link EC2ComputeService} bound. |
58 | * |
59 | * @author Adrian Cole |
60 | */ |
61 | public class EC2ComputeServiceContextModule extends BaseComputeServiceContextModule { |
62 | @Override |
63 | protected void configure() { |
64 | installDependencies(); |
65 | install(new EC2BindComputeStrategiesByClass()); |
66 | install(new EC2BindComputeSuppliersByClass()); |
67 | super.configure(); |
68 | } |
69 | |
70 | protected void installDependencies(){ |
71 | install(new EC2ComputeServiceDependenciesModule()); |
72 | } |
73 | |
74 | @Override |
75 | protected boolean shouldEagerlyParseImages(Injector injector) { |
76 | // If no owners to query, then will never lookup all images |
77 | String[] amiOwners = injector.getInstance(Key.get(String[].class, Names.named(PROPERTY_EC2_AMI_OWNERS))); |
78 | return (amiOwners.length > 0); |
79 | } |
80 | |
81 | @Override |
82 | protected Supplier<Set<? extends Image>> supplyNonParsingImageCache( |
83 | AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, |
84 | final Supplier<Set<? extends Image>> imageSupplier, Injector injector) { |
85 | final Supplier<LoadingCache<RegionAndName, ? extends Image>> cache = injector.getInstance(Key.get(new TypeLiteral<Supplier<LoadingCache<RegionAndName, ? extends Image>>>() {})); |
86 | return new Supplier<Set<? extends Image>>() { |
87 | @Override |
88 | public Set<? extends Image> get() { |
89 | return ImmutableSet.copyOf(cache.get().asMap().values()); |
90 | } |
91 | }; |
92 | } |
93 | |
94 | @Provides |
95 | @Singleton |
96 | protected Supplier<LoadingCache<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache( |
97 | final RegionAndNameToImageSupplier supplier) { |
98 | return supplier; |
99 | } |
100 | |
101 | @Provides |
102 | @Singleton |
103 | protected Supplier<CacheLoader<RegionAndName, Image>> provideRegionAndNameToImageSupplierCacheLoader( |
104 | final RegionAndIdToImage delegate) { |
105 | return Suppliers.<CacheLoader<RegionAndName, Image>>ofInstance(new CacheLoader<RegionAndName, Image>() { |
106 | private final AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>(); |
107 | |
108 | @Override |
109 | public Image load(final RegionAndName key) throws Exception { |
110 | // raw lookup of an image |
111 | Supplier<Image> rawSupplier = new Supplier<Image>() { |
112 | @Override public Image get() { |
113 | try { |
114 | return delegate.load(key); |
115 | } catch (ExecutionException e) { |
116 | throw Throwables.propagate(e); |
117 | } |
118 | } |
119 | }; |
120 | |
121 | // wrap in retry logic |
122 | Supplier<Image> retryingSupplier = new RetryOnTimeOutExceptionSupplier<Image>( |
123 | new SetAndThrowAuthorizationExceptionSupplier<Image>(rawSupplier, authException)); |
124 | |
125 | return retryingSupplier.get(); |
126 | } |
127 | |
128 | }); |
129 | } |
130 | |
131 | @Provides |
132 | @Singleton |
133 | @Named(PROPERTY_EC2_AMI_OWNERS) |
134 | String[] amiOwners(@Named(PROPERTY_EC2_AMI_OWNERS) String amiOwners) { |
135 | if (amiOwners.trim().equals("")) |
136 | return new String[] {}; |
137 | return toArray(Splitter.on(',').split(amiOwners), String.class); |
138 | } |
139 | |
140 | } |
141 | |