Skip to content

Commit

Permalink
Add aws smoke test model package
Browse files Browse the repository at this point in the history
Adds a package that provides a Smithy model with shapes used for
https://smithy.io/2.0/additional-specs/smoke-tests.html#smoketestcase
`vendorParamsShape` for AWS smoke tests. The package has Java POJOs
corresponding to these shapes which can be used by code generators
to do aws-specific configuration on generated smoke tests.

The POJOs are meant to be direct translations of the Smithy shapes,
so to make it more ergonomic to get the POJOs from a smoke test
case I added a util class AwsSmokeTestModel that can be used to
check whether a smoke test case has either concrete vendor params
shape, and to get the respective POJO.
  • Loading branch information
milesziemer committed Jan 24, 2024
1 parent 6418c56 commit 31f3fd0
Show file tree
Hide file tree
Showing 10 changed files with 552 additions and 0 deletions.
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ include ":smithy-rules-engine"
include ":smithy-smoke-test-traits"
include ":smithy-syntax"
include ":smithy-aws-endpoints"
include ":smithy-aws-smoke-test-model"
15 changes: 15 additions & 0 deletions smithy-aws-smoke-test-model/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

description = "Defines shapes used by AWS for modeling smoke tests"

ext {
displayName = "Smithy :: AWS :: Smoke Test :: Model"
moduleName = "software.amazon.smithy.aws.smoketest.model"
}

