-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Generate DDB client code for Java V2 AWS SDK #92
Conversation
// This is the only time when Polymorph needs to convert a list of a Dafny type to a list | ||
// of a type that Polymorph does not know about. So this is a special case and warrants | ||
// its own generation logic. | ||
if (targetShape.getId().getName().equals("BinarySetAttributeValue")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: I am a little hesitant on using only the name of a shape to trigger an edge case.
BinarySetAttributeValue
is probably fine, as it's so unique,
no other AWS Service model we use will include it...
Actually, another Database Service (RDS, Aurora, etc. ) might...
// SizeEstimateRangeGB is a list of the case above, where Smithy models values as integers, | ||
// but the SDK expects doubles. | ||
// This is the only instance of double -> int conversion in a list right now. | ||
if (memberShape.getMemberName().equals("SizeEstimateRangeGB")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: Many AWS Services could have a shape named SizeEstimateRangeGB
.
We only know this logic works for DDB...
We should use both the namespace and the name to protect this edge case.
return shapeName.equals("ConsumedCapacityUnits") | ||
|| shapeName.equals("Double"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: Many AWS Services could have a shape named ConsumedCapacityUnits
.
We only know this logic works for DDB...
We should use both the namespace and the name to protect this edge case.
.addAnnotation( | ||
AnnotationSpec.builder(SuppressWarnings.class) | ||
.addMember("value", "$S", "unchecked") | ||
.build() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Praise: Nice job on figuring this out!
Nuances with Dafny like this trip my polymorph work up all the time.
public static final ClassName BLOB_TO_NATIVE_SDK_BYTES = | ||
ClassName.get("software.amazon.awssdk.core", "SdkBytes"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue/Suggestion: It may be best if this constant lived in awssdk/v2/ShimV2.java
,
as compared to here.
// "TargetValue" refers to a table's target R/W capacity target values. | ||
// SDK handles these as doubles, but the Smithy model stores them as integers. | ||
if (member.getMemberName().equals("TargetValue")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: Many AWS Services could have a shape named TargetValue
.
We only know this logic works for DDB...
We should use both the namespace and the name to protect this edge case.
...ph/src/main/java/software/amazon/polymorph/smithyjava/generator/awssdk/v2/ToNativeAwsV2.java
Show resolved
Hide resolved
public ClassName classForDouble() { | ||
return ClassName.get(Double.class); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: I wonder why we need this method?
if ("message".equals(uncapitalize(memberShape.getMemberName()))) { | ||
return CodeBlock.of("$L.get$L()", variableName, capitalize(memberShape.getMemberName())); | ||
// BatchStatementError and CancellationReason types' messages are retrieved via "message". | ||
if (memberShape.getContainer().getName().contains("BatchStatementError") | ||
|| memberShape.getContainer().getName().contains("CancellationReason")) { | ||
return CodeBlock.of("$L.$L()", variableName, | ||
uncapitalize(memberShape.getMemberName())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: This follows from my comment on the KMS PR.
#82 (comment)
We should go ahead and be specific here.
Fully qualify BatchStatementError
and CancellationReason
(both are names that could be in any AWS Service Model, but not get treated the same as DDB's).
I'd also advocate for handling Error Structures seperately...
i.e.: if the member name is message
and it's structure has the error
trait, use getMessage
).
public boolean shapeIdRequiresStaticTypeDescriptor(final ShapeId shapeId) { | ||
String className = classForNotErrorNotUnitShape(shapeId).toString(); | ||
|
||
return (className.equals("Dafny.Com.Amazonaws.Dynamodb.Types.AttributeMap") | ||
|| className.equals("Dafny.Com.Amazonaws.Dynamodb.Types.Key")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Praise: This is great and safe as the edge case is handled by a fully qualified name.
if (smithyName.simpleName().endsWith("Input")) { | ||
return ClassName.get(smithyName.packageName(), | ||
smithyName.simpleName() | ||
.substring( | ||
0, | ||
smithyName.simpleName().lastIndexOf("Input")) | ||
+ "Request" | ||
); | ||
} | ||
if (smithyName.simpleName().endsWith("Output")) { | ||
return ClassName.get(smithyName.packageName(), | ||
smithyName.simpleName() | ||
.substring( | ||
0, | ||
smithyName.simpleName().lastIndexOf("Output")) | ||
+ "Response" | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Why did we not need this for KMS?
Is this not true for KMS?
Or do all KMS shapes already use Request
and Response
... I bet that is it...
// OperationErrors are streamed to gather the types that are only inputs or outputs to errors. | ||
// Right now this is only CancellationReasonList. | ||
LinkedHashSet<ShapeId> operationErrors = subject.serviceShape | ||
.getOperations().stream() | ||
.map(shapeId -> subject.model.expectShape(shapeId, OperationShape.class)) | ||
.map(OperationShape::getErrors) | ||
.flatMap(Collection::stream) | ||
.filter(structureShape -> !structureShape.toString().contains("InvalidEndpointException")) | ||
.collect(Collectors.toCollection(LinkedHashSet::new)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the value in this.
But, operationErrors
is left in allReleventShapeIds
.
So... those Error structures will get included in convertAllRelevent
,
and will be passed to generateConvertStructure
.
Then, as part of convertServiceErrors
, they will get
another conversion method, but a modeledError
conversion method.
I will refactor this so that we only generate modeledError
.
if (memberShape.getContainer().getName().contains("BatchStatementError") | ||
|| memberShape.getContainer().getName().contains("CancellationReason")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: BatchStatementError
(link to shape in model) and
CancellationReason
(link to shape in model) are not marked with the @error
trait.
Thus, they are just normal structures.
That is why their access is via message
, as compared to getMessage
.
In Java, getMessage
is method of java.lang.Exception
,
the global base Exception.
All AWS SDK exceptions extend from java.lang.Exception
,
as do the Exceptions we generate.
This is why message
is accessed by getMessage
for structures marked with the Error trait.
Where "srv's Op strucs" is a Service's Operation Structures, or all of a Service's Operations' Input, Output, Errors and all shapes related to the above. We need dafny-lang/dafny#3034 to resolve singular datatype creation (now known as a "Record Type"). DONE: - [x] Test Java KMS - [x] Test Java DDB - [x] Merge #83 into this TODO: - [ ] Test Java DDB again - [ ] Address Issues raised in PR #82, #92, #83
Use the codegen for the AWS SDK V2 to correctly name the Enums. I have also addressed some issues raised in the PRs. DONE: - [x] Test Java KMS - [x] Test Java DDB - [x] Merge #83 into this TODO: - [ ] Implement ToNative Double solution - [ ] Test Java DDB again - [ ] Address Issues raised in PR #82, #92, #83 - [ ] Consolidate duplicated code - [ ] Test Java KMS & DDB Again - [ ] PR & Merge
Where "srv's Op strucs" is a Service's Operation Structures, or all of a Service's Operations' Input, Output, Errors and all shapes related to the above. We need dafny-lang/dafny#3034 to resolve singular datatype creation (now known as a "Record Type"). DONE: - [x] Test Java KMS - [x] Test Java DDB - [x] Merge #83 into this TODO: - [ ] Test Java DDB again - [ ] Address Issues raised in PR #82, #92, #83
Use the codegen for the AWS SDK V2 to correctly name the Enums. I have also addressed some issues raised in the PRs. DONE: - [x] Test Java KMS - [x] Test Java DDB - [x] Merge #83 into this TODO: - [ ] Implement ToNative Double solution - [ ] Test Java DDB again - [ ] Address Issues raised in PR #82, #92, #83 - [ ] Consolidate duplicated code - [ ] Test Java KMS & DDB Again - [ ] PR & Merge
This landed elsewhere right? |
Yes. I merged this else where. I left this open as I wanted to make sure I came back are resolved these issues... |
Create a shared makefile, and then use that shared makefile
Note this is based on another change that is currently in PR: #82
#82 makes changes that are used in this PR. #82 should be merged into
main-1.x
before this change is merged.Description of changes:
Testing:
I ran
bin/generate_code.sh
from my private-ESDK-dafny repo, then ranmake transpile_java && make test_java
.The tests run GetItem, QueryItem, and PutItem. See test file.
I opened a draft PR with the generated changes in my fork of private-ESDK-dafny: link
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.