"""Main file.""" import secrets import time import sentry_sdk from owslogger import logger import aura_api import config from exceptions import ApiError from exceptions import TokenExpired # Global logger log = logger.setup( config.ENVIRONMENT, config.LOGGER_NAME, config.LOGGER_LEVEL, config.SERVICE_NAME, config.SERVICE_VERSION, correlation_id=str(time.time()), dsn=config.LOGGER_DSN, # set this when you run it on jenkins not fargate. ) # Sentry handler sentry_sdk.init(config.SENTRY_DSN) def get_source_dest_instance_ids(token: object, source_name: str, dest_name: str) -> tuple: instances = aura_api.get_all_instances(token) source = next(item for item in instances if item['name'] == source_name) dest = next(item for item in instances if item['name'] == dest_name) assert source, f'Error: No instance with name: {source_name}' assert dest, f'Error: No instance with name: {dest_name}' return source.get('id'), dest.get('id') def status_running_check(token: object, dest_id: str): """Check if dest instance is running.""" for (attempt, val,) in enumerate(range(0, config.STATUS_CHECK_MAX_RETRIES)): log.info(f'Status checks attempt: {attempt}') timeout = time.time() + config.STATUS_CHECK_TIMEOUT_SEC while time.time() < timeout: try: dest_instance = aura_api.get_instance_details(token, dest_id) if dest_instance.get('status') == 'running': log.info('Instance is now running.') return True else: log.info(f"Instance is still {dest_instance.get('status')}.") # Add some delay of 10-12 mins before making the api call. time.sleep(secrets.SystemRandom().randrange(600, 720)) except TokenExpired: # in case refresh takes > 1 hr, token would have expired. log.info('Token Expired, fetching a new one and retry.') token = aura_api.get_oauth_token() time.sleep(secrets.SystemRandom().randrange(60, 80)) # If timeout is reached and function has not returned, fail. log.error('Max retry attempts reached and instance is not running.') raise ApiError('Instance failed to get running.') def main(): source_name = config.NEO4J_HOSTS_MAP[config.NEO4J_HOST_TO_REFRESH] dest_name = config.NEO4J_HOST_TO_REFRESH sentry_sdk.set_tags({ 'source_db': source_name, 'dest_db': dest_name, }) try: log.info(f'Starting refresh process from {source_name} to {dest_name}.') token = aura_api.get_oauth_token() source_id, dest_id = get_source_dest_instance_ids(token, source_name, dest_name) log.info(f'Source Id: {source_id} , destination Id: {dest_id}') log.info('Starting to refresh neo4j instance.') aura_api.overwrite_instance(token, dest_id, source_id) log.info('Overwrite started, now running status check.') status_running_check(token, dest_id) log.info('Finished refreshing neo4j instance.') time.sleep(secrets.SystemRandom().randrange(60, 80)) if config.DESTINATION_CDC_MODE != 'OFF': # get fresh token in case refresh took longer and token will expire soon. token = aura_api.get_oauth_token() # CDC is automatically disabled for Cloned instances. log.info(f'Overwrite CDC mode to: {config.DESTINATION_CDC_MODE}') aura_api.update_instance(token, dest_id, config.DESTINATION_CDC_MODE) # updating cdc mode is async and does not take that long to go # from updating to running but better to check that the instance # is running after the update. time.sleep(secrets.SystemRandom().randrange(60, 80)) status_running_check(token, dest_id) log.info('Finished updating CDC mode for the instance.') except Exception as err: log.error('Failed to finish refresh due to exception.') log.exception(err) raise err if __name__ == '__main__': main()