dependencies {
api project(":smithy-smoke-test-traits")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.aws.smoketests.model;

import java.util.Optional;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.smoketests.traits.SmokeTestCase;

/**
* Provides methods for interfacing with Java representations of the different
* kinds of vendor params shapes used in smoke tests for AWS services.
*/
public final class AwsSmokeTestModel {
private AwsSmokeTestModel() {
}

/**
* @param testCase The test case to check.
* @return {@code true} if the {@code testCase}'s {@link SmokeTestCase#getVendorParams()}
* are {@link AwsVendorParams}.
*/
public static boolean hasAwsVendorParams(SmokeTestCase testCase) {
return testCase.getVendorParamsShape()
.filter(AwsVendorParams.ID::equals)
.isPresent();
}

/**
* @param testCase The test case to check.
* @return {@code true} if the {@code testCase}'s {@link SmokeTestCase#getVendorParams()}
* are {@link S3VendorParams}.
*/
public static boolean hasS3VendorParams(SmokeTestCase testCase) {
return testCase.getVendorParamsShape()
.filter(S3VendorParams.ID::equals)
.isPresent();
}

/**
* Gets the vendor params for the given {@code forTestCase} as {@link AwsVendorParams}.
*
* <p>The vendor params will be present if {@link #hasAwsVendorParams(SmokeTestCase)}
* was {@code true} for the given {@code forTestCase}.
*
* @param forTestCase The test case to get vendor params for.
* @return The optionally present vendor params as {@link S3VendorParams}.
*/
public static Optional<AwsVendorParams> getAwsVendorParams(SmokeTestCase forTestCase) {
if (!hasAwsVendorParams(forTestCase)) {
return Optional.empty();
}

ObjectNode vendorParams = forTestCase.getVendorParams().orElse(Node.objectNode());
return Optional.of(new AwsVendorParams(vendorParams));
}

/**
* Gets the vendor params for the given {@code forTestCase} as {@link S3VendorParams}.
*
* <p>The vendor params will be present if {@link #hasS3VendorParams(SmokeTestCase)}
* was {@code true} for the given {@code forTestCase}.
*
* @param forTestCase The test case to get vendor params for.
* @return The optionally present vendor params as {@link S3VendorParams}.
*/
public static Optional<S3VendorParams> getS3VendorParams(SmokeTestCase forTestCase) {
if (!hasS3VendorParams(forTestCase)) {
return Optional.empty();
}

ObjectNode vendorParams = forTestCase.getVendorParams().orElse(Node.objectNode());
return Optional.of(new S3VendorParams(vendorParams));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.aws.smoketests.model;

import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;

/**
* Concrete vendor params to apply to AWS services by default.
*/
public final class AwsVendorParams extends BaseAwsVendorParams {
public static final ShapeId ID = ShapeId.from("aws.test#AwsVendorParams");

AwsVendorParams(ObjectNode node) {
super(node);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.aws.smoketests.model;

import java.util.List;
import java.util.Optional;
import software.amazon.smithy.model.node.ObjectNode;

/**
* Base vendor params for all AWS services.
*/
public abstract class BaseAwsVendorParams {
private static final String DEFAULT_REGION = "us-west-2";
private static final boolean DEFAULT_USE_FIPS = false;
private static final boolean DEFAULT_USE_DUALSTACK = false;
private static final boolean DEFAULT_USE_ACCOUNT_ID_ROUTING = true;

private final String region;
private final List<String> sigv4aRegionSet;
private final String uri;
private final boolean useFips;
private final boolean useDualstack;
private final boolean useAccountIdRouting;

BaseAwsVendorParams(ObjectNode node) {
this.region = node.getStringMemberOrDefault("region", DEFAULT_REGION);
this.sigv4aRegionSet = node.getArrayMember("sigv4aRegionSet")
.map(a -> a.getElementsAs(el -> el.expectStringNode().getValue()))
.orElse(null);
this.uri = node.getStringMemberOrDefault("uri", null);
this.useFips = node.getBooleanMemberOrDefault("useFips", DEFAULT_USE_FIPS);
this.useDualstack = node.getBooleanMemberOrDefault("useDualstack", DEFAULT_USE_DUALSTACK);
this.useAccountIdRouting = node.getBooleanMemberOrDefault(
"useAccountIdRouting", DEFAULT_USE_ACCOUNT_ID_ROUTING);
}

/**
* @return The AWS region to sign the request for and to resolve the default
* endpoint with. Defaults to {@code us-west-2}.
*/
public String getRegion() {
return region;
}

/**
* @return The set of regions to sign a sigv4a request with, if present.
*/
public Optional<List<String>> getSigv4aRegionSet() {
return Optional.ofNullable(sigv4aRegionSet);
}

/**
* @return The static endpoint to send the request to, if present.
*/
public Optional<String> getUri() {
return Optional.ofNullable(uri);
}

/**
* @return Whether to resolve a FIPS compliant endpoint or not. Defaults to
* {@code false}.
*/
public boolean useFips() {
return useFips;
}

/**
* @return Whether to resolve a dualstack endpoint or not. Defaults to
* {@code false}.
*/
public boolean useDualstack() {
return useDualstack;
}

/**
* @return Whether to use account ID based routing where applicable.
* Defaults to {@code true}.
*/
public boolean useAccountIdRouting() {
return useAccountIdRouting;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.aws.smoketests.model;

import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;

/**
* Vendor params for S3.
*/
public final class S3VendorParams extends BaseAwsVendorParams {
public static final ShapeId ID = ShapeId.from("aws.test#S3VendorParams");

private static final boolean DEFAULT_USE_ACCELERATE = false;
private static final boolean DEFAULT_USE_GLOBAL_ENDPOINT = false;
private static final boolean DEFAULT_FORCE_PATH_STYLE = false;
private static final boolean DEFAULT_USE_ARN_REGION = true;
private static final boolean DEFAULT_USE_MULTI_REGION_ACCESS_POINTS = true;

private final boolean useAccelerate;
private final boolean useGlobalEndpoint;
private final boolean forcePathStyle;
private final boolean useArnRegion;
private final boolean useMultiRegionAccessPoints;

S3VendorParams(ObjectNode node) {
super(node);
this.useAccelerate = node.getBooleanMemberOrDefault("useAccelerate", DEFAULT_USE_ACCELERATE);
this.useGlobalEndpoint = node.getBooleanMemberOrDefault("useGlobalEndpoint", DEFAULT_USE_GLOBAL_ENDPOINT);
this.forcePathStyle = node.getBooleanMemberOrDefault("forcePathStyle", DEFAULT_FORCE_PATH_STYLE);
this.useArnRegion = node.getBooleanMemberOrDefault("useArnRegion", DEFAULT_USE_ARN_REGION);
this.useMultiRegionAccessPoints = node.getBooleanMemberOrDefault(
"useMultiRegionAccessPoints", DEFAULT_USE_MULTI_REGION_ACCESS_POINTS);
}

/**
* @return Whether to resolve an accelerate endpoint or not. Defaults to
* {@code false}.
*/
public boolean useAccelerate() {
return useAccelerate;
}

/**
* @return Whether to use the global endpoint for {@code us-east-1}.
* Defaults to {@code false}.
*/
public boolean useGlobalEndpoint() {
return useGlobalEndpoint;
}

/**
* @return Whether to force path-style addressing. Defaults to {@code false}.
*/
public boolean forcePathStyle() {
return forcePathStyle;
}

/**
* @return Whether to use the region in the bucket ARN to override the set
* region. Defaults to {@code true}.
*/
public boolean useArnRegion() {
return useArnRegion;
}

/**
* @return Whether to use S3's multi-region access points. Defaults to
* {@code true}.
*/
public boolean useMultiRegionAccessPoints() {
return useMultiRegionAccessPoints;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
$version: "2.0"

namespace aws.test

/// Base vendor params for all aws services.
@mixin
@suppress(["UnreferencedShape"])
structure BaseAwsVendorParams {
/// The AWS region to sign the request for and to resolve the default
/// endpoint with.
region: String = "us-west-2"

/// The set of regions to sign a sigv4a request with.
sigv4aRegionSet: NonEmptyStringList

/// A static endpoint to send the request to.
uri: String

/// Whether to resolve a FIPS compliant endpoint or not.
useFips: Boolean = false

/// Whether to resolve a dualstack endpoint or not.
useDualstack: Boolean = false

/// Whether to use account ID based routing where applicable.
useAccountIdRouting: Boolean = true
}

@private
@length(min: 1)
@suppress(["UnreferencedShape"])
list NonEmptyStringList {
member: String
}

/// Concrete vendor params to apply to AWS services by default.
@suppress(["UnreferencedShape"])
structure AwsVendorParams with [BaseAwsVendorParams] {}

/// Vendor params for S3.
@suppress(["UnreferencedShape"])
structure S3VendorParams with [BaseAwsVendorParams] {
/// Whether to resolve an accelerate endpoint or not.
useAccelerate: Boolean = false

/// Whether to use the global endpoint for us-east-1.
useGlobalEndpoint: Boolean = false

/// Whether to force path-style addressing.
forcePathStyle: Boolean = false

/// Whether to use the region in the bucket arn to override the set
/// region.
useArnRegion: Boolean = true

/// Whether to use S3's multi-region access points.
useMultiRegionAccessPoints: Boolean = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aws.test.smithy
Loading

0 comments on commit 31f3fd0

Please sign in to comment.