1
15 package com.amazonaws.partitions;
16
17 import com.amazonaws.annotation.SdkInternalApi;
18 import com.amazonaws.partitions.model.Endpoint;
19 import com.amazonaws.partitions.model.Partition;
20 import com.amazonaws.partitions.model.Service;
21 import com.amazonaws.regions.AbstractRegionMetadataProvider;
22 import com.amazonaws.regions.Region;
23 import com.amazonaws.util.ValidationUtils;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.concurrent.ConcurrentHashMap;
32
33
36 @SdkInternalApi
37 public class PartitionMetadataProvider extends AbstractRegionMetadataProvider {
38
39 private static final String STANDARD_PARTITION_HOSTNAME = "{service}.{region}.{dnsSuffix}";
40
41 private final Map<String, Partition> partitionMap = new HashMap<String, Partition>();
42
43 private final Map<String, Region> credentialScopeRegionByHost = new HashMap<String, Region>();
44
45 private final Set<String> standardHostnamePatternDnsSuffixes = new HashSet<String>();
46
47 private final Map<String, Region> regionCache = new ConcurrentHashMap<String, Region>();
48
49 public PartitionMetadataProvider(List<Partition> partitions) {
50 ValidationUtils.assertNotNull(partitions, "partitions");
51
52 for (Partition p : partitions) {
53 partitionMap.put(p.getPartition(), p);
54
55 if (p.getDefaults() != null && STANDARD_PARTITION_HOSTNAME.equals(p.getDefaults().getHostName())) {
56 standardHostnamePatternDnsSuffixes.add(p.getDnsSuffix());
57 }
58
59 for (Service service : p.getServices().values()) {
60 for (Endpoint endpoint : service.getEndpoints().values()) {
61 if (endpoint.getHostName() != null &&
62 endpoint.getCredentialScope() != null &&
63 endpoint.getCredentialScope().getRegion() != null) {
64
65
66 Region region = cacheRegion(new PartitionRegionImpl(endpoint.getCredentialScope().getRegion(), p));
67 credentialScopeRegionByHost.put(endpoint.getHostName(), region);
68 }
69 }
70 }
71 }
72 }
73
74 @Override
75 public List<Region> getRegions() {
76 final List<Region> regions = new ArrayList<Region>();
77
78 for (Partition p : partitionMap.values()) {
79 for (Map.Entry<String, com.amazonaws.partitions.model.Region>
80 entry : p.getRegions().entrySet()) {
81 regions.add(new Region(new PartitionRegionImpl(entry.getKey(),
82 p)));
83 }
84 }
85 return Collections.unmodifiableList(regions);
86 }
87
88 @Override
89 public Region getRegion(String regionName) {
90
91 if (regionName == null) return null;
92
93 final Region regionFromCache = getRegionFromCache(regionName);
94
95 if (regionFromCache != null) {
96 return regionFromCache;
97 }
98
99 return createNewRegion(regionName);
100 }
101
102 private Region createNewRegion(String regionName) {
103 for (Partition p : partitionMap.values()) {
104 if (p.hasRegion(regionName)) {
105 return cacheRegion(new PartitionRegionImpl(regionName, p));
106 }
107 }
108
109 Partition awsPartition = partitionMap.get("aws");
110 if (awsPartition != null) {
111 return cacheRegion(new PartitionRegionImpl(regionName, awsPartition));
112 } else {
113 return null;
114 }
115 }
116
117 private Region getRegionFromCache(String regionName) {
118 return regionCache.get(regionName);
119 }
120
121 private Region cacheRegion(PartitionRegionImpl regionImpl) {
122 final Region region = new Region(regionImpl);
123
124 regionCache.put(region.getName(), region);
125
126 return region;
127 }
128
129 @Override
130 public List<Region> getRegionsForService(String serviceName) {
131 final List<Region> allRegions = getRegions();
132 final List<Region> serviceSupportedRegions = new ArrayList<Region>();
133
134 for (Region r : allRegions) {
135 if (r.isServiceSupported(serviceName)) {
136 serviceSupportedRegions.add(r);
137 }
138 }
139 return serviceSupportedRegions;
140 }
141
142 @Override
143 public Region tryGetRegionByExplicitEndpoint(String endpoint) {
144 String host = getHost(endpoint);
145 return credentialScopeRegionByHost.get(host);
146 }
147
148 @Override
149 public Region tryGetRegionByEndpointDnsSuffix(String endpoint) {
150 String host = getHost(endpoint);
151
152 for (String dnsSuffix : standardHostnamePatternDnsSuffixes) {
153 dnsSuffix = "." + dnsSuffix;
154
155
156
157 if (host.endsWith(dnsSuffix)) {
158 String serviceRegion = host.substring(0, host.length() - dnsSuffix.length());
159 String region = serviceRegion.substring(serviceRegion.lastIndexOf('.') + 1);
160
161 if (region.isEmpty()) {
162 return null;
163 }
164
165
166
167
168 return getRegion(region);
169 }
170 }
171
172 return null;
173 }
174 }
175