Search in sources :

Example 11 with DataStoreException

use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.

the class ObserveQueryExecutorTest method observeQueryReturnsSortedListOfTotalItems.

/**
 * observe Query Returns Sorted List Of Total Items.
 * @throws InterruptedException InterruptedException
 * @throws DataStoreException DataStoreException
 */
@Test
public void observeQueryReturnsSortedListOfTotalItems() throws InterruptedException, DataStoreException {
    CountDownLatch latch = new CountDownLatch(1);
    CountDownLatch changeLatch = new CountDownLatch(1);
    AtomicInteger count = new AtomicInteger();
    List<String> names = Arrays.asList("John", "Jacob", "Joe", "Bob", "Bobby", "Bobb", "Dan", "Dany", "Daniel");
    List<String> weas = Arrays.asList("pon", "lth", "ver", "kly", "ken", "sel", "ner", "rer", "ned");
    List<BlogOwner> owners = new ArrayList<>();
    for (int i = 0; i < names.size() / 2; i++) {
        BlogOwner owner = BlogOwner.builder().name(names.get(i)).wea(weas.get(i)).build();
        owners.add(owner);
    }
    int maxRecords = 50;
    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(owners.get(0)));
            latch.countDown();
        } else if (count.get() == 1) {
            List<BlogOwner> sorted = new ArrayList<>(owners);
            Collections.sort(sorted, Comparator.comparing(BlogOwner::getName).reversed().thenComparing(BlogOwner::getWea));
            assertEquals(sorted, value.getItems());
            Assert.assertEquals(8, 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(owners);
    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);
    List<QuerySortBy> sortBy = new ArrayList<>();
    sortBy.add(BlogOwner.NAME.descending());
    sortBy.add(BlogOwner.WEA.ascending());
    observeQueryExecutor.observeQuery(BlogOwner.class, new ObserveQueryOptions(null, sortBy), observationStarted, onQuerySnapshot, onObservationError, onObservationComplete);
    Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
    for (int i = (names.size() / 2) + 1; i < names.size(); i++) {
        BlogOwner itemChange = BlogOwner.builder().name(names.get(i)).wea(weas.get(i)).build();
        owners.add(itemChange);
        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.CREATE).build());
        } catch (AmplifyException exception) {
            exception.printStackTrace();
        }
    }
    Assert.assertTrue(changeLatch.await(7, 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) QuerySortBy(com.amplifyframework.core.model.query.QuerySortBy) 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)

Example 12 with DataStoreException

use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.

the class VersionRepositoryTest method emitsErrorForNoMetadataInRepo.

/**
 * When you try to get a model version, but there's no metadata for that model,
 * this should fail with an {@link DataStoreException}.
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void emitsErrorForNoMetadataInRepo() throws InterruptedException {
    // Arrange: no metadata is in the repo.
    BlogOwner blogOwner = BlogOwner.builder().name("Jameson Williams").build();
    // Note that this line is NOT executed in arrangement.
    // ModelMetadata metadata = new ModelMetadata(blogOwner.getId(), false, 1, Time.now());
    // putInStore(blogOwner blogOwner);
    // Act: try to lookup the metadata. Is it going to work? Duh.
    TestObserver<Integer> observer = versionRepository.findModelVersion(blogOwner).test();
    assertTrue(observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS));
    // Assert: this failed. There was no version available.
    observer.assertError(error -> {
        if (!(error instanceof DataStoreException)) {
            return false;
        }
        String expectedMessage = String.format(Locale.US, "Wanted 1 metadata for item with id = %s, but had 0.", blogOwner.getId());
        return expectedMessage.equals(error.getMessage());
    });
}
Also used : DataStoreException(com.amplifyframework.datastore.DataStoreException) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Test(org.junit.Test)

Example 13 with DataStoreException

use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.

the class SQLiteStorageAdapter method query.

/**
 * {@inheritDoc}
 */
@Override
public void query(@NonNull String modelName, @NonNull QueryOptions options, @NonNull Consumer<Iterator<? extends Model>> onSuccess, @NonNull Consumer<DataStoreException> onError) {
    Objects.requireNonNull(modelName);
    Objects.requireNonNull(options);
    Objects.requireNonNull(onSuccess);
    Objects.requireNonNull(onError);
    threadPool.submit(() -> {
        final ModelSchema modelSchema = schemaRegistry.getModelSchemaForModelClass(modelName);
        try (Cursor cursor = sqlCommandProcessor.rawQuery(sqlCommandFactory.queryFor(modelSchema, options))) {
            LOG.debug("Querying item for: " + modelName);
            final List<Model> models = new ArrayList<>();
            final SQLiteModelFieldTypeConverter converter = new SQLiteModelFieldTypeConverter(modelSchema, schemaRegistry, gson);
            if (cursor == null) {
                onError.accept(new DataStoreException("Error in getting a cursor to the table for class: " + modelName, AmplifyException.TODO_RECOVERY_SUGGESTION));
                return;
            }
            if (cursor.moveToFirst()) {
                do {
                    final Map<String, Object> data = converter.buildMapForModel(cursor);
                    final SerializedModel model = createSerializedModel(modelSchema, data);
                    models.add(model);
                } while (cursor.moveToNext());
            }
            onSuccess.accept(models.iterator());
        } catch (Exception exception) {
            onError.accept(new DataStoreException("Error in querying the model.", exception, "See attached exception for details."));
        }
    });
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) SerializedModel(com.amplifyframework.core.model.SerializedModel) AmplifyException(com.amplifyframework.AmplifyException) DataStoreException(com.amplifyframework.datastore.DataStoreException)

