Search in sources :

Example 6 with SubscriptionType

use of com.amplifyframework.api.graphql.SubscriptionType in project amplify-android by aws-amplify.

the class AuthRuleRequestDecoratorTest method requestPassThroughForNoAuth.

/**
 * Test that auth rule request decorator returns the same request if there
 * is no auth rule associated with it.
 * @throws AmplifyException if a ModelSchema can't be derived from the Model class.
 */
@Test
public void requestPassThroughForNoAuth() throws AmplifyException {
    final AuthorizationType mode = AuthorizationType.AMAZON_COGNITO_USER_POOLS;
    // NoAuth class does not have use @auth directive
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<NoAuth> originalRequest = createRequest(NoAuth.class, subscriptionType);
        GraphQLRequest<NoAuth> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertEquals(originalRequest, modifiedRequest);
    }
}
Also used : SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) AuthorizationType(com.amplifyframework.api.aws.AuthorizationType) Test(org.junit.Test)

Example 7 with SubscriptionType

use of com.amplifyframework.api.graphql.SubscriptionType in project amplify-android by aws-amplify.

the class AuthRuleRequestDecoratorTest method ownerArgumentNotAddedIfOwnerIsInCustomGroup.

/**
 * Verify owner argument is NOT added if model contains both owner-based and group-based
 * authorization and the user is in any of the read-restricted groups.
 * @throws AmplifyException if a ModelSchema can't be derived from the Model class.
 */
@Test
public void ownerArgumentNotAddedIfOwnerIsInCustomGroup() throws AmplifyException {
    final AuthorizationType mode = AuthorizationType.OPENID_CONNECT;
    // and user is in the read-restricted custom group.
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<OwnerInCustomGroup> originalRequest = createRequest(OwnerInCustomGroup.class, subscriptionType);
        GraphQLRequest<OwnerInCustomGroup> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertNull(getOwnerField(modifiedRequest));
    }
}
Also used : SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) AuthorizationType(com.amplifyframework.api.aws.AuthorizationType) Test(org.junit.Test)

Example 8 with SubscriptionType

use of com.amplifyframework.api.graphql.SubscriptionType in project amplify-android by aws-amplify.

the class AuthRuleRequestDecoratorTest method ownerArgumentNotAddedForNonOwnerBasedAuth.

/**
 * Verify owner argument is NOT added if authStrategy is not OWNER.
 * @throws AmplifyException if a ModelSchema can't be derived from the Model class.
 */
@Test
public void ownerArgumentNotAddedForNonOwnerBasedAuth() throws AmplifyException {
    final AuthorizationType mode = AuthorizationType.AMAZON_COGNITO_USER_POOLS;
    // Public class opens up every operation to the public
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<Public> originalRequest = createRequest(Public.class, subscriptionType);
        GraphQLRequest<Public> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertNull(getOwnerField(modifiedRequest));
    }
    // Private class only allows the correct IAM user
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<Private> originalRequest = createRequest(Private.class, subscriptionType);
        GraphQLRequest<Private> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertNull(getOwnerField(modifiedRequest));
    }
    // Group class only has group-based auth enabled
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<Group> originalRequest = createRequest(Group.class, subscriptionType);
        GraphQLRequest<Group> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertNull(getOwnerField(modifiedRequest));
    }
    // Custom auth with function provider does not add owner field.
    for (SubscriptionType subscriptionType : SubscriptionType.values()) {
        GraphQLRequest<CustomFunction> originalRequest = createRequest(CustomFunction.class, subscriptionType);
        GraphQLRequest<CustomFunction> modifiedRequest = decorator.decorate(originalRequest, mode);
        assertNull(getOwnerField(modifiedRequest));
    }
}
Also used : SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) AuthorizationType(com.amplifyframework.api.aws.AuthorizationType) Test(org.junit.Test)

Example 9 with SubscriptionType

use of com.amplifyframework.api.graphql.SubscriptionType in project amplify-android by aws-amplify.

the class SubscriptionProcessorTest method arrangeDataEmittingSubscription.

