Search in sources :

Example 16 with ModelSchema

use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.

the class MutationProcessorTest method hubEventPublishedForPublicationError.

/**
 * If the AppSync response to the mutation contains not-empty GraphQLResponse error
 * list without any ConflictUnhandled error, then
 * {@link DataStoreChannelEventName#OUTBOX_MUTATION_FAILED} event is published via Hub.
 * @throws DataStoreException On failure to save model and metadata
 */
@Test
public void hubEventPublishedForPublicationError() throws DataStoreException {
    // Save a model, its metadata, and its last sync data.
    BlogOwner model = BlogOwner.builder().name("Average Joe").build();
    ModelMetadata metadata = new ModelMetadata(model.getModelName() + "|" + model.getId(), false, 1, Temporal.Timestamp.now());
    ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
    synchronousStorageAdapter.save(model, metadata);
    // Enqueue an update in the mutation outbox
    assertTrue(mutationOutbox.enqueue(PendingMutation.update(model, schema)).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
    // When AppSync receives that update, have it respond with an error.
    AppSyncMocking.update(appSync).mockErrorResponse(model, 1);
    // Start listening for publication events.
    HubAccumulator errorAccumulator = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_FAILED, 1).start();
    // Start the mutation processor and wait for hub event.
    mutationProcessor.startDrainingMutationOutbox();
    errorAccumulator.await();
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 17 with ModelSchema

use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.

the class PendingMutationTest method pendingMutationsAreComparable.

/**
 * It is possible to sort pending mutations according to their TimeBasedUUID field.
 * @throws AmplifyException On failure to arrange model schema
 */
@Test
public void pendingMutationsAreComparable() throws AmplifyException {
    // First, create a bunch of pending mutations.
    final List<PendingMutation<? extends Model>> expectedOrder = new ArrayList<>();
    final int desiredQuantity = 10;
    for (int index = 0; index < desiredQuantity; index++) {
        // to make sure the comparator can work across model types
        if (new SecureRandom().nextBoolean()) {
            BlogOwner blogger = BlogOwner.builder().name(String.format(Locale.US, "Blogger #%d", index)).build();
            ModelSchema schema = ModelSchema.fromModelClass(BlogOwner.class);
            expectedOrder.add(PendingMutation.creation(blogger, schema));
        } else {
            Post post = Post.builder().title(String.format(Locale.US, "Title #%d", index)).status(PostStatus.ACTIVE).rating(5).build();
            ModelSchema schema = ModelSchema.fromModelClass(Post.class);
            expectedOrder.add(PendingMutation.creation(post, schema));
        }
    }
    // Okay! Now, shuffle them.
    List<PendingMutation<? extends Model>> shuffled = new ArrayList<>(expectedOrder);
    Collections.shuffle(shuffled, new SecureRandom());
    // Now sort them according to the item comparator, {@link PendingMutation#compareTo(Object)}.
    List<PendingMutation<? extends Model>> actualOrder = new ArrayList<>(shuffled);
    Collections.sort(actualOrder);
    assertEquals(expectedOrder, actualOrder);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) Post(com.amplifyframework.testmodels.commentsblog.Post) Model(com.amplifyframework.core.model.Model) ArrayList(java.util.ArrayList) SecureRandom(java.security.SecureRandom) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Test(org.junit.Test)

Example 18 with ModelSchema

use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.

the class InMemoryStorageAdapter method delete.

// item.getClass() -> Class<?>, but type is T. So cast as Class<T> is OK.
@SuppressWarnings("unchecked")
@Override
public <T extends Model> void delete(@NonNull final T item, @NonNull final StorageItemChange.Initiator initiator, @NonNull final QueryPredicate predicate, @NonNull final Consumer<StorageItemChange<T>> onSuccess, @NonNull final Consumer<DataStoreException> onError) {
    final int index = indexOf(item);
    if (index < 0) {
        onError.accept(new DataStoreException("This item was not found in the datastore: " + item.toString(), "Use save() function to create models to store."));
        return;
    }
    Model savedItem = items.remove(index);
    final ModelSchema schema;
    final SerializedModel patchItem;
    try {
        schema = ModelSchema.fromModelClass(item.getClass());
        patchItem = SerializedModel.create(savedItem, schema);
    } catch (AmplifyException schemaBuildFailure) {
        onError.accept(new DataStoreException("Failed to build model schema.", schemaBuildFailure, "Verify your model."));
        return;
    }
    if (!predicate.evaluate(savedItem)) {
        onError.accept(new DataStoreException("Conditional check failed.", "Verify that there is a saved model that matches the provided predicate."));
        return;
    }
    StorageItemChange<T> deletion = StorageItemChange.<T>builder().item((T) savedItem).patchItem(patchItem).modelSchema(schema).type(StorageItemChange.Type.DELETE).predicate(predicate).initiator(initiator).build();
    itemChangeStream.onNext(deletion);
    onSuccess.accept(deletion);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) AmplifyException(com.amplifyframework.AmplifyException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) SerializedModel(com.amplifyframework.core.model.SerializedModel)

Example 19 with ModelSchema

use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.

the class InMemoryStorageAdapter method save.

@Override
public <T extends Model> void save(@NonNull final T item, @NonNull final StorageItemChange.Initiator initiator, @NonNull final QueryPredicate predicate, @NonNull final Consumer<StorageItemChange<T>> onSuccess, @NonNull final Consumer<DataStoreException> onError) {
    StorageItemChange.Type type = StorageItemChange.Type.CREATE;
    final int index = indexOf(item);
    Model savedItem = null;
    if (index > -1) {
        // There is an existing record with that ID; this is an update.
        type = StorageItemChange.Type.UPDATE;
        savedItem = items.get(index);
        if (!predicate.evaluate(savedItem)) {
            onError.accept(new DataStoreException("Conditional check failed.", "Verify that there is a saved model that matches the provided predicate."));
            return;
        } else {
            items.remove(index);
        }
    }
    final ModelSchema schema;
    final SerializedModel patchItem;
    try {
        schema = ModelSchema.fromModelClass(item.getClass());
        patchItem = SerializedModel.difference(item, savedItem, schema);
    } catch (AmplifyException schemaBuildFailure) {
        onError.accept(new DataStoreException("Failed to build model schema.", schemaBuildFailure, "Verify your model."));
        return;
    }
    items.add(item);
    StorageItemChange<T> change = StorageItemChange.<T>builder().item(item).patchItem(patchItem).modelSchema(schema).type(type).predicate(predicate).initiator(initiator).build();
    itemChangeStream.onNext(change);
    onSuccess.accept(change);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) AmplifyException(com.amplifyframework.AmplifyException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) SerializedModel(com.amplifyframework.core.model.SerializedModel)

Example 20 with ModelSchema

use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.

the class ObserveQueryExecutorTest method observeQueryReturnsRecordsBasedOnMaxTime.

/**
 * observe Query Returns batched Records Based On MaxTime.
 * @throws InterruptedException InterruptedException
 * @throws DataStoreException DataStoreException
 */
@Test
public void observeQueryReturnsRecordsBasedOnMaxTime() throws InterruptedException, DataStoreException {
    CountDownLatch latch = new CountDownLatch(1);
    CountDownLatch changeLatch = new CountDownLatch(1);
    AtomicInteger count = new AtomicInteger();
    BlogOwner blogOwner = BlogOwner.builder().name("Alan Turing").build();
    List<BlogOwner> datastoreResultList = new ArrayList<>();
    int maxRecords = 50;
    datastoreResultList.add(blogOwner);
    Consumer<Cancelable> observationStarted = NoOpConsumer.create();
    SyncStatus mockSyncStatus = mock(SyncStatus.class);
    when(mockSyncStatus.get(any(), any())).thenReturn(false);
    Subject<StorageItemChange<? extends Model>> subject = PublishSubject.<StorageItemChange<? extends Model>>create().toSerialized();
    Consumer<DataStoreQuerySnapshot<BlogOwner>> onQuerySnapshot = value -> {
        if (count.get() == 0) {
            Assert.assertTrue(value.getItems().contains(blogOwner));
            latch.countDown();
        } else if (count.get() == 1) {
            Assert.assertEquals(6, value.getItems().size());
            changeLatch.countDown();
        }
        count.getAndIncrement();
    };
    Consumer<DataStoreException> onObservationError = NoOpConsumer.create();
    Action onObservationComplete = () -> {
    };
    SqlQueryProcessor mockSqlQueryProcessor = mock(SqlQueryProcessor.class);
    when(mockSqlQueryProcessor.queryOfflineData(eq(BlogOwner.class), any(), any())).thenReturn(datastoreResultList);
    when(mockSqlQueryProcessor.modelExists(any(), any())).thenReturn(true);
    ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 5);
    ObserveQueryExecutor<BlogOwner> observeQueryExecutor = new ObserveQueryExecutor<>(subject, mockSqlQueryProcessor, threadPool, mockSyncStatus, new ModelSorter<>(), maxRecords, 1);
    observeQueryExecutor.observeQuery(BlogOwner.class, new ObserveQueryOptions(), observationStarted, onQuerySnapshot, onObservationError, onObservationComplete);
    Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
    for (int i = 0; i < 5; i++) {
        BlogOwner itemChange = BlogOwner.builder().name("Alan Turing" + i).build();
        try {
            subject.onNext(StorageItemChange.<BlogOwner>builder().changeId(UUID.randomUUID().toString()).initiator(StorageItemChange.Initiator.SYNC_ENGINE).item(itemChange).patchItem(SerializedModel.create(itemChange, ModelSchema.fromModelClass(BlogOwner.class))).modelSchema(ModelSchema.fromModelClass(BlogOwner.class)).predicate(QueryPredicates.all()).type(StorageItemChange.Type.UPDATE).build());
        } catch (AmplifyException exception) {
            exception.printStackTrace();
        }
    }
    Assert.assertTrue(changeLatch.await(5, TimeUnit.SECONDS));
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Arrays(java.util.Arrays) AmplifyException(com.amplifyframework.AmplifyException) ObserveQueryOptions(com.amplifyframework.core.model.query.ObserveQueryOptions) QueryPredicates(com.amplifyframework.core.model.query.predicate.QueryPredicates) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) StorageItemChange(com.amplifyframework.datastore.storage.StorageItemChange) ArrayList(java.util.ArrayList) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) Consumer(com.amplifyframework.core.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PublishSubject(io.reactivex.rxjava3.subjects.PublishSubject) ModelSchema(com.amplifyframework.core.model.ModelSchema) Subject(io.reactivex.rxjava3.subjects.Subject) NoOpConsumer(com.amplifyframework.core.NoOpConsumer) PostStatus(com.amplifyframework.testmodels.commentsblog.PostStatus) ExecutorService(java.util.concurrent.ExecutorService) DataStoreQuerySnapshot(com.amplifyframework.datastore.DataStoreQuerySnapshot) DataStoreConfiguration(com.amplifyframework.datastore.DataStoreConfiguration) SerializedModel(com.amplifyframework.core.model.SerializedModel) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Model(com.amplifyframework.core.model.Model) Test(org.junit.Test) Action(com.amplifyframework.core.Action) UUID(java.util.UUID) Mockito.when(org.mockito.Mockito.when) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) DataStoreException(com.amplifyframework.datastore.DataStoreException) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Cancelable(com.amplifyframework.core.async.Cancelable) QuerySortBy(com.amplifyframework.core.model.query.QuerySortBy) Assert(org.junit.Assert) Comparator(java.util.Comparator) NoOpAction(com.amplifyframework.core.NoOpAction) Post(com.amplifyframework.testmodels.commentsblog.Post) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) Mockito.mock(org.mockito.Mockito.mock) Action(com.amplifyframework.core.Action) NoOpAction(com.amplifyframework.core.NoOpAction) AmplifyException(com.amplifyframework.AmplifyException) ArrayList(java.util.ArrayList) ObserveQueryOptions(com.amplifyframework.core.model.query.ObserveQueryOptions) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Cancelable(com.amplifyframework.core.async.Cancelable) DataStoreException(com.amplifyframework.datastore.DataStoreException) StorageItemChange(com.amplifyframework.datastore.storage.StorageItemChange) CountDownLatch(java.util.concurrent.CountDownLatch) DataStoreQuerySnapshot(com.amplifyframework.datastore.DataStoreQuerySnapshot) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) ExecutorService(java.util.concurrent.ExecutorService) Test(org.junit.Test)

Aggregations

ModelSchema (com.amplifyframework.core.model.ModelSchema)109 Test (org.junit.Test)69 SerializedModel (com.amplifyframework.core.model.SerializedModel)34 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)30 Model (com.amplifyframework.core.model.Model)28 DataStoreException (com.amplifyframework.datastore.DataStoreException)26 HashMap (java.util.HashMap)23 ArrayList (java.util.ArrayList)22 SchemaRegistry (com.amplifyframework.core.model.SchemaRegistry)21 AmplifyException (com.amplifyframework.AmplifyException)19 Consumer (com.amplifyframework.core.Consumer)19 List (java.util.List)17 NonNull (androidx.annotation.NonNull)14 Cancelable (com.amplifyframework.core.async.Cancelable)14 TimeUnit (java.util.concurrent.TimeUnit)14 QueryPredicate (com.amplifyframework.core.model.query.predicate.QueryPredicate)13 Action (com.amplifyframework.core.Action)12 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)12 Collections (java.util.Collections)12 ModelProvider (com.amplifyframework.core.model.ModelProvider)11