Search in sources :

Example 21 with DataStoreException

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

the class AppSyncClientTest method validateBaseSyncQueryGen.

/**
 * Validates the construction of a base-sync query.
 * @throws JSONException On bad request JSON found in API category call
 * @throws DataStoreException If no valid response returned from AppSync endpoint during sync
 * @throws AmplifyException On failure to arrange model schema
 */
@Test
public void validateBaseSyncQueryGen() throws JSONException, AmplifyException {
    ModelSchema schema = ModelSchema.fromModelClass(BlogOwner.class);
    Await.result((Consumer<GraphQLResponse<PaginatedResult<ModelWithMetadata<BlogOwner>>>> onResult, Consumer<DataStoreException> onError) -> {
        try {
            GraphQLRequest<PaginatedResult<ModelWithMetadata<BlogOwner>>> request = endpoint.buildSyncRequest(schema, null, null, QueryPredicates.all());
            endpoint.sync(request, onResult, onError);
        } catch (DataStoreException datastoreException) {
            onError.accept(datastoreException);
        }
    });
    // Now, capture the request argument on API, so we can see what was passed.
    // Recall that we pass a raw doc to API.
    ArgumentCaptor<GraphQLRequest<ModelWithMetadata<BlogOwner>>> requestCaptor = ArgumentCaptor.forClass(GraphQLRequest.class);
    verify(api).query(requestCaptor.capture(), any(Consumer.class), any(Consumer.class));
    GraphQLRequest<ModelWithMetadata<BlogOwner>> capturedRequest = requestCaptor.getValue();
    Type type = TypeMaker.getParameterizedType(PaginatedResult.class, ModelWithMetadata.class, BlogOwner.class);
    assertEquals(type, capturedRequest.getResponseType());
    // The request was sent as JSON. It has a null variables field, and a present query field.
    JSONAssert.assertEquals(Resources.readAsString("base-sync-request-document-for-blog-owner.txt"), capturedRequest.getContent(), true);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) GraphQLRequest(com.amplifyframework.api.graphql.GraphQLRequest) DataStoreException(com.amplifyframework.datastore.DataStoreException) Type(java.lang.reflect.Type) Consumer(com.amplifyframework.core.Consumer) PaginatedResult(com.amplifyframework.api.graphql.PaginatedResult) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Test(org.junit.Test)

Example 22 with DataStoreException

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

the class SyncProcessor method syncModel.

/**
 * Sync models for a given model class.
 * This involves three steps:
 *  1. Lookup the last time the model class was synced;
 *  2. Make a request to the AppSync endpoint. If the last sync time is within a recent window
 *     of time, then request a *delta* sync. If the last sync time is outside a recent window of time,
 *     perform a *base* sync. A base sync is preformed by passing null.
 *  3. Continue fetching paged results until !hasNextResult() or we have synced the max records.
 *
 * @param schema The schema of the model to sync
 * @param syncTime The time of a last successful sync.
 * @param <T> The type of model to sync.
 * @return a stream of all ModelWithMetadata&lt;T&gt; objects from all pages for the provided model.
 * @throws DataStoreException if dataStoreConfigurationProvider.getConfiguration() fails
 */
