From 5c2cce5657f23c6159203cf2635e7e00795a6eb4 Mon Sep 17 00:00:00 2001 From: Ankit Purvesh Shah Date: Tue, 7 Nov 2023 18:08:20 -0800 Subject: [PATCH 1/4] Enforce version pinning for specified dependencies in license check config - The build process will fail when versions of explicitly allowed dependencies in the license check configuration are updated. - This enforces a review of any updates in licenses before the changes can be merged. - This enforcement does not apply to dependencies with already allowed license types and is only for explicitly allowed dependencies --- build.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0155bdb33b..9eeb6b7a09 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -77,8 +77,10 @@ subprojects { allow("MIT") allow("BSD-2-Clause") allow("CC0-1.0") - allowUrl("https://www.zetetic.net/sqlcipher/license/") allowUrl("https://developer.android.com/studio/terms.html") + allowDependency("net.zetetic", "android-database-sqlcipher", "4.5.4") { + "BSD style License" + } allowDependency("org.jetbrains", "annotations", "16.0.1") { "Apache-2.0, but typo in license URL fixed in newer versions" } From 652216137cb2e3848e4cebbd21e75e662721aa61 Mon Sep 17 00:00:00 2001 From: Ankit Purvesh Shah Date: Fri, 10 Nov 2023 11:04:48 -0800 Subject: [PATCH 2/4] Refactor model class comparison in fetching existing mutations from PersistentRecords Change the model class comparison logic in `getMutationForModelId()` from using `getModelClass().getName()` to directly using `getName()`. This modification addresses an issue where requests from Flutter are encapsulated within a Serialized model. Previously, `getModelClass()` returned a fixed class name "com.amplifyframework.core.model.SerializedModel", making it impossible to differentiate between various model classes generating mutations. This update ensures accurate identification of model class involved in mutation. --- .../datastore/syncengine/Merger.java | 2 +- .../syncengine/PersistentMutationOutbox.java | 4 +- .../syncengine/MutationProcessorTest.java | 2 +- .../PersistentMutationOutboxTest.java | 38 +++++++++---------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java index 2b5ed6d8cc..d011b36c7e 100644 --- a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java +++ b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java @@ -103,7 +103,7 @@ Completable merge( .flatMapCompletable(shouldMerge -> { Completable firstStep; if (mutationOutbox.hasPendingMutation(model.getPrimaryKeyString(), - model.getClass().getName())) { + model.getClass().getSimpleName())) { LOG.info("Mutation outbox has pending mutation for Model: " + model.getModelName() + " with primary key: " + model.resolveIdentifier() + ". Saving the metadata, but not model itself."); diff --git a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java index 27df646677..0bdf585a31 100644 --- a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java +++ b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java @@ -99,7 +99,7 @@ PendingMutation getMutationForModelId(@NonNull String modelId, try { PendingMutation.PersistentRecord persistentRecord = results.next(); PendingMutation pendingMutation = converter.fromRecord(persistentRecord); - if (pendingMutation.getModelSchema().getModelClass().getName().equals(modelClass)) { + if (pendingMutation.getModelSchema().getName().equals(modelClass)) { mutationResult.set(pendingMutation); } } catch (Throwable throwable) { @@ -153,7 +153,7 @@ public Completable enqueue(@NonNull PendingMutation incomin // If there is no existing mutation for the model, then just apply the incoming // mutation, and be done with this. String modelId = incomingMutation.getMutatedItem().getPrimaryKeyString(); - String modelClass = incomingMutation.getModelSchema().getModelClass().getName(); + String modelClass = incomingMutation.getMutatedItem().getModelName(); // getModelSchema().getModelClass().getName(); @SuppressWarnings("unchecked") PendingMutation existingMutation = (PendingMutation) getMutationForModelId(modelId, modelClass); if (existingMutation == null || inFlightMutations.contains(existingMutation.getMutationId())) { diff --git a/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/MutationProcessorTest.java b/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/MutationProcessorTest.java index b2724ca91a..5d5152c4f1 100644 --- a/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/MutationProcessorTest.java +++ b/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/MutationProcessorTest.java @@ -178,7 +178,7 @@ public void canDrainMutationOutbox() throws DataStoreException { // And that it is no longer in the outbox. assertFalse(mutationOutbox.hasPendingMutation(tony.getPrimaryKeyString(), - tony.getClass().getName())); + tony.getClass().getSimpleName())); // And that it was passed to AppSync for publication. verify(appSync).create(eq(tony), any(), any(), any()); diff --git a/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutboxTest.java b/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutboxTest.java index 2c45d0b7ad..6348f6d56c 100644 --- a/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutboxTest.java +++ b/aws-datastore/src/test/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutboxTest.java @@ -147,7 +147,7 @@ public void enqueuePersistsMutationAndNotifiesObserver() throws DataStoreExcepti Collections.singletonList(converter.toRecord(createJameson)), storage.query(PersistentRecord.class) ); - assertTrue(mutationOutbox.hasPendingMutation(jameson.getId(), jameson.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(jameson.getId(), jameson.getClass().getSimpleName())); assertEquals(createJameson, mutationOutbox.peek()); } @@ -208,8 +208,8 @@ public void loadPreparesOutbox() throws DataStoreException, InterruptedException loadObserver.dispose(); // Assert: items are in the outbox. - assertTrue(mutationOutbox.hasPendingMutation(tony.getId(), tony.getClass().getName())); - assertTrue(mutationOutbox.hasPendingMutation(sam.getId(), sam.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(tony.getId(), tony.getClass().getSimpleName())); + assertTrue(mutationOutbox.hasPendingMutation(sam.getId(), sam.getClass().getSimpleName())); // Tony is first, since he is the older of the two mutations. assertEquals(updateTony, mutationOutbox.peek()); @@ -240,7 +240,7 @@ public void removeRemovesChangesFromQueue() throws DataStoreException, Interrupt assertEquals(0, storage.query(PersistentRecord.class).size()); assertNull(mutationOutbox.peek()); - assertFalse(mutationOutbox.hasPendingMutation(bill.getId(), bill.getClass().getName())); + assertFalse(mutationOutbox.hasPendingMutation(bill.getId(), bill.getClass().getSimpleName())); } /** @@ -330,8 +330,8 @@ public void hasPendingMutationReturnsTrueForExistingModelMutation() { boolean completed = mutationOutbox.enqueue(pendingMutation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS); assertTrue(completed); - assertTrue(mutationOutbox.hasPendingMutation(modelId, joe.getClass().getName())); - assertFalse(mutationOutbox.hasPendingMutation(mutationId.toString(), mutationId.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(modelId, joe.getClass().getSimpleName())); + assertFalse(mutationOutbox.hasPendingMutation(mutationId.toString(), mutationId.getClass().getSimpleName())); } /** @@ -357,9 +357,9 @@ public void hasPendingMutationReturnsFalseForItemNotInStore() throws DataStoreEx mutationId, joe, schema, PendingMutation.Type.CREATE, QueryPredicates.all() ); - assertFalse(mutationOutbox.hasPendingMutation(joeId, joe.getClass().getName())); + assertFalse(mutationOutbox.hasPendingMutation(joeId, joe.getClass().getSimpleName())); assertFalse(mutationOutbox.hasPendingMutation(unrelatedMutation.getMutationId().toString(), - unrelatedMutation.getClass().getName())); + unrelatedMutation.getClass().getSimpleName())); } /** @@ -385,7 +385,7 @@ public void hasPendingMutationReturnsFalseForModelMutationWithSamePrimaryKeyForD // Act & Assert: Enqueue and verify BlogOwner assertTrue(mutationOutbox.enqueue(pendingBlogOwnerMutation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertTrue(mutationOutbox.hasPendingMutation(modelId, blogOwner.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(modelId, blogOwner.getClass().getSimpleName())); // Act & Assert: Enqueue and verify Author Author author = Author.builder() @@ -394,7 +394,7 @@ public void hasPendingMutationReturnsFalseForModelMutationWithSamePrimaryKeyForD .build(); // Check hasPendingMutation returns False for Author with same Primary Key (id) as BlogOwner - assertFalse(mutationOutbox.hasPendingMutation(modelId, author.getClass().getName())); + assertFalse(mutationOutbox.hasPendingMutation(modelId, author.getClass().getSimpleName())); PendingMutation pendingAuthorMutation = PendingMutation.instance( mutationId, author, ModelSchema.fromModelClass(Author.class), @@ -403,7 +403,7 @@ public void hasPendingMutationReturnsFalseForModelMutationWithSamePrimaryKeyForD assertTrue(mutationOutbox.enqueue(pendingAuthorMutation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS)); // Make sure Author Mutation is stored - assertTrue(mutationOutbox.hasPendingMutation(modelId, author.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(modelId, author.getClass().getSimpleName())); // Act & Assert: Enqueue and verify Author Post post = Post.builder() @@ -414,7 +414,7 @@ public void hasPendingMutationReturnsFalseForModelMutationWithSamePrimaryKeyForD .build(); // Check hasPendingMutation returns False for Post with same Primary Key (id) as BlogOwner - assertFalse(mutationOutbox.hasPendingMutation(modelId, post.getClass().getName())); + assertFalse(mutationOutbox.hasPendingMutation(modelId, post.getClass().getSimpleName())); PendingMutation pendingPostMutation = PendingMutation.instance( mutationId, post, ModelSchema.fromModelClass(Post.class), @@ -423,7 +423,7 @@ public void hasPendingMutationReturnsFalseForModelMutationWithSamePrimaryKeyForD assertTrue(mutationOutbox.enqueue(pendingPostMutation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS)); // Make sure Post Mutation is stored - assertTrue(mutationOutbox.hasPendingMutation(modelId, post.getClass().getName())); + assertTrue(mutationOutbox.hasPendingMutation(modelId, post.getClass().getSimpleName())); } /** @@ -474,7 +474,7 @@ public void mutationEnqueueForModelWithDuplicatePrimaryKeyThrowsDatastoreExcepti // Additional Checks: Peek the Mutation outbox, existing mutation should be present. assertTrue(mutationOutbox.hasPendingMutation(existingBlogOwner.getPrimaryKeyString(), - existingBlogOwner.getClass().getName())); + existingBlogOwner.getClass().getSimpleName())); assertEquals(existingCreation, mutationOutbox.peek()); } @@ -521,7 +521,7 @@ public void existingCreationIncomingCreationYieldsError() throws AmplifyExceptio // Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox) assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getPrimaryKeyString(), - modelInExistingMutation.getClass().getName())); + modelInExistingMutation.getClass().getSimpleName())); assertEquals(existingCreation, mutationOutbox.peek()); } @@ -567,7 +567,7 @@ public void existingUpdateIncomingCreationYieldsError() throws AmplifyException, // Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox) assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getPrimaryKeyString(), - modelInExistingMutation.getClass().getName())); + modelInExistingMutation.getClass().getSimpleName())); assertEquals(existingUpdate, mutationOutbox.peek()); } @@ -614,7 +614,7 @@ public void existingDeletionIncomingCreationYieldsError() throws AmplifyExceptio // Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox) assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getPrimaryKeyString(), - modelInExistingMutation.getClass().getName())); + modelInExistingMutation.getClass().getSimpleName())); assertEquals(existingDeletion, mutationOutbox.peek()); } @@ -660,7 +660,7 @@ public void existingDeletionIncomingUpdateYieldsError() throws AmplifyException, // Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox) assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getPrimaryKeyString(), - modelInExistingMutation.getClass().getName())); + modelInExistingMutation.getClass().getSimpleName())); assertEquals(existingDeletion, mutationOutbox.peek()); } @@ -1186,7 +1186,7 @@ public void nextItemForModelIdReturnsFirstEnqueued() throws DataStoreException { assertTrue(completed); assertEquals( firstMutation, - mutationOutbox.getMutationForModelId(originalJoe.getId(), originalJoe.getClass().getName()) + mutationOutbox.getMutationForModelId(originalJoe.getId(), originalJoe.getClass().getSimpleName()) ); } From 674cd3329fa3ac3f15ce8bb19ef84433a3959bd3 Mon Sep 17 00:00:00 2001 From: Ankit Purvesh Shah Date: Wed, 15 Nov 2023 11:50:04 -0800 Subject: [PATCH 3/4] nit:remove comment --- .../datastore/syncengine/PersistentMutationOutbox.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java index 0bdf585a31..b22c5fc66e 100644 --- a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java +++ b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/PersistentMutationOutbox.java @@ -153,7 +153,7 @@ public Completable enqueue(@NonNull PendingMutation incomin // If there is no existing mutation for the model, then just apply the incoming // mutation, and be done with this. String modelId = incomingMutation.getMutatedItem().getPrimaryKeyString(); - String modelClass = incomingMutation.getMutatedItem().getModelName(); // getModelSchema().getModelClass().getName(); + String modelClass = incomingMutation.getMutatedItem().getModelName(); @SuppressWarnings("unchecked") PendingMutation existingMutation = (PendingMutation) getMutationForModelId(modelId, modelClass); if (existingMutation == null || inFlightMutations.contains(existingMutation.getMutationId())) { From 397d7e56f426afe6184c1c32b3fe4872ca43539c Mon Sep 17 00:00:00 2001 From: Ankit Purvesh Shah Date: Thu, 16 Nov 2023 11:00:39 -0800 Subject: [PATCH 4/4] Update Merger to use modelName in place of modelClass --- .../java/com/amplifyframework/datastore/syncengine/Merger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java index d011b36c7e..d6b25ab58b 100644 --- a/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java +++ b/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/Merger.java @@ -103,7 +103,7 @@ Completable merge( .flatMapCompletable(shouldMerge -> { Completable firstStep; if (mutationOutbox.hasPendingMutation(model.getPrimaryKeyString(), - model.getClass().getSimpleName())) { + model.getModelName())) { LOG.info("Mutation outbox has pending mutation for Model: " + model.getModelName() + " with primary key: " + model.resolveIdentifier() + ". Saving the metadata, but not model itself.");