Skip to content

Commit 5340ed7

Browse files
Dillon Nysdnys1
authored andcommitted
feat(smithy): ec2Query protocol
Adds support for the `ec2Query` protocol which is used by the EC2 service exclusively.
1 parent c92d96f commit 5340ed7

File tree

17 files changed

+239
-42
lines changed

17 files changed

+239
-42
lines changed

packages/smithy/smithy/lib/src/ast/traits.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export 'traits/aws/protocols/aws_json_1_0_trait.dart';
1919
export 'traits/aws/protocols/aws_json_1_1_trait.dart';
2020
export 'traits/aws/protocols/aws_protocol_trait.dart';
2121
export 'traits/aws/protocols/aws_query_trait.dart';
22+
export 'traits/aws/protocols/ec2_query_trait.dart';
2223
export 'traits/aws/protocols/rest_json_1_trait.dart';
2324
export 'traits/aws/protocols/rest_xml_trait.dart';
2425
export 'traits/aws/service_trait.dart';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import 'package:json_annotation/json_annotation.dart';
5+
import 'package:smithy/ast.dart';
6+
7+
part 'ec2_query_trait.g.dart';
8+
9+
@JsonSerializable()
10+
class Ec2QueryTrait extends AWSProtocolTrait {
11+
const Ec2QueryTrait()
12+
: super(
13+
id,
14+
timestampFormat: TimestampFormat.dateTime,
15+
);
16+
17+
factory Ec2QueryTrait.fromJson(Object? json) =>
18+
_$Ec2QueryTraitFromJson((json as Map).cast<String, Object?>());
19+
20+
static const id = ShapeId(namespace: 'aws.protocols', shape: 'ec2Query');
21+
22+
@override
23+
Map<String, Object?> toJson() => _$Ec2QueryTraitToJson(this);
24+
25+
@override
26+
List<ShapeId> get traits => const [
27+
CorsTrait.id,
28+
EndpointTrait.id,
29+
HostLabelTrait.id,
30+
Ec2QueryNameTrait.id,
31+
XmlAttributeTrait.id,
32+
XmlFlattenedTrait.id,
33+
XmlNameTrait.id,
34+
XmlNamespaceTrait.id,
35+
TimestampFormatTrait.id,
36+
];
37+
}
38+
39+
/// Provides a custom name to use when serializing a structure member
40+
/// name as an EC2 query property.
41+
class Ec2QueryNameTrait extends StringTrait {
42+
const Ec2QueryNameTrait(String value) : super(id, value);
43+
44+
factory Ec2QueryNameTrait.fromJson(Object? json) =>
45+
Ec2QueryNameTrait(json as String);
46+
47+
static const id = ShapeId(namespace: 'aws.protocols', shape: 'ec2QueryName');
48+
}

packages/smithy/smithy/lib/src/ast/traits/aws/protocols/ec2_query_trait.g.dart

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/smithy/smithy/lib/src/ast/traits/trait.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ abstract class Trait<TraitValue extends Object>
142142
AwsQueryTrait.id: AwsQueryTrait.fromJson,
143143
AwsQueryErrorTrait.id: AwsQueryErrorTrait.fromJson,
144144
AwsQueryCompatibleTrait.id: AwsQueryCompatibleTrait.fromJson,
145+
Ec2QueryTrait.id: Ec2QueryTrait.fromJson,
146+
Ec2QueryNameTrait.id: Ec2QueryNameTrait.fromJson,
145147
RestJson1Trait.id: RestJson1Trait.fromJson,
146148
RestXmlTrait.id: RestXmlTrait.fromJson,
147149
S3UnwrappedXmlOutputTrait.id: S3UnwrappedXmlOutputTrait.fromJson,