private <T extends Model> Flowable<List<ModelWithMetadata<T>>> syncModel(ModelSchema schema, SyncTime syncTime) throws DataStoreException {
    final Long lastSyncTimeAsLong = syncTime.exists() ? syncTime.toLong() : null;
    final Integer syncPageSize = dataStoreConfigurationProvider.getConfiguration().getSyncPageSize();
    final Integer syncMaxRecords = dataStoreConfigurationProvider.getConfiguration().getSyncMaxRecords();
    AtomicReference<Integer> recordsFetched = new AtomicReference<>(0);
    QueryPredicate predicate = queryPredicateProvider.getPredicate(schema.getName());
    // Create a BehaviorProcessor, and set the default value to a GraphQLRequest that fetches the first page.
    BehaviorProcessor<GraphQLRequest<PaginatedResult<ModelWithMetadata<T>>>> processor = BehaviorProcessor.createDefault(appSync.buildSyncRequest(schema, lastSyncTimeAsLong, syncPageSize, predicate));
    return processor.concatMap(request -> {
        if (isSyncRetryEnabled) {
            return syncPageWithRetry(request).toFlowable();
        } else {
            return syncPage(request).toFlowable();
        }
    }).doOnNext(paginatedResult -> {
        if (paginatedResult.hasNextResult()) {
            processor.onNext(paginatedResult.getRequestForNextResult());
        } else {
            processor.onComplete();
        }
    }).map(paginatedResult -> Flowable.fromIterable(paginatedResult).map(modelWithMetadata -> hydrateSchemaIfNeeded(modelWithMetadata, schema)).toList().blockingGet()).takeUntil(items -> recordsFetched.accumulateAndGet(items.size(), Integer::sum) >= syncMaxRecords);
}
Also used : DataStoreConfigurationProvider(com.amplifyframework.datastore.DataStoreConfigurationProvider) Single(io.reactivex.rxjava3.core.Single) DataStoreErrorHandler(com.amplifyframework.datastore.DataStoreErrorHandler) BehaviorProcessor(io.reactivex.rxjava3.processors.BehaviorProcessor) NonNull(androidx.annotation.NonNull) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) GraphQLRequest(com.amplifyframework.api.graphql.GraphQLRequest) ModelProvider(com.amplifyframework.core.model.ModelProvider) DataStoreChannelEventName(com.amplifyframework.datastore.DataStoreChannelEventName) AppSync(com.amplifyframework.datastore.appsync.AppSync) SyncQueriesStartedEvent(com.amplifyframework.datastore.events.SyncQueriesStartedEvent) AtomicReference(java.util.concurrent.atomic.AtomicReference) ApiException(com.amplifyframework.api.ApiException) ArrayList(java.util.ArrayList) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) Time(com.amplifyframework.util.Time) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) Consumer(com.amplifyframework.core.Consumer) ModelSchema(com.amplifyframework.core.model.ModelSchema) PaginatedResult(com.amplifyframework.api.graphql.PaginatedResult) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) HubEvent(com.amplifyframework.hub.HubEvent) Amplify(com.amplifyframework.core.Amplify) Flowable(io.reactivex.rxjava3.core.Flowable) HubChannel(com.amplifyframework.hub.HubChannel) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) Completable(io.reactivex.rxjava3.core.Completable) Logger(com.amplifyframework.logging.Logger) Objects(java.util.Objects) DataStoreException(com.amplifyframework.datastore.DataStoreException) List(java.util.List) Cancelable(com.amplifyframework.core.async.Cancelable) AmplifyDisposables(com.amplifyframework.datastore.AmplifyDisposables) ForEach(com.amplifyframework.util.ForEach) Collections(java.util.Collections) GraphQLRequest(com.amplifyframework.api.graphql.GraphQLRequest) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Example 23 with DataStoreException

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

the class SyncProcessor method syncPage.

/**
 * Fetches one page for a sync.
 * @param request GraphQLRequest object for the sync, obtained from {@link AppSync#buildSyncRequest}, or from
 *                response.getData().getRequestForNextResult() for subsequent requests.
 * @param <T> The type of model to sync.
 */
private <T extends Model> Single<PaginatedResult<ModelWithMetadata<T>>> syncPage(GraphQLRequest<PaginatedResult<ModelWithMetadata<T>>> request) {
    return Single.create(emitter -> {
        Cancelable cancelable = appSync.sync(request, result -> {
            if (result.hasErrors()) {
                emitter.onError(new DataStoreException(String.format("A model sync failed: %s", result.getErrors()), "Check your schema."));
            } else if (!result.hasData()) {
                emitter.onError(new DataStoreException.IrRecoverableException("Empty response from AppSync.", "Report to AWS team."));
            } else {
                emitter.onSuccess(result.getData());
            }
        }, emitter::onError);
        emitter.setDisposable(AmplifyDisposables.fromCancelable(cancelable));
    });
}
Also used : DataStoreException(com.amplifyframework.datastore.DataStoreException) Cancelable(com.amplifyframework.core.async.Cancelable)

Example 24 with DataStoreException

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

the class SQLPredicate method parsePredicateOperation.

