software.amazon.awssdk.services.iottwinmaker.endpoints.internal.PartitionFn Maven / Gradle / Ivy
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package software.amazon.awssdk.services.iottwinmaker.endpoints.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.utils.MapUtils;
@SdkInternalApi
public class PartitionFn extends SingleArgFn {
public static final String ID = "aws.partition";
public static final Identifier NAME = Identifier.of("name");
public static final Identifier DNS_SUFFIX = Identifier.of("dnsSuffix");
public static final Identifier DUAL_STACK_DNS_SUFFIX = Identifier.of("dualStackDnsSuffix");
public static final Identifier SUPPORTS_FIPS = Identifier.of("supportsFIPS");
public static final Identifier SUPPORTS_DUAL_STACK = Identifier.of("supportsDualStack");
public static final Identifier INFERRED = Identifier.of("inferred");
private final LazyValue partitionData = LazyValue. builder()
.initializer(this::loadPartitionData).build();
private final LazyValue awsPartition = LazyValue. builder().initializer(this::findAwsPartition).build();
public PartitionFn(FnNode node) {
super(node);
}
public static PartitionFn ofExprs(Expr expr) {
return new PartitionFn(FnNode.ofExprs(ID, expr));
}
@Override
public T acceptFnVisitor(FnVisitor visitor) {
return visitor.visitPartition(this);
}
public static PartitionFn fromParam(Parameter param) {
return PartitionFn.ofExprs(param.expr());
}
@Override
public Value evalArg(Value arg) {
String regionName = arg.expectString();
PartitionData data = partitionData.value();
Partition matchedPartition;
boolean inferred = false;
// Known region
matchedPartition = data.regionMap.get(regionName);
if (matchedPartition == null) {
// try matching on region name pattern
for (Partition p : data.partitions) {
Pattern regex = Pattern.compile(p.regionRegex());
if (regex.matcher(regionName).matches()) {
matchedPartition = p;
inferred = true;
break;
}
}
}
// Couldn't find the region by name or pattern matching. Fallback to 'aws' partition.
if (matchedPartition == null) {
matchedPartition = awsPartition.value();
}
Outputs matchedOutputs = matchedPartition.outputs();
return Value.fromRecord(MapUtils.of(NAME, Value.fromStr(matchedPartition.id()), DNS_SUFFIX,
Value.fromStr(matchedOutputs.dnsSuffix()), DUAL_STACK_DNS_SUFFIX,
Value.fromStr(matchedOutputs.dualStackDnsSuffix()), SUPPORTS_FIPS, Value.fromBool(matchedOutputs.supportsFips()),
SUPPORTS_DUAL_STACK, Value.fromBool(matchedOutputs.supportsDualStack()), INFERRED, Value.fromBool(inferred)));
}
private PartitionData loadPartitionData() {
PartitionDataProvider provider = new DefaultPartitionDataProvider();
// TODO: support custom partitions.json
Partitions partitions = provider.loadPartitions();
PartitionData partitionData = new PartitionData();
partitions.partitions().forEach(part -> {
partitionData.partitions.add(part);
part.regions().forEach((name, override) -> {
partitionData.regionMap.put(name, part);
});
});
return partitionData;
}
private Partition findAwsPartition() {
return partitionData.value().partitions.stream().filter(p -> p.id().equalsIgnoreCase("aws")).findFirst().orElse(null);
}
private static class PartitionData {
private final List partitions = new ArrayList<>();
private final Map regionMap = new HashMap<>();
}
private static final class LazyValue {
private final Supplier initializer;
private T value;
private boolean initialized;
private LazyValue(Builder builder) {
this.initializer = builder.initializer;
}
public T value() {
if (!initialized) {
value = initializer.get();
initialized = true;
}
return value;
}
public static Builder builder() {
return new Builder<>();
}
public static class Builder {
private Supplier initializer;
public Builder initializer(Supplier initializer) {
this.initializer = initializer;
return this;
}
public LazyValue build() {
return new LazyValue<>(this);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy