Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions clients/client-sqs/src/protocols/Aws_json1_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -883,33 +883,40 @@ const de_CommandError = async (output: __HttpResponse, context: __SerdeContext):
throw await de_OverLimitRes(parsedOutput, context);
case "QueueDoesNotExist":
case "com.amazonaws.sqs#QueueDoesNotExist":
case "AWS.SimpleQueueService.NonExistentQueue":
throw await de_QueueDoesNotExistRes(parsedOutput, context);
case "RequestThrottled":
case "com.amazonaws.sqs#RequestThrottled":
throw await de_RequestThrottledRes(parsedOutput, context);
case "UnsupportedOperation":
case "com.amazonaws.sqs#UnsupportedOperation":
case "AWS.SimpleQueueService.UnsupportedOperation":
throw await de_UnsupportedOperationRes(parsedOutput, context);
case "ResourceNotFoundException":
case "com.amazonaws.sqs#ResourceNotFoundException":
throw await de_ResourceNotFoundExceptionRes(parsedOutput, context);
case "MessageNotInflight":
case "com.amazonaws.sqs#MessageNotInflight":
case "AWS.SimpleQueueService.MessageNotInflight":
throw await de_MessageNotInflightRes(parsedOutput, context);
case "ReceiptHandleIsInvalid":
case "com.amazonaws.sqs#ReceiptHandleIsInvalid":
throw await de_ReceiptHandleIsInvalidRes(parsedOutput, context);
case "BatchEntryIdsNotDistinct":
case "com.amazonaws.sqs#BatchEntryIdsNotDistinct":
case "AWS.SimpleQueueService.BatchEntryIdsNotDistinct":
throw await de_BatchEntryIdsNotDistinctRes(parsedOutput, context);
case "EmptyBatchRequest":
case "com.amazonaws.sqs#EmptyBatchRequest":
case "AWS.SimpleQueueService.EmptyBatchRequest":
throw await de_EmptyBatchRequestRes(parsedOutput, context);
case "InvalidBatchEntryId":
case "com.amazonaws.sqs#InvalidBatchEntryId":
case "AWS.SimpleQueueService.InvalidBatchEntryId":
throw await de_InvalidBatchEntryIdRes(parsedOutput, context);
case "TooManyEntriesInBatchRequest":
case "com.amazonaws.sqs#TooManyEntriesInBatchRequest":
case "AWS.SimpleQueueService.TooManyEntriesInBatchRequest":
throw await de_TooManyEntriesInBatchRequestRes(parsedOutput, context);
case "InvalidAttributeName":
case "com.amazonaws.sqs#InvalidAttributeName":
Expand All @@ -919,42 +926,53 @@ const de_CommandError = async (output: __HttpResponse, context: __SerdeContext):
throw await de_InvalidAttributeValueRes(parsedOutput, context);
case "QueueDeletedRecently":
case "com.amazonaws.sqs#QueueDeletedRecently":
case "AWS.SimpleQueueService.QueueDeletedRecently":
throw await de_QueueDeletedRecentlyRes(parsedOutput, context);
case "QueueNameExists":
case "com.amazonaws.sqs#QueueNameExists":
case "QueueAlreadyExists":
throw await de_QueueNameExistsRes(parsedOutput, context);
case "InvalidIdFormat":
case "com.amazonaws.sqs#InvalidIdFormat":
throw await de_InvalidIdFormatRes(parsedOutput, context);
case "PurgeQueueInProgress":
case "com.amazonaws.sqs#PurgeQueueInProgress":
case "AWS.SimpleQueueService.PurgeQueueInProgress":
throw await de_PurgeQueueInProgressRes(parsedOutput, context);
case "KmsAccessDenied":
case "com.amazonaws.sqs#KmsAccessDenied":
case "KMS.AccessDeniedException":
throw await de_KmsAccessDeniedRes(parsedOutput, context);
case "KmsDisabled":
case "com.amazonaws.sqs#KmsDisabled":
case "KMS.DisabledException":
throw await de_KmsDisabledRes(parsedOutput, context);
case "KmsInvalidKeyUsage":
case "com.amazonaws.sqs#KmsInvalidKeyUsage":
case "KMS.InvalidKeyUsageException":
throw await de_KmsInvalidKeyUsageRes(parsedOutput, context);
case "KmsInvalidState":
case "com.amazonaws.sqs#KmsInvalidState":
case "KMS.InvalidStateException":
throw await de_KmsInvalidStateRes(parsedOutput, context);
case "KmsNotFound":
case "com.amazonaws.sqs#KmsNotFound":
case "KMS.NotFoundException":
throw await de_KmsNotFoundRes(parsedOutput, context);
case "KmsOptInRequired":
case "com.amazonaws.sqs#KmsOptInRequired":
case "KMS.OptInRequired":
throw await de_KmsOptInRequiredRes(parsedOutput, context);
case "KmsThrottled":
case "com.amazonaws.sqs#KmsThrottled":
case "KMS.ThrottlingException":
throw await de_KmsThrottledRes(parsedOutput, context);
case "InvalidMessageContents":
case "com.amazonaws.sqs#InvalidMessageContents":
throw await de_InvalidMessageContentsRes(parsedOutput, context);
case "BatchRequestTooLong":
case "com.amazonaws.sqs#BatchRequestTooLong":
case "AWS.SimpleQueueService.BatchRequestTooLong":
throw await de_BatchRequestTooLongRes(parsedOutput, context);
default:
const parsedBody = parsedOutput.body;
Expand Down Expand Up @@ -2094,8 +2112,17 @@ function sharedHeaders(operation: string): __HeaderBag {
const populateBodyWithQueryCompatibility = (parsedOutput: any, headers: __HeaderBag) => {
const queryErrorHeader = headers["x-amzn-query-error"];
if (parsedOutput.body !== undefined && queryErrorHeader != null) {
const codeAndType = queryErrorHeader.split(";");
parsedOutput.body.Code = codeAndType[0];
parsedOutput.body.Type = codeAndType[1];
const [Code, Type] = queryErrorHeader.split(";");
const entries = Object.entries(parsedOutput.body);
const Error = {
Type,
Code,
} as any;
Object.assign(parsedOutput.body, Error);
for (const [k, v] of entries) {
Error[k] = v;
}
delete Error.__type;
parsedOutput.body.Error = Error;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@
import static software.amazon.smithy.model.knowledge.HttpBinding.Location.DOCUMENT;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import software.amazon.smithy.aws.traits.auth.UnsignedPayloadTrait;
import software.amazon.smithy.aws.traits.protocols.AwsQueryCompatibleTrait;
import software.amazon.smithy.aws.traits.protocols.AwsQueryErrorTrait;
import software.amazon.smithy.model.knowledge.HttpBindingIndex;
import software.amazon.smithy.model.knowledge.NeighborProviderIndex;
import software.amazon.smithy.model.neighbor.Walker;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.shapes.ShapeVisitor;
import software.amazon.smithy.model.traits.IdempotencyTokenTrait;
import software.amazon.smithy.model.traits.TimestampFormatTrait;
Expand Down Expand Up @@ -300,6 +306,29 @@ static void generateProtocolTests(ProtocolGenerator generator, GenerationContext
AwsProtocolUtils::filterMalformedRequestTests).run();
}

/**
* @return map of error full shape id to alias strings having AwsQueryCompat error code.
*/
static Map<String, TreeSet<String>> getErrorAliases(GenerationContext context,
Collection<OperationShape> operations) {
Map<String, TreeSet<String>> aliases = new HashMap<>();
ServiceShape service = context.getService();
boolean awsQueryCompatible = service.hasTrait(AwsQueryCompatibleTrait.class);
if (awsQueryCompatible) {
for (OperationShape operation : operations) {
List<ShapeId> errors = operation.getErrors();
for (ShapeId error : errors) {
Shape errorShape = context.getModel().expectShape(error);
if (errorShape.hasTrait(AwsQueryErrorTrait.class)) {
String alias = errorShape.expectTrait(AwsQueryErrorTrait.class).getCode();
aliases.computeIfAbsent(error.toString(), k -> new TreeSet<>()).add(alias);
}
}
}
}
return aliases;
}

private static boolean filterProtocolTests(
ServiceShape service,
OperationShape operation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@

package software.amazon.smithy.aws.typescript.codegen;

import java.util.Collection;
import java.util.Map;
import java.util.TreeSet;
import software.amazon.smithy.aws.traits.protocols.AwsQueryCompatibleTrait;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.typescript.codegen.SmithyCoreSubmodules;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
import software.amazon.smithy.typescript.codegen.protocols.cbor.SmithyRpcV2Cbor;
import software.amazon.smithy.utils.IoUtils;

/**
* Extension of the Smithy RPCv2 CBOR protocol generator, adding
Expand All @@ -23,19 +28,17 @@ public void generateSharedComponents(GenerationContext context) {
if (context.getService().hasTrait(AwsQueryCompatibleTrait.class)) {
TypeScriptWriter writer = context.getWriter();
writer.addImport("HeaderBag", "__HeaderBag", TypeScriptDependency.SMITHY_TYPES);
writer.write("""
const populateBodyWithQueryCompatibility = (parsedOutput: any, headers: __HeaderBag) => {
const queryErrorHeader = headers["x-amzn-query-error"];
if (parsedOutput.body !== undefined && queryErrorHeader != null) {
const codeAndType = queryErrorHeader.split(";");
parsedOutput.body.Code = codeAndType[0];
parsedOutput.body.Type = codeAndType[1];
}
};
""");
writer.write(IoUtils.readUtf8Resource(
AwsProtocolUtils.class, "populate-body-with-query-compatibility-code-stub.ts"));
}
}

@Override
public Map<String, TreeSet<String>> getErrorAliases(GenerationContext context,
Collection<OperationShape> operations) {
return AwsProtocolUtils.getErrorAliases(context, operations);
}

@Override
protected void writeSharedRequestHeaders(ProtocolGenerator.GenerationContext context) {
TypeScriptWriter writer = context.getWriter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

package software.amazon.smithy.aws.typescript.codegen;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import software.amazon.smithy.aws.traits.ServiceTrait;
import software.amazon.smithy.aws.traits.protocols.AwsQueryCompatibleTrait;
import software.amazon.smithy.aws.typescript.codegen.protocols.DeserializerElisionDenyList;
Expand Down Expand Up @@ -56,6 +59,37 @@ abstract class JsonRpcProtocolGenerator extends HttpRpcProtocolGenerator {
super(true);
}

@Override
public void generateSharedComponents(GenerationContext context) {
super.generateSharedComponents(context);
AwsProtocolUtils.generateJsonParseBody(context);
AwsProtocolUtils.generateJsonParseErrorBody(context);
AwsProtocolUtils.addItempotencyAutofillImport(context);

TypeScriptWriter writer = context.getWriter();
writer.addUseImports(getApplicationProtocol().getResponseType());
writer.addDependency(AwsDependency.AWS_SDK_CORE);
writer.addImport("loadRestJsonErrorCode", null, AwsDependency.AWS_SDK_CORE);

if (context.getService().hasTrait(AwsQueryCompatibleTrait.class)) {
AwsProtocolUtils.generateJsonParseBodyWithQueryHeader(context);
}
writer.write(
context.getStringStore().flushVariableDeclarationCode()
);
}

@Override
public void generateProtocolTests(GenerationContext context) {
AwsProtocolUtils.generateProtocolTests(this, context);
}

@Override
public Map<String, TreeSet<String>> getErrorAliases(GenerationContext context,
Collection<OperationShape> operations) {
return AwsProtocolUtils.getErrorAliases(context, operations);
}

@Override
protected String getOperationPath(GenerationContext context, OperationShape operationShape) {
return "/";
Expand Down Expand Up @@ -97,26 +131,6 @@ protected void generateDocumentBodyShapeDeserializers(GenerationContext context,
);
}

@Override
public void generateSharedComponents(GenerationContext context) {
super.generateSharedComponents(context);
AwsProtocolUtils.generateJsonParseBody(context);
AwsProtocolUtils.generateJsonParseErrorBody(context);
AwsProtocolUtils.addItempotencyAutofillImport(context);

TypeScriptWriter writer = context.getWriter();
writer.addUseImports(getApplicationProtocol().getResponseType());
writer.addDependency(AwsDependency.AWS_SDK_CORE);
writer.addImport("loadRestJsonErrorCode", null, AwsDependency.AWS_SDK_CORE);

if (context.getService().hasTrait(AwsQueryCompatibleTrait.class)) {
AwsProtocolUtils.generateJsonParseBodyWithQueryHeader(context);
}
writer.write(
context.getStringStore().flushVariableDeclarationCode()
);
}

@Override
protected void writeRequestHeaders(GenerationContext context, OperationShape operation) {
TypeScriptWriter writer = context.getWriter();
Expand Down Expand Up @@ -164,10 +178,6 @@ protected void serializeInputDocument(
writer.write("body = JSON.stringify($L);", inputStructure.accept(getMemberSerVisitor(context, "input")));
}

private DocumentMemberSerVisitor getMemberSerVisitor(GenerationContext context, String dataSource) {
return new JsonMemberSerVisitor(context, dataSource, getDocumentTimestampFormat());
}

@Override
protected boolean writeUndefinedInputBody(GenerationContext context, OperationShape operation) {
TypeScriptWriter writer = context.getWriter();
Expand Down Expand Up @@ -203,17 +213,16 @@ protected void deserializeOutputDocument(
writer.write("contents = $L;", outputStructure.accept(getMemberDeserVisitor(context, "data")));
}

private ShapeVisitor<String> getMemberDeserVisitor(GenerationContext context, String dataSource) {
return new JsonMemberDeserVisitor(context, dataSource, getDocumentTimestampFormat());
@Override
protected boolean enableSerdeElision() {
return true;
}

@Override
public void generateProtocolTests(GenerationContext context) {
AwsProtocolUtils.generateProtocolTests(this, context);
private DocumentMemberSerVisitor getMemberSerVisitor(GenerationContext context, String dataSource) {
return new JsonMemberSerVisitor(context, dataSource, getDocumentTimestampFormat());
}

@Override
protected boolean enableSerdeElision() {
return true;
private ShapeVisitor<String> getMemberDeserVisitor(GenerationContext context, String dataSource) {
return new JsonMemberDeserVisitor(context, dataSource, getDocumentTimestampFormat());
}
}
Loading
Loading