Skip to content

Surface API Review Document API [Review only] #3786

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

Closed
wants to merge 16 commits into from

Conversation

joviegas
Copy link
Contributor

Motivation and Context

Modifications

Testing

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions. Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated LaunchChangelog

License

  • I confirm that this pull request can be released under the Apache 2 license

joviegas and others added 9 commits January 20, 2023 17:26
* Adding new Interface EnhancedDocument

* Fix review comments from Anna-karin and David

* Addresed Zoe's comment
* DefaultEnhancedDocument implementation

* Updated Null check in the conveter itself while iterating Arrays of AttributeValue

* handled review comments

* Update test cases for JsonAttributeCOnverter

* Removed ctor and added a builder

* Removed ctor for toBuilder
* DocumentTableSchema Implementation

* Handle review comments -1

* Handle review comments 2
@joviegas joviegas requested a review from a team as a code owner February 21, 2023 18:57
}

/**
* Question 1 : Should we add API to input {@link TableMetadata} in DocumentTableSchema.Builder ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this means. Maybe a code snippet may help?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two way door we can add latter , I will document why it is not required now

}

/**
*- Does EnhancedDocument.Builder needs add(key, Object, attributeConverterProvider)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say no. Seems error-prone since it takes a generic Object in the middle. Is there any reason we want to add it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not required , more details

/**
*- Does EnhancedDocument.Builder needs add(key, Object, attributeConverterProvider)
*
* - Should we refer bytes as binary or byte in apis example addBinary(byte[] byte) or addByte(byte[] byte)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say we should stick with SdkBytes

*
* - Should we refer bytes as binary or byte in apis example addBinary(byte[] byte) or addByte(byte[] byte)
*
* - Map<String, Object> getRawMap(String attributeName); ==> Can we remove the use of Object ? <Zoe>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 removing it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removig

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as List we cannot remove this because DDB maps can be of different type and need not be fixed to one particular type.

*
* - Map<String, Object> getRawMap(String attributeName); ==> Can we remove the use of Object ? <Zoe>
*
* - getJsonPretty. Do we actually need this?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 removing it

* - Object get(String attributeName); ==> Do we need this
* - We don't have jsonPretty utility elsewhere. Do we need it?
*
* - Builder add(String attributeName, Object value); ==> Using raw type is a bit code smell and error prone to me.Should it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, add(String attributeName, Object value) is not type safe and would defeat the purpose of all other methods IMO

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might need it for adding beans, though, where we don't know the type but we have a configured attribute converter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just realized it now 😅 . I wonder how we can prevent people from using add(String attributeName, Object value) for everything. Maybe we can rename it to something like addCustomType?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putGeneric() ? putCustom() ? poll
putObject

*/