@SuppressWarnings("SameParameterValue")
private static <T extends Model> void arrangeDataEmittingSubscription(AppSync appSync, ModelSchema modelSchema, SubscriptionType subscriptionType, GraphQLResponse<ModelWithMetadata<T>> response) throws DataStoreException {
    Answer<Cancelable> answer = invocation -> {
        final int startConsumerIndex = 1;
        Consumer<String> onStart = invocation.getArgument(startConsumerIndex);
        onStart.accept(RandomString.string());
        final int dataConsumerIndex = 2;
        Consumer<GraphQLResponse<ModelWithMetadata<T>>> onData = invocation.getArgument(dataConsumerIndex);
        onData.accept(response);
        return new NoOpCancelable();
    };
    arrangeSubscription(appSync, answer, modelSchema, subscriptionType);
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ModelProvider(com.amplifyframework.core.model.ModelProvider) Pair(android.util.Pair) RunWith(org.junit.runner.RunWith) AppSync(com.amplifyframework.datastore.appsync.AppSync) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) Answer(org.mockito.stubbing.Answer) Consumer(com.amplifyframework.core.Consumer) SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) Observable(io.reactivex.rxjava3.core.Observable) Map(java.util.Map) Mockito.doAnswer(org.mockito.Mockito.doAnswer) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) ModelSchema(com.amplifyframework.core.model.ModelSchema) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) Before(org.junit.Before) DataStoreConfiguration(com.amplifyframework.datastore.DataStoreConfiguration) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Model(com.amplifyframework.core.model.Model) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Completable(io.reactivex.rxjava3.core.Completable) Action(com.amplifyframework.core.Action) RobolectricTestRunner(org.robolectric.RobolectricTestRunner) 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) Assert.assertFalse(org.junit.Assert.assertFalse) RandomString(com.amplifyframework.testutils.random.RandomString) Temporal(com.amplifyframework.core.model.temporal.Temporal) AmplifyModelProvider(com.amplifyframework.testmodels.commentsblog.AmplifyModelProvider) Collections(java.util.Collections) Mockito.mock(org.mockito.Mockito.mock) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) Consumer(com.amplifyframework.core.Consumer) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) Cancelable(com.amplifyframework.core.async.Cancelable)

Example 10 with SubscriptionType

use of com.amplifyframework.api.graphql.SubscriptionType in project amplify-android by aws-amplify.

the class SubscriptionProcessor method subscriptionObservable.

