use of com.amplifyframework.core.model.SchemaRegistry in project amplify-android by aws-amplify.
the class MultiAuthSyncEngineInstrumentationTest method configure.
/**
* Method used to configure each scenario.
* @param modelType The model type.
* @param signInToCognito Does the test scenario require the user to be logged in with user pools.
* @param signInWithOidc Does the test scenario require the user to be logged in with an OIDC provider.
* @param expectedAuthType The auth type that should succeed for the test.
* @throws AmplifyException No expected.
* @throws IOException Not expected.
*/
private void configure(Class<? extends Model> modelType, boolean signInToCognito, boolean signInWithOidc, AuthorizationType expectedAuthType) throws AmplifyException, IOException {
Amplify.addPlugin(new AndroidLoggingPlugin(LogLevel.VERBOSE));
String tag = modelType.getSimpleName();
MultiAuthTestModelProvider modelProvider = MultiAuthTestModelProvider.getInstance(Collections.singletonList(modelType));
SchemaRegistry schemaRegistry = SchemaRegistry.instance();
ModelSchema modelSchema = ModelSchema.fromModelClass(modelType);
schemaRegistry.register(modelType.getSimpleName(), modelSchema);
StrictMode.enable();
Context context = getApplicationContext();
@RawRes int configResourceId = Resources.getRawResourceId(context, "amplifyconfiguration");
AmplifyConfiguration amplifyConfiguration = AmplifyConfiguration.fromConfigFile(context, configResourceId);
readCredsFromConfig(context);
// Setup an auth plugin
CategoryConfiguration authCategoryConfiguration = amplifyConfiguration.forCategoryType(CategoryType.AUTH);
// Turn off persistence so the mobile client's state for one test does not interfere with the others.
try {
authCategoryConfiguration.getPluginConfig("awsCognitoAuthPlugin").getJSONObject("Auth").getJSONObject("Default").put("Persistence", false);
} catch (JSONException exception) {
exception.printStackTrace();
fail();
return;
}
AuthCategory authCategory = new AuthCategory();
AWSCognitoAuthPlugin authPlugin = new AWSCognitoAuthPlugin();
authCategory.addPlugin(authPlugin);
authCategory.configure(authCategoryConfiguration, context);
auth = SynchronousAuth.delegatingTo(authCategory);
if (signInToCognito) {
Log.v(tag, "Test requires signIn.");
AuthSignInResult authSignInResult = auth.signIn(cognitoUser, cognitoPassword);
if (!authSignInResult.isSignInComplete()) {
fail("Unable to complete initial sign-in");
}
}
if (signInWithOidc) {
oidcLogin();
if (token.get() == null) {
fail("Unable to autenticate with OIDC provider");
}
}
// Setup an API
DefaultCognitoUserPoolsAuthProvider cognitoProvider = new DefaultCognitoUserPoolsAuthProvider(authPlugin.getEscapeHatch());
CategoryConfiguration apiCategoryConfiguration = amplifyConfiguration.forCategoryType(CategoryType.API);
ApiAuthProviders apiAuthProviders = ApiAuthProviders.builder().cognitoUserPoolsAuthProvider(cognitoProvider).awsCredentialsProvider(authPlugin.getEscapeHatch()).oidcAuthProvider(token::get).build();
ApiCategory apiCategory = new ApiCategory();
requestInterceptor = new HttpRequestInterceptor(expectedAuthType);
apiCategory.addPlugin(AWSApiPlugin.builder().configureClient("DataStoreIntegTestsApi", okHttpClientBuilder -> okHttpClientBuilder.addInterceptor(requestInterceptor)).apiAuthProviders(apiAuthProviders).build());
apiCategory.configure(apiCategoryConfiguration, context);
api = SynchronousApi.delegatingTo(apiCategory);
// Setup DataStore
DataStoreConfiguration dsConfig = DataStoreConfiguration.builder().errorHandler(exception -> Log.e(tag, "DataStore error handler received an error.", exception)).syncExpression(modelSchema.getName(), () -> Where.id("FAKE_ID").getQueryPredicate()).build();
CategoryConfiguration dataStoreCategoryConfiguration = AmplifyConfiguration.fromConfigFile(context, configResourceId).forCategoryType(CategoryType.DATASTORE);
String databaseName = "IntegTest" + modelType.getSimpleName() + ".db";
SQLiteStorageAdapter sqLiteStorageAdapter = TestStorageAdapter.create(schemaRegistry, modelProvider, databaseName);
AWSDataStorePlugin awsDataStorePlugin = AWSDataStorePlugin.builder().storageAdapter(sqLiteStorageAdapter).modelProvider(modelProvider).apiCategory(apiCategory).authModeStrategy(AuthModeStrategyType.MULTIAUTH).schemaRegistry(schemaRegistry).dataStoreConfiguration(dsConfig).build();
DataStoreCategory dataStoreCategory = new DataStoreCategory();
dataStoreCategory.addPlugin(awsDataStorePlugin);
dataStoreCategory.configure(dataStoreCategoryConfiguration, context);
dataStoreCategory.initialize(context);
dataStore = SynchronousDataStore.delegatingTo(dataStoreCategory);
}
use of com.amplifyframework.core.model.SchemaRegistry in project amplify-android by aws-amplify.
the class TopologicalOrderingTest method orderingOfBlogPostComment.
/**
* Checks the topological ordering of the Blog, Post, and Comment classes.
* @throws AmplifyException On failure to load models into registry
*/
@Test
public void orderingOfBlogPostComment() throws AmplifyException {
// Load the models into the registry.
// They are provided intentionally out of topological order.
final SimpleModelProvider provider = SimpleModelProvider.withRandomVersion(Comment.class, Blog.class, BlogOwner.class, Post.class);
final SchemaRegistry registry = SchemaRegistry.instance();
registry.clear();
registry.register(provider.models());
// Find the schema that the registry created for each of the models.
ModelSchema commentSchema = findSchema(registry, Comment.class);
ModelSchema postSchema = findSchema(registry, Post.class);
ModelSchema blogSchema = findSchema(registry, Blog.class);
// Act: get a topological ordering of the models.
TopologicalOrdering topologicalOrdering = TopologicalOrdering.forRegisteredModels(registry, provider);
// Assert: Blog comes before Post, and Post comes before Comment.
assertTrue(topologicalOrdering.check(blogSchema).isBefore(postSchema));
assertTrue(topologicalOrdering.check(postSchema).isBefore(commentSchema));
// Assert: in other words, Comment is after Post, and Post is after Blog.
assertTrue(topologicalOrdering.check(commentSchema).isAfter(postSchema));
assertTrue(topologicalOrdering.check(postSchema).isAfter(blogSchema));
}
use of com.amplifyframework.core.model.SchemaRegistry in project amplify-android by aws-amplify.
the class SQLiteStorageAdapter method initialize.
/**
* {@inheritDoc}
*/
@Override
public synchronized void initialize(@NonNull Context context, @NonNull Consumer<List<ModelSchema>> onSuccess, @NonNull Consumer<DataStoreException> onError, @NonNull DataStoreConfiguration dataStoreConfiguration) {
Objects.requireNonNull(context);
Objects.requireNonNull(onSuccess);
Objects.requireNonNull(onError);
// Create a thread pool large enough to take advantage of parallelization, but small enough to avoid
// OutOfMemoryError and CursorWindowAllocationException issues.
this.threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * THREAD_POOL_SIZE_MULTIPLIER);
this.context = context;
this.dataStoreConfiguration = dataStoreConfiguration;
threadPool.submit(() -> {
try {
/*
* Start with a fresh registry.
*/
schemaRegistry.clear();
/*
* Create {@link ModelSchema} objects for the corresponding {@link Model}.
* Any exception raised during this when inspecting the Model classes
* through reflection will be notified via the `onError` callback.
*/
schemaRegistry.register(modelsProvider.modelSchemas(), modelsProvider.customTypeSchemas());
/*
* Create the CREATE TABLE and CREATE INDEX commands for each of the
* Models. Instantiate {@link SQLiteStorageHelper} to execute those
* create commands.
*/
this.sqlCommandFactory = new SQLiteCommandFactory(schemaRegistry, gson);
CreateSqlCommands createSqlCommands = getCreateCommands(modelsProvider.modelNames());
sqliteStorageHelper = SQLiteStorageHelper.getInstance(context, databaseName, DATABASE_VERSION, createSqlCommands);
/*
* Create and/or open a database. This also invokes
* {@link SQLiteStorageHelper#onCreate(SQLiteDatabase)} which executes the tasks
* to create tables and indexes. When the function returns without any exception
* being thrown, invoke the `onError` callback.
*
* Errors are thrown when there is no write permission to the database, no space
* left in the database for any write operation and other errors thrown while
* creating and opening a database. All errors are passed through the
* `onError` callback.
*
* databaseConnectionHandle represents a connection handle to the database.
* All database operations will happen through this handle.
*/
databaseConnectionHandle = sqliteStorageHelper.getWritableDatabase();
/*
* Create helper instance that can traverse through model relations.
*/
this.sqliteModelTree = new SQLiteModelTree(schemaRegistry, databaseConnectionHandle);
/*
* Create a command processor which runs the actual SQL transactions.
*/
this.sqlCommandProcessor = new SQLCommandProcessor(databaseConnectionHandle);
sqlQueryProcessor = new SqlQueryProcessor(sqlCommandProcessor, sqlCommandFactory, schemaRegistry);
syncStatus = new SyncStatus(sqlQueryProcessor, dataStoreConfiguration);
/*
* Detect if the version of the models stored in SQLite is different
* from the version passed in through {@link ModelProvider#version()}.
* Delete the database if there is a version change.
*/
toBeDisposed.add(updateModels().subscribe(() -> onSuccess.accept(Immutable.of(new ArrayList<>(schemaRegistry.getModelSchemaMap().values()))), throwable -> onError.accept(new DataStoreException("Error in initializing the SQLiteStorageAdapter", throwable, AmplifyException.TODO_RECOVERY_SUGGESTION))));
} catch (Exception exception) {
onError.accept(new DataStoreException("Error in initializing the SQLiteStorageAdapter", exception, "See attached exception"));
}
});
}
use of com.amplifyframework.core.model.SchemaRegistry in project amplify-android by aws-amplify.
the class SerializedModelAdapter method deserialize.
@Override
public SerializedModel deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject object = json.getAsJsonObject();
ModelSchema modelSchema = context.deserialize(object.get("modelSchema"), ModelSchema.class);
JsonObject serializedDataObject = object.get("serializedData").getAsJsonObject();
Map<String, Object> serializedData = new HashMap<>(GsonObjectConverter.toMap(serializedDataObject));
// Patch up nested models as SerializedModels themselves.
for (Map.Entry<String, JsonElement> item : serializedDataObject.entrySet()) {
ModelField field = modelSchema.getFields().get(item.getKey());
if (field != null && field.isModel()) {
SchemaRegistry schemaRegistry = SchemaRegistry.instance();
ModelSchema nestedModelSchema = schemaRegistry.getModelSchemaForModelClass(field.getTargetType());
serializedData.put(field.getName(), SerializedModel.builder().serializedData(Collections.singletonMap("id", item.getValue().getAsString())).modelSchema(nestedModelSchema).build());
}
}
return SerializedModel.builder().serializedData(serializedData).modelSchema(modelSchema).build();
}
use of com.amplifyframework.core.model.SchemaRegistry in project amplify-android by aws-amplify.
the class SelectionSetTest method nestedSerializedModel.
/**
* Test generating SelectionSet for nested ModelSchema using SerializedModel.
* @throws AmplifyException if a ModelSchema can't be derived from postSchema
*/
@Test
public void nestedSerializedModel() throws AmplifyException {
SchemaRegistry schemaRegistry = SchemaRegistry.instance();
ModelField blogModelId = ModelField.builder().isRequired(true).targetType("ID").build();
ModelField blogName = ModelField.builder().isRequired(true).targetType("String").build();
Map<String, ModelField> blogFields = new HashMap<>();
blogFields.put("id", blogModelId);
blogFields.put("name", blogName);
ModelSchema blogSchema = ModelSchema.builder().name("Blog").pluralName("Blogs").modelClass(SerializedModel.class).fields(blogFields).build();
ModelField postModelId = ModelField.builder().isRequired(true).targetType("ID").build();
ModelField postTitle = ModelField.builder().isRequired(true).targetType("String").build();
ModelField postBlog = ModelField.builder().isRequired(true).targetType("Blog").isModel(true).build();
Map<String, ModelField> postFields = new HashMap<>();
postFields.put("id", postModelId);
postFields.put("title", postTitle);
postFields.put("blog", postBlog);
Map<String, ModelAssociation> associations = new HashMap<>();
associations.put("blog", ModelAssociation.builder().name("BelongsTo").targetName("blogId").associatedType("Blog").build());
ModelSchema postSchema = ModelSchema.builder().name("Post").pluralName("Posts").modelClass(SerializedModel.class).fields(postFields).associations(associations).build();
schemaRegistry.register("Blog", blogSchema);
schemaRegistry.register("Post", postSchema);
SelectionSet selectionSet = SelectionSet.builder().modelClass(SerializedModel.class).modelSchema(postSchema).operation(QueryType.SYNC).requestOptions(new JustIDGraphQLRequestOptions()).build();
assertEquals(Resources.readAsString("selection-set-post-nested.txt"), selectionSet.toString() + "\n");
}
Aggregations