packages/smithy/smithy/lib/src/serialization/xml/smithy_xml_plugin.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ import 'package:xml/xml.dart';
99
class SmithyXmlPlugin implements SerializerPlugin {
1010
const SmithyXmlPlugin();
1111

12-
/// Extracts the root element from the response document.
13-
XmlElement responseRootElement(XmlDocument document) => document.rootElement;
14-
1512
@override
1613
Object? beforeSerialize(Object? object, FullType specifiedType) {
1714
if (specifiedType.isUnspecified) {
@@ -189,6 +186,9 @@ class SmithyXmlPlugin implements SerializerPlugin {
189186
if (object is! String || !object.startsWith('<')) {
190187
return object;
191188
}
189+
if (specifiedType == const FullType(String)) {
190+
return object;
191+
}
192192
try {
193193
object = XmlDocument.parse(object);
194194
} on XmlParserException {
@@ -197,7 +197,7 @@ class SmithyXmlPlugin implements SerializerPlugin {
197197
return object;
198198
}
199199
}
200-
return _deserialize(responseRootElement(object));
200+
return _deserialize(object.rootElement);
201201
}
202202

203203
@override

packages/smithy/smithy/lib/src/serialization/xml/xml_indexer.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ abstract class XmlIndexer {
44
static const XmlIndexer none = _NoneIndexer();
55
static const XmlIndexer awsQueryList = _AwsQueryListIndexer();
66
static const XmlIndexer awsQueryMap = _AwsQueryMapIndexer();
7+
static const XmlIndexer ec2QueryList = _Ec2QueryListIndexer();
78

89
String elementName(String name, int index);
910
}
@@ -22,6 +23,13 @@ class _AwsQueryMapIndexer implements XmlIndexer {
2223
String elementName(String name, int index) => '${index + 1}.$name';
2324
}
2425

26+
class _Ec2QueryListIndexer implements XmlIndexer {
27+
const _Ec2QueryListIndexer();
28+
29+
@override
30+
String elementName(String name, int index) => '${index + 1}';
31+
}
32+
2533
class _NoneIndexer implements XmlIndexer {
2634
const _NoneIndexer();
2735

packages/smithy/smithy_aws/lib/smithy_aws.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export 'src/http/retry/aws_retryer.dart' hide zMaxAttempts, zRetryAttempt;
2323
export 'src/protocol/aws_json_1_0.dart';
2424
export 'src/protocol/aws_json_1_1.dart';
2525
export 'src/protocol/aws_query_protocol.dart';
26+
export 'src/protocol/ec2_query.dart';
2627
export 'src/protocol/rest_json_1.dart';
2728
export 'src/protocol/rest_xml.dart';
2829
export 'src/s3/s3_client_config.dart';

packages/smithy/smithy_aws/lib/src/protocol/aws_query_protocol.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class AwsQueryProtocol<InputPayload, Input, OutputPayload, Output>
4646
);
4747

4848
static final _coreSerializers = (Serializers().toBuilder()
49-
..addPlugin(const AwsQueryPlugin())
49+
..addPlugin(const SmithyXmlPlugin())
5050
..addAll(const [
5151
QueryBoolSerializer(),
5252
QueryIntSerializer(),

packages/smithy/smithy_aws/lib/src/protocol/aws_query_serializer.dart

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ import 'package:built_value/serializer.dart';
44
import 'package:smithy/smithy.dart';
55
import 'package:xml/xml.dart';
66

7-
class AwsQueryPlugin extends SmithyXmlPlugin {
8-
const AwsQueryPlugin();
9-
10-
@override
11-
XmlElement responseRootElement(XmlDocument document) =>
12-
document.rootElement.firstElementChild!;
13-
}
14-
157
class AwsQuerySerializer implements FullSerializer<List<int>> {
168
AwsQuerySerializer(
179
this._serializers, {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import 'dart:convert';
5+
6+
import 'package:aws_common/aws_common.dart';
7+
import 'package:smithy/ast.dart';
8+
import 'package:smithy_aws/src/protocol/aws_query_protocol.dart';
9+
import 'package:xml/xml.dart';
10+
11+
class Ec2QueryProtocol<InputPayload, Input, OutputPayload, Output>
12+
extends AwsQueryProtocol<InputPayload, Input, OutputPayload, Output> {
13+
Ec2QueryProtocol({
14+
required super.action,
15+
required super.version,
16+
super.requestInterceptors = const [],
17+
super.responseInterceptors = const [],
18+
super.serializers = const [],
19+
super.builderFactories = const {},
20+
});
21+
22+
@override
23+
ShapeId get protocolId => Ec2QueryTrait.id;
24+
25+
@override
26+
Future<String?> resolveErrorType(AWSBaseHttpResponse response) async {
27+
try {
28+
final body = await utf8.decodeStream(response.split());
29+
final el = XmlDocument.parse(body).rootElement;
30+
return el.childElements
31+
.firstWhere((el) => el.name.local == 'Errors')
32+
.childElements
33+
.firstWhere((el) => el.name.local == 'Error')
34+
.childElements
35+
.firstWhere((el) => el.name.local == 'Code')
36+
.innerText;
37+
} on Exception {
38+
return null;
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)