DynamoDbTable<EnhancedDocument> table =
enhancedClient.table(tableName, TableSchema.fromDocumentSchemaBuilder()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromDocumentBuilder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromDocumentSchemaBuilder to be consistent with other Builders in tableSchema

* {@link TableSchema}
* Changes : New API added
* Type : Interface
* package :software.amazon.awssdk.enhanced.dynamodbt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is dynamodbt typo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo error

String tableName = getConcreteTableName("table-name");
DynamoDbTable<EnhancedDocument> table = enhancedClient.table(
tableName,
TableSchema.fromDocumentSchemaBuilder()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe documentSchemaBuilder? I think the others have from* because they take a bean/annotated class.

DynamoDbTable<EnhancedDocument> table = enhancedClient.table(
tableName,
TableSchema.fromDocumentSchemaBuilder()
.primaryKey("sampleHashKey", AttributeValueType.S)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partitionKey to match the annotation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, partition key also seems to be the term mostly used in other parts of the enhanced client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay

tableName,
TableSchema.fromDocumentSchemaBuilder()
.primaryKey("sampleHashKey", AttributeValueType.S)
.sortKey("sampleSortKey", AttributeValueType.S)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we support secondary sort keys or global secondary indexes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the sortIndexKey same as StaticTableMetada will add functional test for this.

Comment on lines 50 to 51
.attributeConverterProviders(CustomAttributeConverterProvider.create(),
AttributeConverterProvider.defaultProvider())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these apply to input documents (e.g. for putItem) or just output documents (e.g. from getItem)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question , thinking of it applies to only output documents like getItems. The input Documents need to specify the converters if any , explicitly in their builders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified the code the merge Table Schema and Documents attribute converters

* No attributeConverters supplied, in this case it uses the {@link DefaultAttributeConverterProvider} and does not error
*/
EnhancedDocument simpleDoc = EnhancedDocument.builder()
.addString("HashKey", "abcdefg123")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/add/put/ to match our naming conventions for map-like structures? "add" would be for lists/collections.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add replaced with put

Comment on lines 254 to 257
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> simpleDoc.getBoolean("sdkByteSet"))
.withMessage("Value of attribute sdkByteSet of type "
+ "EnhancedType(java.util.Collections$UnmodifiableRandomAccessList) "
+ "cannot be converted into a Boolean value.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could do getString on almost anything though, right, since our StringConverter is pretty open to doing whatever?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we use getString on any type .
Add functional test

Comment on lines 330 to 337
/**
* Gets the EnhancedType for the specified attribute key
*
* @param attributeName Name of the attribute.
* @return type of the specified attribute in the current item; or null if the attribute either doesn't exist or the attribute
* value is null.
*/
EnhancedType<?> getTypeOf(String attributeName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, how do we know this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We first to a get("key") which returns the value as String, Number Boolean ,Map, List etc and the we do a EnhancedType.of(value.class)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump on this. I don't think we should be able to know the type of an attribute. That should be up to the caller to tell us what to convert it to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, Will remove this API .


assertThat(simpleDoc.getSdkBytes("sdkByte")).isEqualTo(SdkBytes.fromUtf8String("a"));
assertThat(simpleDoc.getBoolean("booleanKey")).isTrue();
assertThat(simpleDoc.getJson("jsonKey")).isEqualTo("{\"1\": [\"a\", \"b\", \"c\"],\"2\": 1}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it's not clear from the example, how is this different/better for JSON than add/getString()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getString just gets a Value of type Sting , where as getJson only works on attributes of type Map and converts to json key value pairs

}

/**
*- Does EnhancedDocument.Builder needs add(key, Object, attributeConverterProvider)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I like this idea. How would it affect the table schema or table objects? Will they be updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No , TableSchema is final

*
* - Map<String, Object> getRawMap(String attributeName); ==> Can we remove the use of Object ? <Zoe>
*
* - getJsonPretty. Do we actually need this?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe for toJson?

*
* - getJsonPretty. Do we actually need this?
*
* - Object get(String attributeName); ==> Do we need this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java doc , about custom classes as maps

Comment on lines 96 to 97
static DocumentTableSchema.Builder fromDocumentSchemaBuilder(){
return DocumentTableSchema.builder();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be called documentSchemaBuilder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will update the code

Comment on lines 94 to 96
if (json == null) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we fail, instead? Same everywhere else we're doing this below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Validate.paramNotNull(json, "json") where null checks were done

}
return DefaultEnhancedDocument.builder()
.json(json)
.attributeConverterProviders(DefaultAttributeConverterProvider.create())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hear me out: After playing with this a lot, I don't think we should have any attribute converters enabled on an EnhancedDocument by default.

We should do "late resolution" of the attribute converters in the SDK. We'd only use those converters when the get* methods are called on the EnhancedDocument. That allows us to attach the attribute converters the customer has configured on their table schema before we do any of the get* calls.

A drawback of that is if they create an enhanced document and try to do get* calls on it, it will fail because they have no attribute converters configured, but that isn't the primary use-case... and they can pretty easy just fix that by adding the default converters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove it from DefaultEnhancedDocument.
But I think we require to implictly default out the converters for methods like fromJson and fromAttributeValueMap .

Input needed

  1. Pass providers in the static factory methods
    However , if we still plan to make user to supply defaultProvider then which one do you think is a better option
    If we plan to still provide it for fromJson and fromAttributeValueMap then we have following option
- static EnhancedDocument fromJson(String json, AttributeConverterProvider providers)
- static EnhancedDocument fromAttributeValueMap(Map<String, AttributeValue> attributeValueMap, AttributeConverterProvider providers) 

- static EnhancedDocument fromMap(Map<String, Object> attributes, AttributeConverterProvider providers)

Or

  1. Remove the static factory method and just provide the Builders for it
        EnhancedDocument.builder()
                        .json("json")
                        .addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
                        .build();
        EnhancedDocument.builder()
                        .atributeValueMap(attributeValueMap)
                        .addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
                        .build();
  1. What about we throw a Validation error if User doesnot specify any AttributeConverterProvider while building the EnhancedDocument and in the error message we suggest user to specify the defaultConverter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why fromMap and fromJson would require an attribute converter. Let me play with it a bit to see if I can understand...

return null;
}
DefaultEnhancedDocument.DefaultBuilder defaultBuilder = DefaultEnhancedDocument.builder();
attributes.entrySet().forEach(key -> defaultBuilder.add(key.getKey(), key.getValue()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Why not just attributes.forEach((k, v) -> ...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @return the value of the specified attribute in the current document as SdkBytes; or null if the attribute either
* doesn't exist or the attribute value is null.
*/
SdkBytes getSdkBytes(String attributeName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just call this getBytes? The customer might not know what SdkBytes are. Best prior art I could find is in transfer manager where ResumableFileDownload, Upload and Transfer have a method called serializeToBytes that returns SdkBytes and fromBytes that takes SdkBytes.

I couldn't find any methods where we call it "SdkBytes".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 285 to 301
private Boolean getBool(String attributeName) {
Object object = get(attributeName);
if (object instanceof Boolean) {
return (Boolean) object;
}
if (object instanceof String || object instanceof SdkNumber) {
if ("1".equals(object.toString())) {
return true;
}
if ("0".equals(object.toString())) {
return false;
}
return Boolean.valueOf((String) object);
}
throw new IllegalStateException("Value of attribute " + attributeName + " of type " + getTypeOf(attributeName)
+ " cannot be converted into a Boolean value.");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BooleanAttributeConverter handles this already. We should be using attribute converters for every conversion we do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this now

Comment on lines 357 to 359
if (!isNullValueAdded(attributeName, value)) {
attributeValueMap.put(attributeName, AttributeValue.fromS(value));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely should be using attribute value converters for these methods as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the code. Removed for other instances too

/**
* Converts AttributeValue to simple Java Objects like String, SdkNumber, SdkByte.
*/
public static Object toSimpleValue(AttributeValue value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the attribute converters, instead!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above when we want to get List/Map of generics the AttributeConveters fails to get the converterFor(genericTypeOfInnerElement) because of "type erasure."

* Utilities for working with {@link AttributeValue} and {@link EnhancedDocument} types.
*/
@SdkInternalApi
public final class DocumentUtils {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost this whole class looks like a case of "you should be using attribute converters instead"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with Attribute Converters is we cannot use AttributeConverters for List/Map Generics.

Example : in order to convert the List <List> the EnhancedType should be defined as new new EnhancedType<Map<String, List<List<String>>>>(){} however when want to pass a generic List or even when we want to get a generic List of List or nested Map List we loose the generic information because of "type erasure." Thus we need these additional API to extract the type of inner elements by inspecting it individually.

I was not able to solve the issue of "type erasure." with Attribute converters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attribute converters are able to get around type erasure by using enhanced types. Let me do some prototyping to see if I can better understand the problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Matt

* @param attributeName the name of the attribute that represents the partition key
* @param attributeValueType the {@link AttributeValueType} of the partition key
*/
public Builder primaryKey(String attributeName, AttributeValueType attributeValueType) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partitionKey to match the static and bean table schemas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added now

Comment on lines 96 to 97
static DocumentTableSchema.Builder fromDocumentSchemaBuilder(){
return DocumentTableSchema.builder();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will update the code

}
return DefaultEnhancedDocument.builder()
.json(json)
.attributeConverterProviders(DefaultAttributeConverterProvider.create())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove it from DefaultEnhancedDocument.
But I think we require to implictly default out the converters for methods like fromJson and fromAttributeValueMap .

Input needed

  1. Pass providers in the static factory methods
    However , if we still plan to make user to supply defaultProvider then which one do you think is a better option
    If we plan to still provide it for fromJson and fromAttributeValueMap then we have following option
- static EnhancedDocument fromJson(String json, AttributeConverterProvider providers)
- static EnhancedDocument fromAttributeValueMap(Map<String, AttributeValue> attributeValueMap, AttributeConverterProvider providers) 

- static EnhancedDocument fromMap(Map<String, Object> attributes, AttributeConverterProvider providers)

Or

  1. Remove the static factory method and just provide the Builders for it
        EnhancedDocument.builder()
                        .json("json")
                        .addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
                        .build();
        EnhancedDocument.builder()
                        .atributeValueMap(attributeValueMap)
                        .addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
                        .build();
  1. What about we throw a Validation error if User doesnot specify any AttributeConverterProvider while building the EnhancedDocument and in the error message we suggest user to specify the defaultConverter.

Comment on lines 94 to 96
if (json == null) {
return null;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Validate.paramNotNull(json, "json") where null checks were done

return null;
}
DefaultEnhancedDocument.DefaultBuilder defaultBuilder = DefaultEnhancedDocument.builder();
attributes.entrySet().forEach(key -> defaultBuilder.add(key.getKey(), key.getValue()));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @return value of the specified attribute in the current document as a number; or null if the attribute either doesn't exist
* or the attribute value is null
*/
SdkNumber getSdkNumber(String attributeName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @return Map value of the specified attribute in the current document as EnhancedDocument or null if the attribute either
* doesn't exist or the attribute value is null.
*/
EnhancedDocument getMapAsDocument(String attributeName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @param value The boolean value that needs to be set.
* @return Builder instance to construct a {@link EnhancedDocument}
*/
Builder addBoolean(String attributeName, boolean value);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 465 to 490
/**
* Appends an attribute of name attributeName with specified Set of {@link String} values to the document builder.
*
* @param attributeName Name of the attribute that needs to be added in the Document.
* @param values Set of String values that needs to be set.
* @return Builder instance to construct a {@link EnhancedDocument}
*/
Builder addStringSet(String attributeName, Set<String> values);

/**
* Appends an attribute of name attributeName with specified Set of {@link Number} values to the document builder.
*
* @param attributeName Name of the attribute that needs to be added in the Document.
* @param values Set of Number values that needs to be set.
* @return Builder instance to construct a {@link EnhancedDocument}
*/
Builder addNumberSet(String attributeName, Set<Number> values);

/**
* Appends an attribute of name attributeName with specified Set of {@link SdkBytes} values to the document builder.
*
* @param attributeName Name of the attribute that needs to be added in the Document.
* @param values Set of SdkBytes values that needs to be set.
* @return Builder instance to construct a {@link EnhancedDocument}
*/
Builder addSdkBytesSet(String attributeName, Set<SdkBytes> values);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No ,since Bytes , number, String are separtaely represented as Bs,Ns and SS we need these explicit APIs

Comment on lines 79 to 80
attributeValueMap = Collections.unmodifiableMap(objectMapToAttributeMap(builder.attributeValueMap,
attributeConverterProviders));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done changes.

Comment on lines 50 to 51
.attributeConverterProviders(CustomAttributeConverterProvider.create(),
AttributeConverterProvider.defaultProvider())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified the code the merge Table Schema and Documents attribute converters

@joviegas joviegas force-pushed the feature/master/joviegas_local_ddb_tests branch from f023ef9 to c9078fc Compare February 24, 2023 20:02
joviegas and others added 3 commits March 9, 2023 15:28
…3811)

* TableSchema API to create table and functional tests

* Surface API Review

* Surface API Review - compilation issues

* Surface API Review - Review comments

* Surface API Review comments from Matt

* Compilation issue and toStringMethod for JsonNode

* Updated after handling Matt's comments

* Functional Test added

* Update in test cases

* Removed functional tests , will create new PR for this

* Review comments handled

* Explicutly adding the dependency in th pom.xml

* Removed @code from @snippet line in javadoc
* Remove extra spaces in Json and make it same as Items as in V1

* Moved Json string helper functions to seperate class
@joviegas joviegas force-pushed the feature/master/joviegas_local_ddb_tests branch from c395ac2 to b60c4fc Compare March 15, 2023 20:37
.putString("direct_attr", "sample_value")
.putWithType("custom_attr", customObject,
EnhancedType.of(CustomClassForDocumentAPI.class))
.putList(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putMapOfType is not here, but it should probably be putMap to be consistent with putList

)
.build();

assertThat(customDoc.toJson()).isEqualTo("{\"direct_attr\": \"sample_value\", \"custom_attr\": {\"string\": \"str\","
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is still space. Does this PR contain the change to remove it?

CustomAttributeForDocumentConverterProvider.create(),
defaultProvider()
)
.putString("direct_attr", "sample_value")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the expected behavior if users pass null?

        EnhancedDocument simpleDoc = EnhancedDocument.builder()
                                                     .attributeConverterProviders(defaultProvider())
                                                     .putString("test", null).build();

        System.out.println(simpleDoc.toJson());

Right now it treats it as null and prints {"test": null}

.putNull("nullKey")
.putNumber("numberKey", 2.0)
.putBytes("sdkByte", SdkBytes.fromUtf8String("a"))
.putBoolean("booleanKey", true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be Builder putBoolean(String attributeName, boolean value);?

EnhancedType.of(CustomClassForDocumentAPI.class))
.build();

// Note that Converter Not found exception is thrown even though we are accessing the string attribute
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we fail at .build()?


assertThat(simpleDoc.isPresent("HashKey")).isTrue();
// No Null pointer or doesnot exist is thrown
assertThat(simpleDoc.isPresent("HashKey2")).isFalse();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joviegas
Copy link
Contributor Author

@DynamoDbDocument
@Data
class MyDocument implements EnhancedDocument
{
   @DynamoDbPartitionKey
   String key;
}

@DynamoDbBean
@Data
class MyRecord
{
   List<MyDocument> myListOfDocuments;
}

@sonarqubecloud
Copy link

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 10 Code Smells

75.9% 75.9% Coverage
0.5% 0.5% Duplication

@joviegas
Copy link
Contributor Author

joviegas commented May 9, 2023

These comments were addressed offline and in the final merge of this feature in the mainline.
This feature is already merged.

@joviegas joviegas closed this May 9, 2023
@joviegas joviegas deleted the feature/master/joviegas_local_ddb_tests branch January 15, 2025 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants