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);
}
}
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));
}
}
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));
}
}
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);
}
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());
}
Aggregations