Add support for stringArray rules engine Parameters (#2266)
This commit is contained in:
parent
e52e625d0b
commit
a6f1d1ce12
|
@ -23,9 +23,9 @@ This following is the :rfc:`ABNF <5234>` grammar for rule set parameter names:
|
|||
.. productionlist:: smithy
|
||||
identifier = ALPHA *(ALPHA / DIGIT)
|
||||
|
||||
Parameters declare their respective type using the ``type`` key. There are two
|
||||
supported rule set parameter types: ``string`` and ``boolean``. The following
|
||||
table provides the description of these types, and their Smithy compatible
|
||||
Parameters declare their respective type using the ``type`` key. The following
|
||||
parameter types are supported: ``string``, ``boolean``, and ``stringArray``.
|
||||
The following table provides the description of these types, and their Smithy compatible
|
||||
types whose values can be bound to these parameters. Rule set parameters are
|
||||
always considered nullable and have no default value associated with them.
|
||||
|
||||
|
@ -42,6 +42,9 @@ always considered nullable and have no default value associated with them.
|
|||
* - ``boolean``
|
||||
- ``boolean``
|
||||
- Boolean value type.
|
||||
* - ``stringArray``
|
||||
- ``list``
|
||||
- A list with ``string`` members.
|
||||
|
||||
|
||||
.. _rules-engine-parameters-implementation:
|
||||
|
@ -219,13 +222,14 @@ The ``staticContextParam`` structure has the following properties:
|
|||
* - value
|
||||
- ``document``
|
||||
- **Required**. The static value to be set for the parameter. The type
|
||||
of the value MUST be either a ``string`` or ``boolean``.
|
||||
of the value MUST be either a ``string``, ``boolean`` or an
|
||||
array of ``string``.
|
||||
|
||||
Each parameter is identified using it’s name as specified in the rule set. The
|
||||
type of a ``staticContextParam`` MUST be compatible with the parameter type
|
||||
specified in the rule set.
|
||||
|
||||
The following example specifies two parameters to statically set for an
|
||||
The following example specifies three parameters to statically set for an
|
||||
operation:
|
||||
|
||||
.. code-block:: smithy
|
||||
|
@ -236,6 +240,9 @@ operation:
|
|||
}
|
||||
previewEndpoint: {
|
||||
value: true
|
||||
},
|
||||
supportedPrefixes: {
|
||||
value: ["host", "id", "resourceId"]
|
||||
}
|
||||
)
|
||||
operation GetThing {}
|
||||
|
|
|
@ -91,13 +91,13 @@ A parameter object contains the following properties:
|
|||
- Description
|
||||
* - type
|
||||
- ``string``
|
||||
- **Required**. MUST be one of ``string`` or ``boolean``.
|
||||
- **Required**. MUST be one of ``string``, ``boolean``, or ``stringArray``.
|
||||
* - builtIn
|
||||
- ``string``
|
||||
- Specifies a named built-in value that is sourced and provided to the
|
||||
endpoint provider by a caller.
|
||||
* - default
|
||||
- ``string`` or ``boolean``
|
||||
- ``string``, ``boolean`` or an array of ``string``.
|
||||
- Specifies the default value for the parameter if not set. Parameters
|
||||
with defaults MUST also be marked as ``required``. The type of the
|
||||
provided default MUST match ``type``.
|
||||
|
|
|
@ -45,6 +45,9 @@ public interface Type {
|
|||
if (parameterType == ParameterType.BOOLEAN) {
|
||||
return booleanType();
|
||||
}
|
||||
if (parameterType == ParameterType.STRING_ARRAY) {
|
||||
return arrayType(stringType());
|
||||
}
|
||||
throw new IllegalArgumentException("Unexpected parameter type: " + parameterType);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public final class ArrayValue extends Value {
|
|||
} else {
|
||||
Type first = values.get(0).getType();
|
||||
for (Value value : values) {
|
||||
if (value.getType() != first) {
|
||||
if (!value.getType().isA(first)) {
|
||||
throw new SourceException("An array cannot contain different types", this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,9 @@ public final class GetAttr extends LibraryFunction {
|
|||
throw new InvalidRulesException("Invalid path component: slice index must be >= 0",
|
||||
sourceLocation);
|
||||
}
|
||||
result.add(Part.Key.of(component.substring(0, slicePartIndex)));
|
||||
if (slicePartIndex > 0) {
|
||||
result.add(Part.Key.of(component.substring(0, slicePartIndex)));
|
||||
}
|
||||
result.add(new Part.Index(slice));
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new InvalidRulesException(String.format("%s could not be parsed as a number", slicePart),
|
||||
|
|
|
@ -10,6 +10,7 @@ import software.amazon.smithy.model.node.Node;
|
|||
import software.amazon.smithy.model.node.StringNode;
|
||||
import software.amazon.smithy.model.shapes.ShapeType;
|
||||
import software.amazon.smithy.rulesengine.language.error.RuleError;
|
||||
import software.amazon.smithy.rulesengine.language.evaluation.type.ArrayType;
|
||||
import software.amazon.smithy.rulesengine.language.evaluation.type.BooleanType;
|
||||
import software.amazon.smithy.rulesengine.language.evaluation.type.StringType;
|
||||
import software.amazon.smithy.rulesengine.language.evaluation.type.Type;
|
||||
|
@ -28,7 +29,12 @@ public enum ParameterType {
|
|||
/**
|
||||
* A "boolean" parameter type.
|
||||
*/
|
||||
BOOLEAN;
|
||||
BOOLEAN,
|
||||
|
||||
/**
|
||||
* An array (list) of strings parameter type.
|
||||
*/
|
||||
STRING_ARRAY;
|
||||
|
||||
/**
|
||||
* Creates a {@link ParameterType} of a specific type from the given Node information.
|
||||
|
@ -39,14 +45,18 @@ public enum ParameterType {
|
|||
*/
|
||||
public static ParameterType fromNode(StringNode node) throws RuleError {
|
||||
String value = node.getValue();
|
||||
if (value.equalsIgnoreCase("String")) {
|
||||
if (value.equalsIgnoreCase("string")) {
|
||||
return STRING;
|
||||
}
|
||||
if (value.equalsIgnoreCase("Boolean")) {
|
||||
if (value.equalsIgnoreCase("boolean")) {
|
||||
return BOOLEAN;
|
||||
}
|
||||
if (value.equals("stringArray")) {
|
||||
return STRING_ARRAY;
|
||||
}
|
||||
throw new RuleError(new SourceException(
|
||||
String.format("Unexpected parameter type `%s`. Expected `String` or `Boolean`.", value), node));
|
||||
String.format("Unexpected parameter type `%s`. Expected `string`, `boolean`, or `stringArray`.",
|
||||
value), node));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,6 +73,17 @@ public enum ParameterType {
|
|||
if (node.isBooleanNode()) {
|
||||
return BOOLEAN;
|
||||
}
|
||||
if (node.isArrayNode()) {
|
||||
// confirm all elements are Strings
|
||||
node.expectArrayNode().getElements().forEach(memberNode -> {
|
||||
if (!memberNode.isStringNode()) {
|
||||
throw new RuleError(new SourceException(
|
||||
String.format("Unexpected array member parameter type `%s`. Expected a string.",
|
||||
memberNode.getType()), memberNode));
|
||||
}
|
||||
});
|
||||
return STRING_ARRAY;
|
||||
}
|
||||
throw new RuleError(new SourceException(
|
||||
String.format("Unexpected parameter type `%s`. Expected a string or boolean.", node.getType()), node));
|
||||
}
|
||||
|
@ -81,8 +102,14 @@ public enum ParameterType {
|
|||
if (type instanceof BooleanType) {
|
||||
return BOOLEAN;
|
||||
}
|
||||
if (type instanceof ArrayType) {
|
||||
ArrayType arrayType = (ArrayType) type;
|
||||
if (arrayType.getMember().isA(Type.stringType()) || arrayType.getMember().isA(Type.emptyType())) {
|
||||
return STRING_ARRAY;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(
|
||||
String.format("Unexpected parameter type `%s`. Expected a string or boolean.", type));
|
||||
String.format("Unexpected parameter type `%s`. Expected a string, boolean, or array<string>.", type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,6 +132,16 @@ public enum ParameterType {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this == STRING ? "String" : "Boolean";
|
||||
// Inconsistent casing on string/boolean to preserve backwards compatibility in serialization
|
||||
switch (this) {
|
||||
case STRING:
|
||||
return "String";
|
||||
case BOOLEAN:
|
||||
return "Boolean";
|
||||
case STRING_ARRAY:
|
||||
return "stringArray";
|
||||
default:
|
||||
return "Unknown Type";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public final class StaticContextParamsTraitValidator extends AbstractValidator {
|
|||
.orElse(Collections.emptyMap());
|
||||
for (Map.Entry<String, StaticContextParamDefinition> entry : definitionMap.entrySet()) {
|
||||
Node node = entry.getValue().getValue();
|
||||
if (node.isStringNode() || node.isBooleanNode()) {
|
||||
if (supportedType(node)) {
|
||||
continue;
|
||||
}
|
||||
events.add(error(operationShape,
|
||||
|
@ -45,4 +45,17 @@ public final class StaticContextParamsTraitValidator extends AbstractValidator {
|
|||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
private static boolean supportedType(Node node) {
|
||||
if (node.isStringNode() || node.isBooleanNode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node.isArrayNode()) {
|
||||
// all elements must be strings
|
||||
return node.expectArrayNode().getElements().stream().allMatch(e -> e.isStringNode());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
[WARNING] example#FizzBuzz: This shape applies a trait that is unstable: smithy.rules#clientContextParams | UnstableTrait
|
||||
[WARNING] example#FizzBuzz: This shape applies a trait that is unstable: smithy.rules#endpointRuleSet | UnstableTrait
|
||||
[WARNING] example#FizzBuzz: This shape applies a trait that is unstable: smithy.rules#endpointTests | UnstableTrait
|
||||
[WARNING] example#GetThing: This shape applies a trait that is unstable: smithy.rules#staticContextParams | UnstableTrait.smithy.rules#staticContextParams
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace example
|
|||
use smithy.rules#clientContextParams
|
||||
use smithy.rules#endpointRuleSet
|
||||
use smithy.rules#endpointTests
|
||||
use smithy.rules#staticContextParams
|
||||
|
||||
@clientContextParams(
|
||||
bar: {type: "string", documentation: "a client string parameter"}
|
||||
|
@ -30,10 +31,16 @@ use smithy.rules#endpointTests
|
|||
default: "asdf"
|
||||
documentation: "docs"
|
||||
},
|
||||
stringArrayParam: {
|
||||
type: "stringArray",
|
||||
required: true,
|
||||
default: ["a", "b", "c"],
|
||||
documentation: "docs"
|
||||
}
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
"documentation": "Template the region into the URI when FIPS is enabled",
|
||||
"documentation": "Template baz into URI when bar is set",
|
||||
"conditions": [
|
||||
{
|
||||
"fn": "isSet",
|
||||
|
@ -49,6 +56,25 @@ use smithy.rules#endpointTests
|
|||
},
|
||||
"type": "endpoint"
|
||||
},
|
||||
{
|
||||
"documentation": "Template first array value into URI",
|
||||
"conditions": [
|
||||
{
|
||||
"fn": "getAttr",
|
||||
"argv": [
|
||||
{
|
||||
"ref": "stringArrayParam"
|
||||
},
|
||||
"[0]"
|
||||
],
|
||||
"assign": "arrayValue"
|
||||
}
|
||||
],
|
||||
"endpoint": {
|
||||
"url": "https://example.com/{arrayValue}"
|
||||
},
|
||||
"type": "endpoint"
|
||||
},
|
||||
{
|
||||
"conditions": [],
|
||||
"documentation": "error fallthrough",
|
||||
|
@ -94,6 +120,19 @@ use smithy.rules#endpointTests
|
|||
}
|
||||
},
|
||||
{
|
||||
"documentation": "Default array values used"
|
||||
"params": {
|
||||
}
|
||||
"expect": {
|
||||
"endpoint": {
|
||||
"url": "https://example.com/a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": {
|
||||
"stringArrayParam": []
|
||||
}
|
||||
"documentation": "a documentation string",
|
||||
"expect": {
|
||||
"error": "endpoint error"
|
||||
|
@ -106,6 +145,9 @@ service FizzBuzz {
|
|||
operations: [GetThing]
|
||||
}
|
||||
|
||||
@staticContextParams(
|
||||
"stringArrayParam": {value: []}
|
||||
)
|
||||
operation GetThing {
|
||||
input := {}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ use smithy.rules#staticContextParams
|
|||
"ExtraParameter": {
|
||||
"type": "string",
|
||||
"documentation": "docs"
|
||||
},
|
||||
"StringArrayParameter": {
|
||||
"type": "stringArray",
|
||||
documentation: "docs"
|
||||
}
|
||||
},
|
||||
"rules": []
|
||||
|
@ -38,7 +42,8 @@ service FizzBuzz {
|
|||
|
||||
@staticContextParams(
|
||||
"ParameterFoo": {value: "foo"},
|
||||
"ExtraParameter": {value: "someValue"}
|
||||
"ExtraParameter": {value: "someValue"},
|
||||
"StringArrayParameter": {value: ["a", "b", "c"]}
|
||||
)
|
||||
operation GetResource {
|
||||
input: GetResourceInput
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// while parsing the parameter `RegionName`
|
||||
// at invalid-rules/invalid-param-type.json5:10
|
||||
// while parsing the parameter type
|
||||
// Unexpected parameter type `notastring`. Expected `String` or `Boolean`.
|
||||
// Unexpected parameter type `notastring`. Expected `string`, `boolean`, or `stringArray`.
|
||||
// at invalid-rules/invalid-param-type.json5:11
|
||||
{
|
||||
"version": "1.2",
|
||||
|
|
|
@ -4,5 +4,5 @@ namespace smithy.example
|
|||
|
||||
use smithy.rules#staticContextParams
|
||||
|
||||
@staticContextParams(arrayParam: {value: ["foo", "bar"]})
|
||||
@staticContextParams(arrayParam: {value: ["foo", 3]})
|
||||
operation OperationArray {}
|
||||
|
|
Loading…
Reference in New Issue