Exemplo n.º 1
0
def can_authenticate_to_old(old):
    old_client = OLDClient(old['url'])
    try:
        return old_client.login(
            DEFAULT_LOCAL_OLD_USERNAME,
            DEFAULT_LOCAL_OLD_PASSWORD)
    except Exception as e:
        logger.warning(
            f'Exception of type {type(e)} when attempting to'
            f' authenticate to the OLD')
        return False
Exemplo n.º 2
0
def authenticate_to_leader(old):
    logger.debug(
        f'checking if we can login to the leader OLD at {old["leader"]}'
        f' using username {old["username"]} and password'
        f' {old["password"]}')
    old_client = OLDClient(old['leader'])
    try:
        logged_in = old_client.login(old['username'], old['password'])
        if logged_in:
            return old_client
        return False
    except Exception:
        logger.exception(f'Failed to login to the leader OLD {old["leader"]}')
        return False
Exemplo n.º 3
0
def process_command(dtserver, old_service, command):
    """Process a sync-OLD! command."""

    # Get the OLD metadata from DTServer
    old = fetch_old(dtserver, command['old_id'])
    old['url'] = f'{old_service.url}/{old["slug"]}'

    # Determine whether the OLD already exists and create it if necessary
    old_exists = does_old_exist(old)
    if not old_exists:
        old_exists = create_local_old(old)
        if not old_exists:
            msg = f'Failed to create the OLD {old["slug"]} locally'
            logger.warning(msg)
            raise SyncOLDError(msg)

    # Abort if we are not set to sync or if there is nothing to sync with
    if not old['is_auto_syncing']:
        logger.debug(f'OLD {old["slug"]} is not set to auto-sync')
        return
    if not old['leader']:
        logger.debug(f'OLD {old["slug"]} has no remote leader OLD')
        return
    leader_client = authenticate_to_leader(old)
    if not leader_client:
        logger.warning(f'Unable to login to leader OLD {old["leader"]}')
        return

    # Fetch the last modified values for each resource in the local OLD and in
    # the leader OLD and construct a diff.
    local_client = OLDClient(old['url'])
    local_client.login(
        DEFAULT_LOCAL_OLD_USERNAME,
        DEFAULT_LOCAL_OLD_PASSWORD)
    local_last_mod = local_client.get('sync/last_modified')
    leader_last_mod = leader_client.get('sync/last_modified')
    diff = get_diff(local_last_mod, leader_last_mod)

    # Perform the local updates by modifying the SQLite db of the OLD directly.
    meta = sqla.MetaData()
    db_path = os.path.join(c.OLD_DIR, f"{old['slug']}.sqlite")
    engine = sqla.create_engine(f'sqlite:///{db_path}')
    with engine.connect() as conn:
        # Perform any deletions
        delete_state = diff['delete']
        if delete_state:
            for table_name, rows in delete_state.items():
                if not rows:
                    continue
                table = sqla.Table(table_name, meta, autoload_with=engine)
                conn.execute(
                    table.delete().where(
                        table.c.id.in_(rows)))
        # Perform any additions
        add_params = diff['add']
        if add_params:
            for batch in batch_tables(add_params):
                add_state = leader_client.post(
                    'sync/tables', {'tables': batch})
                for table_name, rows in add_state.items():
                    if not rows:
                        continue
                    table = sqla.Table(table_name, meta, autoload_with=engine)
                    conn.execute(
                        table.insert(),
                        [prepare_row_for_upsert(table_name, row)
                        for row in rows.values()])
        # Perform any updates
        update_params = diff['update']
        if update_params:
            for batch in batch_tables(update_params):
                update_state = leader_client.post(
                    'sync/tables', {'tables': batch})
                for table_name, rows in update_state.items():
                    if not rows:
                        continue
                    table = sqla.Table(table_name, meta, autoload_with=engine)
                    for row in rows.values():
                        row_id = row['id']
                        updated_row = prepare_row_for_upsert(table_name, row)
                        conn.execute(
                            table.update().where(
                                table.c.id == row_id).values(**updated_row))