Example 14 with DataStoreException

use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.

the class SQLiteStorageAdapter method delete.

/**
 * {@inheritDoc}
 */
@Override
public <T extends Model> void delete(@NonNull T item, @NonNull StorageItemChange.Initiator initiator, @NonNull QueryPredicate predicate, @NonNull Consumer<StorageItemChange<T>> onSuccess, @NonNull Consumer<DataStoreException> onError) {
    Objects.requireNonNull(item);
    Objects.requireNonNull(initiator);
    Objects.requireNonNull(predicate);
    Objects.requireNonNull(onSuccess);
    Objects.requireNonNull(onError);
    threadPool.submit(() -> {
        try {
            final String modelName = item.getModelName();
            final ModelSchema modelSchema = schemaRegistry.getModelSchemaForModelClass(modelName);
            // Check if data being deleted exists; "Succeed" deletion in that case.
            if (!sqlQueryProcessor.modelExists(item, QueryPredicates.all())) {
                LOG.verbose(modelName + " model with id = " + item.getId() + " does not exist.");
                // Pass back item change instance without publishing it.
                onSuccess.accept(StorageItemChange.<T>builder().item(item).patchItem(SerializedModel.create(item, modelSchema)).modelSchema(modelSchema).type(StorageItemChange.Type.DELETE).predicate(predicate).initiator(initiator).build());
                return;
            }
            // Check if existing data meets the condition, only if a condition other than all() was provided.
            if (!QueryPredicates.all().equals(predicate) && !sqlQueryProcessor.modelExists(item, predicate)) {
                throw new DataStoreException("Deletion failed because condition did not match existing model instance.", "The deletion will continue to fail until the model instance is updated.");
            }
            // identify items affected by cascading delete before deleting them
            List<Model> cascadedModels = sqliteModelTree.descendantsOf(Collections.singleton(item));
            // execute local deletion
            writeData(item, StorageItemChange.Type.DELETE);
            // publish cascaded deletions
            for (Model cascadedModel : cascadedModels) {
                ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(cascadedModel.getModelName());
                itemChangeSubject.onNext(StorageItemChange.builder().item(cascadedModel).patchItem(SerializedModel.create(cascadedModel, schema)).modelSchema(schema).type(StorageItemChange.Type.DELETE).predicate(QueryPredicates.all()).initiator(initiator).build());
            }
            // publish successful deletion of top-level item
            StorageItemChange<T> change = StorageItemChange.<T>builder().item(item).patchItem(SerializedModel.create(item, modelSchema)).modelSchema(modelSchema).type(StorageItemChange.Type.DELETE).predicate(predicate).initiator(initiator).build();
            itemChangeSubject.onNext(change);
            onSuccess.accept(change);
        } catch (DataStoreException dataStoreException) {
            onError.accept(dataStoreException);
        } catch (Exception someOtherTypeOfException) {
            DataStoreException dataStoreException = new DataStoreException("Error in deleting the model.", someOtherTypeOfException, "See attached exception for details.");
            onError.accept(dataStoreException);
        }
    });
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) AmplifyException(com.amplifyframework.AmplifyException) DataStoreException(com.amplifyframework.datastore.DataStoreException)

Example 15 with DataStoreException

use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.

the class SQLiteStorageAdapter method observe.

/**
 * {@inheritDoc}
 */
@NonNull
@Override
public Cancelable observe(@NonNull Consumer<StorageItemChange<? extends Model>> onItemChanged, @NonNull Consumer<DataStoreException> onObservationError, @NonNull Action onObservationComplete) {
    Objects.requireNonNull(onItemChanged);
    Objects.requireNonNull(onObservationError);
    Objects.requireNonNull(onObservationComplete);
    Disposable disposable = itemChangeSubject.subscribe(onItemChanged::accept, failure -> {
        if (failure instanceof DataStoreException) {
            onObservationError.accept((DataStoreException) failure);
            return;
        }
        onObservationError.accept(new DataStoreException("Failed to observe items in storage adapter.", failure, "Inspect the failure details."));
    }, onObservationComplete::call);
    return disposable::dispose;
}
Also used : Disposable(io.reactivex.rxjava3.disposables.Disposable) CompositeDisposable(io.reactivex.rxjava3.disposables.CompositeDisposable) DataStoreException(com.amplifyframework.datastore.DataStoreException) NonNull(androidx.annotation.NonNull)

Aggregations

DataStoreException (com.amplifyframework.datastore.DataStoreException)89 Test (org.junit.Test)52 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)36 Consumer (com.amplifyframework.core.Consumer)32 List (java.util.List)32 Cancelable (com.amplifyframework.core.async.Cancelable)31 Model (com.amplifyframework.core.model.Model)31 ArrayList (java.util.ArrayList)31 AmplifyException (com.amplifyframework.AmplifyException)29 ModelSchema (com.amplifyframework.core.model.ModelSchema)28 Collections (java.util.Collections)28 Action (com.amplifyframework.core.Action)27 QueryPredicate (com.amplifyframework.core.model.query.predicate.QueryPredicate)27 TimeUnit (java.util.concurrent.TimeUnit)25 Post (com.amplifyframework.testmodels.commentsblog.Post)23 PostStatus (com.amplifyframework.testmodels.commentsblog.PostStatus)23 Arrays (java.util.Arrays)23 Assert.assertEquals (org.junit.Assert.assertEquals)23 ObserveQueryOptions (com.amplifyframework.core.model.query.ObserveQueryOptions)22 DataStoreQuerySnapshot (com.amplifyframework.datastore.DataStoreQuerySnapshot)21