Skip to content

Commit 1c68ab0

Browse files
skmcgrailkstich
authored andcommitted
Smithy Rules Engine Traits
1 parent edfd6cc commit 1c68ab0

39 files changed

+2206
-0
lines changed

config/spotbugs/filter.xml

+6
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,10 @@
136136
<Class name="software.amazon.smithy.model.knowledge.PropertyBindingIndex"/>
137137
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
138138
</Match>
139+
140+
<!-- This is a false positive. The value is guarded behind an Objects.requireNonNull -->
141+
<Match>
142+
<Class name="software.amazon.smithy.rulesengine.traits.ContextIndex"/>
143+
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
144+
</Match>
139145
</FindBugsFilter>

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ include ":smithy-waiters"
2828
include ":smithy-aws-cloudformation-traits"
2929
include ":smithy-aws-cloudformation"
3030
include ":smithy-validation-model"
31+
include ":smithy-rules-engine"

smithy-rules-engine/build.gradle

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
description = "Smithy rules engine Language and traits"
17+
18+
ext {
19+
displayName = "Smithy :: Rules Engine"
20+
moduleName = "software.amazon.smithy.rulesengine"
21+
}
22+
23+
dependencies {
24+
api project(":smithy-model")
25+
api project(":smithy-utils")
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
/**
17+
* Smithy Rules Engine.
18+
*/
19+
@SmithyUnstableApi
20+
package software.amazon.smithy.rulesengine;
21+
22+
import software.amazon.smithy.utils.SmithyUnstableApi;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.rulesengine.traits;
17+
18+
import java.util.Objects;
19+
import java.util.Optional;
20+
import software.amazon.smithy.model.shapes.ShapeType;
21+
import software.amazon.smithy.utils.SmithyBuilder;
22+
import software.amazon.smithy.utils.SmithyUnstableApi;
23+
import software.amazon.smithy.utils.ToSmithyBuilder;
24+
25+
/**
26+
* A service client context parameter definition.
27+
*/
28+
@SmithyUnstableApi
29+
public final class ClientContextParamDefinition implements ToSmithyBuilder<ClientContextParamDefinition> {
30+
private final ShapeType type;
31+
private final String documentation;
32+
33+
private ClientContextParamDefinition(Builder builder) {
34+
this.type = SmithyBuilder.requiredState("type", builder.type);
35+
this.documentation = builder.documentation;
36+
}
37+
38+
public static Builder builder() {
39+
return new Builder();
40+
}
41+
42+
public ShapeType getType() {
43+
return type;
44+
}
45+
46+
public Optional<String> getDocumentation() {
47+
return Optional.ofNullable(documentation);
48+
}
49+
50+
public Builder toBuilder() {
51+
return builder()
52+
.type(type)
53+
.documentation(documentation);
54+
}
55+
56+
@Override
57+
public int hashCode() {
58+
return Objects.hash(getType(), getDocumentation());
59+
}
60+
61+
@Override
62+
public boolean equals(Object o) {
63+
if (this == o) {
64+
return true;
65+
}
66+
if (o == null || getClass() != o.getClass()) {
67+
return false;
68+
}
69+
ClientContextParamDefinition that = (ClientContextParamDefinition) o;
70+
return getType() == that.getType() && Objects.equals(getDocumentation(), that.getDocumentation());
71+
}
72+
73+
public static final class Builder implements SmithyBuilder<ClientContextParamDefinition> {
74+
private ShapeType type;
75+
private String documentation;
76+
77+
private Builder() {
78+
}
79+
80+
public Builder type(ShapeType type) {
81+
this.type = type;
82+
return this;
83+
}
84+
85+
public Builder documentation(String documentation) {
86+
this.documentation = documentation;
87+
return this;
88+
}
89+
90+
public ClientContextParamDefinition build() {
91+
return new ClientContextParamDefinition(this);
92+
}
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.rulesengine.traits;
17+
18+
import java.util.LinkedHashMap;
19+
import java.util.Map;
20+
import software.amazon.smithy.model.node.Node;
21+
import software.amazon.smithy.model.node.NodeMapper;
22+
import software.amazon.smithy.model.shapes.ShapeId;
23+
import software.amazon.smithy.model.traits.AbstractTrait;
24+
import software.amazon.smithy.model.traits.AbstractTraitBuilder;
25+
import software.amazon.smithy.model.traits.Trait;
26+
import software.amazon.smithy.utils.BuilderRef;
27+
import software.amazon.smithy.utils.SmithyBuilder;
28+
import software.amazon.smithy.utils.SmithyUnstableApi;
29+
import software.amazon.smithy.utils.ToSmithyBuilder;
30+
31+
/**
32+
* Indicates that the named rule-set parameters that should be configurable
33+
* on the service client using the specified smithy types.
34+
*/
35+
@SmithyUnstableApi
36+
public final class ClientContextParamsTrait extends AbstractTrait implements ToSmithyBuilder<ClientContextParamsTrait> {
37+
public static final ShapeId ID = ShapeId.from("smithy.rules#clientContextParams");
38+
39+
private final Map<String, ClientContextParamDefinition> parameters;
40+
41+
public ClientContextParamsTrait(Builder builder) {
42+
super(ID, builder.getSourceLocation());
43+
this.parameters = builder.parameters.copy();
44+
}
45+
46+
public static Builder builder() {
47+
return new Builder();
48+
}
49+
50+
public Map<String, ClientContextParamDefinition> getParameters() {
51+
return parameters;
52+
}
53+
54+
@Override
55+
protected Node createNode() {
56+
NodeMapper mapper = new NodeMapper();
57+
return mapper.serialize(this.getParameters()).expectObjectNode();
58+
}
59+
60+
@Override
61+
public SmithyBuilder<ClientContextParamsTrait> toBuilder() {
62+
return builder()
63+
.sourceLocation(getSourceLocation())
64+
.parameters(getParameters());
65+
}
66+
67+
public static final class Provider extends AbstractTrait.Provider {
68+
public Provider() {
69+
super(ID);
70+
}
71+
72+
@Override
73+
public Trait createTrait(ShapeId target, Node value) {
74+
NodeMapper mapper = new NodeMapper();
75+
76+
Map<String, ClientContextParamDefinition> parameters = new LinkedHashMap<>();
77+
value.expectObjectNode().getMembers().forEach((stringNode, node) -> {
78+
parameters.put(stringNode.getValue(), mapper.deserialize(node, ClientContextParamDefinition.class));
79+
});
80+
81+
ClientContextParamsTrait trait = builder()
82+
.parameters(parameters)
83+
.sourceLocation(value)
84+
.build();
85+
trait.setNodeCache(value);
86+
return trait;
87+
}
88+
}
89+
90+
public static final class Builder extends AbstractTraitBuilder<ClientContextParamsTrait, Builder> {
91+
private final BuilderRef<Map<String, ClientContextParamDefinition>> parameters = BuilderRef.forOrderedMap();
92+
93+
private Builder() {
94+
}
95+
96+
public Builder parameters(Map<String, ClientContextParamDefinition> parameters) {
97+
this.parameters.clear();
98+
this.parameters.get().putAll(parameters);
99+
return this;
100+
}
101+
102+
public Builder putParameter(String name, ClientContextParamDefinition definition) {
103+
this.parameters.get().put(name, definition);
104+
return this;
105+
}
106+
107+
public Builder removeParameter(String name) {
108+
this.parameters.get().remove(name);
109+
return this;
110+
}
111+
112+
public Builder clearParameters() {
113+
this.parameters.clear();
114+
return this;
115+
}
116+
117+
@Override
118+
public ClientContextParamsTrait build() {
119+
return new ClientContextParamsTrait(this);
120+
}
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.rulesengine.traits;
17+
18+
import java.lang.ref.WeakReference;
19+
import java.util.Map;
20+
import java.util.Objects;
21+
import java.util.Optional;
22+
import software.amazon.smithy.model.Model;
23+
import software.amazon.smithy.model.knowledge.KnowledgeIndex;
24+
import software.amazon.smithy.model.node.Node;
25+
import software.amazon.smithy.model.shapes.MemberShape;
26+
import software.amazon.smithy.model.shapes.OperationShape;
27+
import software.amazon.smithy.model.shapes.Shape;
28+
import software.amazon.smithy.utils.MapUtils;
29+
import software.amazon.smithy.utils.Pair;
30+
import software.amazon.smithy.utils.SmithyUnstableApi;
31+
32+
/**
33+
* Resolves an indexes the context parameters in the model.
34+
*/
35+
@SmithyUnstableApi
36+
public final class ContextIndex implements KnowledgeIndex {
37+
private final WeakReference<Model> model;
38+
39+
public ContextIndex(Model model) {
40+
this.model = new WeakReference<>(model);
41+
}
42+
43+
public static ContextIndex of(Model model) {
44+
return model.getKnowledge(ContextIndex.class, ContextIndex::new);
45+
}
46+
47+
/**
48+
* Gets the mapping of context parameter names and corresponding {@link ClientContextParamDefinition} to be
49+
* generated on the service client's configuration.
50+
*
51+
* @param service The service shape.
52+
* @return The mapping of context parameter names to {@link ClientContextParamDefinition}.
53+
*/
54+
public Optional<ClientContextParamsTrait> getClientContextParams(Shape service) {
55+
return service.getTrait(ClientContextParamsTrait.class);
56+
}
57+
58+
/**
59+
* Gets the static context parameter names and their {@link StaticContextParamDefinition} to be set for the given
60+
* operation.
61+
*
62+
* @param operation The operation shape.
63+
* @return The mapping of context parameter names to the static {@link Node} value to be set.
64+
*/
65+
public Optional<StaticContextParamsTrait> getStaticContextParams(Shape operation) {
66+
return operation.getTrait(StaticContextParamsTrait.class);
67+
}
68+
69+
/**
70+
* Gets the mapping of {@link MemberShape} to {@link ContextParamTrait} for the operation.
71+
*
72+
* @param operation The operation shape.
73+
* @return The mapping of operation's {@link MemberShape} to {@link ContextParamTrait}.
74+
*/
75+
public Map<MemberShape, ContextParamTrait> getContextParams(Shape operation) {
76+
OperationShape operationShape = operation.asOperationShape()
77+
.orElseThrow(() -> new IllegalArgumentException(operation.toShapeId()
78+
+ " is not an operation shape"));
79+
80+
return getModel().expectShape(operationShape.getInputShape())
81+
.members().stream()
82+
.map(memberShape -> Pair.of(memberShape, memberShape.getTrait(ContextParamTrait.class)))
83+
.filter(pair -> pair.right.isPresent())
84+
.collect(MapUtils.toUnmodifiableMap(pair -> pair.left, pair -> pair.right.get()));
85+
}
86+
87+
private Model getModel() {
88+
return Objects.requireNonNull(model.get(), "The dereferenced WeakReference<Model> is null");
89+
}
90+
}

0 commit comments

Comments
 (0)