Comment 4 for bug 1498573

Revision history for this message
Petr Malik (pmalik) wrote :

I poked around the API extensions a bit trying how it could be refactored to allow datastores easily implement their own with minimal amount of code.

The extensions are currently broken down into models, views and service modules. The service module contains the Controller classes (e.g. UserController). The Controllers are where the heavy lifting is done (it is the class guest should be overriding - see the datastore-specific 'root_controller' config property - for handling root-related API calls).

The controllers use model and view classes internally (all static calls). Unfortunately, rather than doing all (datastore specific) validations in the Controller classes the current implementation does *some* (but not all) in the models as well (it calls into guestagent.db.models to build datastore-specific model objects that also perform validations when constructed).

Implementing a new user/database extension for a non-mysql datastore would hence require overriding both the controller and mode/view classes. That's many classes for just building the proper objects...

I would suggest removing the datastore-specific code from models and views (all datastores use the same fields anyways). The validation should be all moved into the Controllers, before the static model methods get called (building the proper model object could be implemented via a single overridable method in the Controller class). The models and views would then simply perform serialization (which does not really require any datastore-specific functionality [it can use the base model's 'deserialize' method to do that, no need to construct a datastore-specific class, alternatively some models deserialize 'manually' - see https://github.com/openstack/trove/blob/master/trove/extensions/mysql/models.py#L105 )

Each datastore would then need to provide the 'user_controller' and 'database_controller' configuration property (like it already does with the 'root_controller'). The base controller implementation could then use the same model/view implementation (current MySQL classes moved into the common package).
Datastore-specific controller would then just implement 'builder' methods for guestagent models called by the base implementation which could then stay pretty much intact.