'Handle transition between providers.
The provider can currently be changed only by the caller updating
\'ha\' and/or \'distributed\' attributes. If we allow updates of flavor_id
directly in the future those requests will also land here.'

@registry.receives(resources.ROUTER, [events.PRECOMMIT_UPDATE])
def _update_router_provider(self, resource, event, trigger, context, router_id, router, old_router, router_db, **kwargs):

    drv = self.get_provider_for_router(context, router_id)
    new_drv = None
    if _flavor_specified(router):
        if (router['flavor_id'] != old_router['flavor_id']):
            raise NotImplementedError()
    try:
        _ensure_driver_supports_request(drv, router)
    except lib_exc.InvalidInput:
        if old_router['flavor_id']:
            raise lib_exc.InvalidInput(error_message=_("Changing    the    'ha'    and    'distributed'    attributes    on    a    router    associated    with    a    flavor    is    not    supported"))
        if ('distributed' not in router):
            router['distributed'] = old_router['distributed']
        if ('ha' not in router):
            router['ha'] = old_router['distributed']
        new_drv = self._attrs_to_driver(router)
    if new_drv:
        LOG.debug('Router    %(id)s    migrating    from    %(old)s    provider    to    %(new)s    provider.', {'id': router_id, 'old': drv, 'new': new_drv})
        _ensure_driver_supports_request(new_drv, router)
        with context.session.begin(subtransactions=True):
            self._stm.del_resource_associations(context, [router_id])
            self._stm.add_resource_association(context, plugin_constants.L3, new_drv.name, router_id)
