use of com.amplifyframework.datastore.appsync.AppSync in project amplify-android by aws-amplify.
the class SubscriptionProcessorTest method setup.
/**
* Sets up an {@link SubscriptionProcessor} and associated test dependencies.
* @throws DataStoreException on error building the {@link DataStoreConfiguration}
*/
@Before
public void setup() throws DataStoreException {
ModelProvider modelProvider = AmplifyModelProvider.getInstance();
schemaRegistry = SchemaRegistry.instance();
schemaRegistry.register(modelProvider.modelSchemas());
this.modelSchemas = sortedModels(modelProvider);
this.appSync = mock(AppSync.class);
this.merger = mock(Merger.class);
DataStoreConfiguration dataStoreConfiguration = DataStoreConfiguration.builder().syncExpression(BlogOwner.class, () -> BlogOwner.NAME.beginsWith("John")).build();
QueryPredicateProvider queryPredicateProvider = new QueryPredicateProvider(() -> dataStoreConfiguration);
queryPredicateProvider.resolvePredicates();
this.subscriptionProcessor = SubscriptionProcessor.builder().appSync(appSync).modelProvider(modelProvider).schemaRegistry(schemaRegistry).merger(merger).queryPredicateProvider(queryPredicateProvider).onFailure(throwable -> {
}).build();
}
use of com.amplifyframework.datastore.appsync.AppSync in project amplify-android by aws-amplify.
the class SubscriptionProcessorTest method arrangeStartedSubscriptions.
private static void arrangeStartedSubscriptions(AppSync appSync, List<ModelSchema> modelSchemas, SubscriptionType[] subscriptionTypes) {
Answer<Cancelable> answer = invocation -> {
final int startConsumerIndex = 1;
Consumer<String> onStart = invocation.getArgument(startConsumerIndex);
onStart.accept(RandomString.string());
return new NoOpCancelable();
};
arrangeSubscriptions(appSync, answer, modelSchemas, subscriptionTypes);
}
use of com.amplifyframework.datastore.appsync.AppSync in project amplify-android by aws-amplify.
the class SubscriptionProcessorTest method appSyncInvokedWhenSubscriptionsStarted.
/**
* When {@link SubscriptionProcessor#startSubscriptions()} is invoked,
* the {@link AppSync} client receives subscription requests.
*/
@Test
public void appSyncInvokedWhenSubscriptionsStarted() {
// For every Class-SubscriptionType pairing, use a CountDownLatch
// to tell whether or not we've "seen" a subscription event for it.
Map<Pair<ModelSchema, SubscriptionType>, CountDownLatch> seen = new HashMap<>();
// Build a stream of such pairs.
Observable.fromIterable(modelSchemas).flatMap(modelSchema -> Observable.fromArray(SubscriptionType.values()).map(value -> Pair.create(modelSchema, value))).blockingForEach(pair -> {
// For each one, store a latch. Add a mocking behavior to count down
// the latch when the subscription API is hit, for that class and subscription type.
CountDownLatch latch = new CountDownLatch(1);
seen.put(Pair.create(pair.first, pair.second), latch);
Answer<Cancelable> answer = invocation -> {
latch.countDown();
return new NoOpCancelable();
};
arrangeSubscription(appSync, answer, pair.first, pair.second);
});
// Act: start some subscriptions.
try {
subscriptionProcessor.startSubscriptions();
} catch (DataStoreException exception) {
// startSubscriptions throws this exception if it doesn't receive the start_ack messages after a time out.
// This test doesn't mock those start_ack messages, so this expection is expected. That's okay though -
// we just want to verify that the subscriptions were requested.
}
// Make sure that all of the subscriptions have been
Observable.fromIterable(seen.entrySet()).blockingForEach(entry -> {
CountDownLatch latch = entry.getValue();
assertTrue(latch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
});
}
use of com.amplifyframework.datastore.appsync.AppSync in project amplify-android by aws-amplify.
the class MutationProcessorTest method setup.
/**
* A {@link MutationProcessor} is being tested. To do so, we arrange mutations into
* an {@link MutationOutbox}. Fake responses are returned from a mock {@link AppSync}.
* @throws AmplifyException When loading SchemaRegistry
*/
@Before
public void setup() throws AmplifyException {
ShadowLog.stream = System.out;
LocalStorageAdapter localStorageAdapter = InMemoryStorageAdapter.create();
this.synchronousStorageAdapter = SynchronousStorageAdapter.delegatingTo(localStorageAdapter);
this.mutationOutbox = new PersistentMutationOutbox(localStorageAdapter);
VersionRepository versionRepository = new VersionRepository(localStorageAdapter);
Merger merger = new Merger(mutationOutbox, versionRepository, localStorageAdapter);
this.appSync = mock(AppSync.class);
this.configurationProvider = mock(DataStoreConfigurationProvider.class);
ConflictResolver conflictResolver = new ConflictResolver(configurationProvider, appSync);
schemaRegistry = SchemaRegistry.instance();
schemaRegistry.register(Collections.singleton(BlogOwner.class));
this.mutationProcessor = MutationProcessor.builder().merger(merger).versionRepository(versionRepository).schemaRegistry(schemaRegistry).mutationOutbox(mutationOutbox).appSync(appSync).conflictResolver(conflictResolver).build();
}
use of com.amplifyframework.datastore.appsync.AppSync 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<T> 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);
}
Aggregations