@SuppressWarnings("fallthrough")
private // Utility method to recursively parse a given predicate operation.
StringBuilder parsePredicateOperation(QueryPredicateOperation<?> operation) throws DataStoreException {
    final StringBuilder builder = new StringBuilder();
    final String model = Wrap.inBackticks(operation.modelName());
    final String field = Wrap.inBackticks(operation.field());
    final String column = model == null ? operation.field() : model + "." + field;
    final QueryOperator<?> op = operation.operator();
    switch(op.type()) {
        case BETWEEN:
            BetweenQueryOperator<?> betweenOp = (BetweenQueryOperator<?>) op;
            addBinding(betweenOp.start());
            addBinding(betweenOp.end());
            return builder.append(column).append(SqlKeyword.DELIMITER).append(SqlKeyword.BETWEEN).append(SqlKeyword.DELIMITER).append("?").append(SqlKeyword.DELIMITER).append(SqlKeyword.AND).append(SqlKeyword.DELIMITER).append("?");
        case CONTAINS:
            ContainsQueryOperator containsOp = (ContainsQueryOperator) op;
            addBinding(containsOp.value());
            return builder.append("instr(").append(column).append(",").append("?").append(")").append(SqlKeyword.DELIMITER).append(SqlKeyword.fromQueryOperator(QueryOperator.Type.GREATER_THAN)).append(SqlKeyword.DELIMITER).append("0");
        case NOT_CONTAINS:
            NotContainsQueryOperator notContainsOp = (NotContainsQueryOperator) op;
            addBinding(notContainsOp.value());
            return builder.append("instr(").append(column).append(",").append("?").append(")").append(SqlKeyword.DELIMITER).append(SqlKeyword.fromQueryOperator(QueryOperator.Type.EQUAL)).append(SqlKeyword.DELIMITER).append("0");
        case BEGINS_WITH:
            BeginsWithQueryOperator beginsWithOp = (BeginsWithQueryOperator) op;
            addBinding(beginsWithOp.value() + "%");
            return builder.append(column).append(SqlKeyword.DELIMITER).append(SqlKeyword.LIKE).append(SqlKeyword.DELIMITER).append("?");
        case EQUAL:
        case NOT_EQUAL:
            Object operatorValue = getOperatorValue(op);
            if (operatorValue == null) {
                SqlKeyword sqlNullCheck = op.type() == QueryOperator.Type.EQUAL ? SqlKeyword.IS_NULL : SqlKeyword.IS_NOT_NULL;
                return builder.append(column).append(SqlKeyword.DELIMITER).append(sqlNullCheck.toString());
            }
        case LESS_THAN:
        case GREATER_THAN:
        case LESS_OR_EQUAL:
        case GREATER_OR_EQUAL:
            addBinding(getOperatorValue(op));
            return builder.append(column).append(SqlKeyword.DELIMITER).append(SqlKeyword.fromQueryOperator(op.type())).append(SqlKeyword.DELIMITER).append("?");
        default:
            throw new DataStoreException("Tried to parse an unsupported QueryPredicateOperation", "Try changing to one of the supported values from " + "QueryPredicateOperation.Type enum.");
    }
}
Also used : BeginsWithQueryOperator(com.amplifyframework.core.model.query.predicate.BeginsWithQueryOperator) DataStoreException(com.amplifyframework.datastore.DataStoreException) BetweenQueryOperator(com.amplifyframework.core.model.query.predicate.BetweenQueryOperator) SqlKeyword(com.amplifyframework.datastore.storage.sqlite.SqlKeyword) ContainsQueryOperator(com.amplifyframework.core.model.query.predicate.ContainsQueryOperator) NotContainsQueryOperator(com.amplifyframework.core.model.query.predicate.NotContainsQueryOperator) NotContainsQueryOperator(com.amplifyframework.core.model.query.predicate.NotContainsQueryOperator)

Example 25 with DataStoreException

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

the class GsonPendingMutationConverter method fromRecord.

@NonNull
@Override
public <T extends Model> PendingMutation<T> fromRecord(@NonNull PendingMutation.PersistentRecord record) throws DataStoreException {
    final Class<?> itemClass;
    try {
        itemClass = Class.forName(record.getContainedModelClassName());
    } catch (ClassNotFoundException classNotFoundException) {
        throw new DataStoreException("Could not find a class with the name " + record.getContainedModelClassName(), classNotFoundException, "Verify that you have built this model into your project.");
    }
    final Type itemType = TypeToken.getParameterized(PendingMutation.class, itemClass).getType();
    return gson.fromJson(record.getSerializedMutationData(), itemType);
}
Also used : DataStoreException(com.amplifyframework.datastore.DataStoreException) Type(java.lang.reflect.Type) 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