private <T extends Model> Observable<SubscriptionEvent<? extends Model>> subscriptionObservable(AppSync appSync, SubscriptionType subscriptionType, AbortableCountDownLatch<DataStoreException> latch, ModelSchema modelSchema) {
    return Observable.<GraphQLResponse<ModelWithMetadata<T>>>create(emitter -> {
        SubscriptionMethod method = subscriptionMethodFor(appSync, subscriptionType);
        AtomicReference<String> subscriptionId = new AtomicReference<>();
        Cancelable cancelable = method.subscribe(modelSchema, token -> {
            LOG.debug("Subscription started for " + subscriptionType.name() + " " + modelSchema.getName() + " subscriptionId: " + token);
            subscriptionId.set(token);
            latch.countDown();
        }, emitter::onNext, dataStoreException -> {
            if (isExceptionType(dataStoreException, AppSyncErrorType.UNAUTHORIZED)) {
                // Ignore Unauthorized errors, so that DataStore can still be used even if the user is only
                // authorized to read a subset of the models.
                latch.countDown();
                LOG.warn("Unauthorized failure:" + subscriptionType.name() + " " + modelSchema.getName());
            } else if (isExceptionType(dataStoreException, AppSyncErrorType.OPERATION_DISABLED)) {
                // Ignore OperationDisabled errors, so that DataStore can be used even without subscriptions.
                // This logic is only in place to address a specific use case, and should not be used without
                // unless you have consulted with AWS.  It is subject to be deprecated/removed in the future.
                latch.countDown();
                LOG.warn("Operation disabled:" + subscriptionType.name() + " " + modelSchema.getName());
            } else {
                if (latch.getCount() > 0) {
                    // An error occurred during startup.  Abort and notify the Orchestrator by throwing the
                    // exception from startSubscriptions.
                    latch.abort(dataStoreException);
                } else {
                    // An error occurred after startup. Notify the Orchestrator via the onFailure action.
                    onFailure.accept(dataStoreException);
                }
            }
        }, () -> {
            LOG.debug("Subscription completed:" + subscriptionId.get());
            emitter.onComplete();
        });
        // When the observable is disposed, we need to call cancel() on the subscription
        // so it can properly dispose of resources if necessary. For the AWS API plugin,
        // this means closing the underlying network connection.
        emitter.setDisposable(AmplifyDisposables.fromCancelable(cancelable));
    }).doOnError(subscriptionError -> LOG.warn("An error occurred on the remote " + subscriptionType.name() + " subscription for model " + modelSchema.getName(), subscriptionError)).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).map(SubscriptionProcessor::unwrapResponse).filter(modelWithMetadata -> {
        QueryPredicate predicate = queryPredicateProvider.getPredicate(modelSchema.getName());
        return predicate.evaluate(modelWithMetadata.getModel());
    }).map(modelWithMetadata -> SubscriptionEvent.<T>builder().type(fromSubscriptionType(subscriptionType)).modelWithMetadata(modelWithMetadata).modelSchema(modelSchema).build());
}
Also used : Arrays(java.util.Arrays) AmplifyException(com.amplifyframework.AmplifyException) NonNull(androidx.annotation.NonNull) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) ModelProvider(com.amplifyframework.core.model.ModelProvider) DataStoreChannelEventName(com.amplifyframework.datastore.DataStoreChannelEventName) AppSync(com.amplifyframework.datastore.appsync.AppSync) AtomicReference(java.util.concurrent.atomic.AtomicReference) Empty(com.amplifyframework.util.Empty) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) HashSet(java.util.HashSet) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) AppSyncExtensions(com.amplifyframework.datastore.appsync.AppSyncExtensions) Consumer(com.amplifyframework.core.Consumer) CompositeDisposable(io.reactivex.rxjava3.disposables.CompositeDisposable) SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) Locale(java.util.Locale) Observable(io.reactivex.rxjava3.core.Observable) ModelSchema(com.amplifyframework.core.model.ModelSchema) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) HubEvent(com.amplifyframework.hub.HubEvent) Amplify(com.amplifyframework.core.Amplify) HubChannel(com.amplifyframework.hub.HubChannel) SerializedModel(com.amplifyframework.core.model.SerializedModel) AppSyncErrorType(com.amplifyframework.datastore.appsync.AppSyncExtensions.AppSyncErrorType) Model(com.amplifyframework.core.model.Model) Set(java.util.Set) Completable(io.reactivex.rxjava3.core.Completable) Action(com.amplifyframework.core.Action) Logger(com.amplifyframework.logging.Logger) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) DataStoreException(com.amplifyframework.datastore.DataStoreException) List(java.util.List) Cancelable(com.amplifyframework.core.async.Cancelable) ReplaySubject(io.reactivex.rxjava3.subjects.ReplaySubject) AmplifyDisposables(com.amplifyframework.datastore.AmplifyDisposables) GraphQLResponseException(com.amplifyframework.datastore.DataStoreException.GraphQLResponseException) VisibleForTesting(androidx.annotation.VisibleForTesting) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) Cancelable(com.amplifyframework.core.async.Cancelable)

Aggregations

SubscriptionType (com.amplifyframework.api.graphql.SubscriptionType)15 Test (org.junit.Test)12 AuthorizationType (com.amplifyframework.api.aws.AuthorizationType)9 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)6 Action (com.amplifyframework.core.Action)6 Consumer (com.amplifyframework.core.Consumer)6 Cancelable (com.amplifyframework.core.async.Cancelable)6 Model (com.amplifyframework.core.model.Model)6 ModelSchema (com.amplifyframework.core.model.ModelSchema)6 DataStoreException (com.amplifyframework.datastore.DataStoreException)6 ModelProvider (com.amplifyframework.core.model.ModelProvider)5 SchemaRegistry (com.amplifyframework.core.model.SchemaRegistry)5 AppSync (com.amplifyframework.datastore.appsync.AppSync)5 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)5 Completable (io.reactivex.rxjava3.core.Completable)5 Observable (io.reactivex.rxjava3.core.Observable)5 List (java.util.List)5 TimeUnit (java.util.concurrent.TimeUnit)5 NoOpCancelable (com.amplifyframework.core.async.NoOpCancelable)4 NonNull (androidx.annotation.NonNull)3