Exemplo n.º 1
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.logger = Logger()
     self.table_name = kwargs.get(Constants.TABLE, Settings.SERVICE_NAME)
     self.client = kwargs.get(Constants.CLIENT, get_default_dynamo_client())
     self.resource = kwargs.get(Constants.RESOURCE,
                                get_default_dynamo_resource())
     self._initialize_tables()
Exemplo n.º 2
0
 def __init__(self,
              account_name,
              http=HttpRequestor(),
              secrets_manager=SecretManager()):
     self.http = http
     self.secrets_manager = secrets_manager
     self.account_name = account_name
     self.account_id = get_newrelic_account_id(self.account_name)
     self.api_key = get_newrelic_api_key(self.account_name,
                                         self.secrets_manager)
     self.logger = Logger(Settings.SERVICE_NAME)
Exemplo n.º 3
0
 def __init__(self, **kwargs):
     """ Initialization for mongodb with support for TDD. """
     super().__init__(**kwargs)
     self.db_name = Settings.MONGO_DB_NAME
     collection_name = kwargs.get(Constants.TABLE, Settings.SERVICE_NAME)
     self.host = kwargs.get(Constants.HOST, Settings.MONGO_URL)
     self.port = kwargs.get(Constants.PORT, Settings.MONGO_PORT)
     self.client = kwargs.get(Constants.CLIENT, MongoClient(self.host, self.port, serverSelectionTimeoutMS=20))
     self.collection = None
     self.logger = Logger()
     self.database = self.client[self.db_name]
     self._select_collection(collection_name)
Exemplo n.º 4
0
class NewRelicQueryExecutor:
    def __init__(self,
                 account_name,
                 http=HttpRequestor(),
                 secrets_manager=SecretManager()):
        self.http = http
        self.secrets_manager = secrets_manager
        self.account_name = account_name
        self.account_id = get_newrelic_account_id(self.account_name)
        self.api_key = get_newrelic_api_key(self.account_name,
                                            self.secrets_manager)
        self.logger = Logger(Settings.SERVICE_NAME)

    def execute_faceted_query(self, query):
        result = self._execute_query(query)
        result_json = result.json()
        if not result.ok:
            return self._get_failure_result(result_json)
        return QueryResult(result_json, ResultTypes.SUCCESS)

    def execute_single_value_query(self, query):
        try:
            result = self._execute_query(query)
            result_json = result.json()
            if not result.ok:
                return self._get_failure_result(result_json)
            results = result_json.get(Constants.RESULTS, None)
            if results:
                first_result = results[0]
                if first_result:
                    filtered_result = next(iter(first_result.values()))
                    return QueryResult(filtered_result, ResultTypes.SUCCESS)
                return QueryResult(None, ResultTypes.UNKNOWN,
                                   Constants.NR_EMPTY_RESULTS_MESSAGE)
            return QueryResult(None, ResultTypes.UNKNOWN,
                               Constants.NR_NO_RESULT_ITEM_MESSAGE)
        except (Exception, ValueError) as ex:  # pylint: disable=broad-except
            self.logger.error(
                f'Newrelic query execution for {query} failed: {ex}')
            return QueryResult(None, ResultTypes.ERROR, ex)

    def _get_failure_result(self, result_json):
        self.logger.info(f'Newrelic result: {result_json}')
        return QueryResult(None, ResultTypes.ERROR, result_json)

    def build_url(self, account_id, query):
        try:
            url = Settings.NEWRELIC_QUERY_URL
            encoded_query = quote(query)
            return url.format(account_id=account_id, query=encoded_query)
        except TypeError as ex:
            self.logger.error(
                f'Encoding query failed due to non-string parameter: {ex}')
            return None

    def _execute_query(self, query):
        self.logger.info(f'Executing newrelic query: {query}')
        headers = {Constants.X_QUERY_KEY_HEADER: self.api_key}
        url = self.build_url(self.account_id, query)
        return self.http.get(url, headers=headers)
Exemplo n.º 5
0
def check_session(session_token, http_client=HttpRequestor(), logger=Logger()):
    try:
        response = http_client.get(Settings.SESSION_URL.format(session_token=session_token)).json()
        return response.get(Constants.STATUS, Constants.EMPTY) == Constants.OKTA_ACTIVE_STATUS
    except Exception as ex:  # pylint: disable=broad-except
        logger.error(f'Error checking session. ex: {ex}')
        return False
Exemplo n.º 6
0
class BaseModel:
    logger = Logger()
    id: str  # pylint: disable=invalid-name

    def __init__(self, dictionary=None):
        if dictionary:
            vars(self).update(dictionary)

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return self.to_json(self)

    # pylint: disable=inconsistent-return-statements
    @staticmethod
    def safe_set_attribute(attribute):
        if attribute:
            return attribute

    def get_attribute(self, attribute_name):
        return self.__dict__.get(attribute_name, Constants.EMPTY)

    @staticmethod
    def from_json(json_string):
        return json.loads(json_string, object_hook=BaseModel)

    def get_json(self):
        return BaseModel.to_json(self)

    @staticmethod
    def to_json(model):
        return json.dumps(model.__dict__, default=str)

    def validate(self, model=None, schema=None):
        if schema is None:
            schema = self.to_schema()
            if not schema:
                return True
        validator = Validator(schema)
        model_data = self.__dict__
        if model:
            model_data = model
        result = validator.validate(model_data)
        self.logger.info(f'Validation errors: {validator.errors}')
        return result

    def to_schema(self):
        schema = {}
        # pylint: disable=no-member
        functions = self.__annotations__
        for key, value in functions.items():
            # pylint: disable=unidiomatic-typecheck
            if type(value) is not Field:
                return False
            schema[key] = {
                'type': SchemaTypeMappings[value.type.__name__],
            }
            schema[key].update(value.schema)
        return schema
Exemplo n.º 7
0
 def __init__(self, queue_name, **kwargs):
     self.queue_name = queue_name
     self.runner = True
     self.exit = False
     self.client = kwargs.pop(Constants.CLIENT,
                              MessageQueue(queue_name=self.queue_name))
     self.logger = kwargs.pop(Constants.LOGGER, Logger())
     super().__init__(**kwargs)
Exemplo n.º 8
0
class SumologicQueryExecutor:

    def __init__(self, http=HttpRequestor()):
        self.http = http
        self.logger = Logger(Settings.SERVICE_NAME)
        self.headers = {Constants.CONTENT_TYPE_HEADER: Constants.CONTENT_TYPE_JSON,
                        Constants.ACCEPT_HEADER: Constants.CONTENT_TYPE_JSON}

    def execute_sumologic_query(self, query, from_time, to_time, api_id, api_key):
        try:
            payload = {Constants.QUERY: query, Constants.FROM_DATE_PARAMETER: from_time,
                       Constants.TO_DATE_PARAMETER: to_time}
            self.logger.info(f'Running sumologic query... {payload}')
            result = self.http.post(
                Constants.SUMOLOGIC_QUERY_URL, auth=self.http.get_auth_value(api_id, api_key),
                data=json.dumps(payload, default=str), headers=self.headers)
            self.logger.info(f'Result from sumologic post is... {result.text}')
            if result.status_code == Constants.RECEIVED_SUCCESS_CODE:
                return self.get_sumologic_query_results(result, api_id, api_key)
            return QueryResult(None, ResultTypes.UNKNOWN, Constants.SUMO_NO_RESULT_FOUND_MESSAGE)
        except (Exception, ValueError) as ex:  # pylint: disable=broad-except
            self.logger.error(f'Sumologic query execution failed: {ex}', exc_info=True)
            return QueryResult(None, ResultTypes.ERROR, ex)

    def get_sumologic_query_results(self, query_request_json, api_id, api_key, retry_count=5, wait_time_seconds=5):
        try:
            retries = retry_count
            result_json = query_request_json.json()
            url_get = result_json[Constants.LINK][Constants.HREF]
            self.logger.info(f'Making sumologic get request for query results. {url_get}')
            while retries >= 0:
                retries -= 1
                query_result = self.http.get(
                    url_get, auth=self.http.get_auth_value(api_id, api_key), headers=self.headers)
                if query_result.status_code == Constants.SUCCESS_RESPONSE_CODE:
                    result = query_result.json()
                    message_count = result.get(Constants.SUMOLOGIC_MESSAGE_COUNT, None)
                    if message_count:
                        return QueryResult(message_count, ResultTypes.SUCCESS)
                    return QueryResult(None, ResultTypes.UNKNOWN, Constants.SUMO_MISSING_COUNT_MESSAGE)
                sleep(wait_time_seconds)
            return QueryResult(0, ResultTypes.UNKNOWN, Constants.SUMO_RETRY_EXCEEDED_MESSAGE)
        except (Exception, ValueError) as ex:  # pylint: disable=broad-except
            self.logger.error(f'Error getting sumologic query results. {ex}')
            return QueryResult(None, ResultTypes.ERROR, ex)
Exemplo n.º 9
0
 def __init__(self, **kwargs):
     self.logger = kwargs.get(Constants.LOGGER, Logger())
     self.queue_name = kwargs.get(Constants.QUEUE_NAME, None)
     self.endpoint_url = None
     if not Settings.ENV:
         self.endpoint_url = kwargs.get(
             Constants.ENDPOINT_URL,
             f'{Settings.SQS_URL}:{Settings.SQS_PORT}')
     self.sqs_resource = kwargs.get(Constants.CLIENT,
                                    get_sqs_resource(self.endpoint_url))
     self.sqs_client = kwargs.get(Constants.CLIENT,
                                  get_sqs_client(self.endpoint_url))
Exemplo n.º 10
0
 def create(component_type, **kwargs):
     if isinstance(component_type, Components.DataClients):
         return Factory._create_data_client(component_type, **kwargs)
     if isinstance(component_type, Components.ServiceClients):
         return Factory._create_service_client(component_type, **kwargs)
     if isinstance(component_type, Components.MonitorClients):
         return MonitoringProvider()
     if isinstance(component_type, Components.LogClients):
         return Logger()
     if isinstance(component_type, Components.SecretsClients):
         return SecretManager()
     if isinstance(component_type, Components.Controllers):
         return Factory._create_controller(component_type, **kwargs)
     return None
Exemplo n.º 11
0
 def __init__(self, **kwargs):
     self.logger = Logger()
     self.collector = kwargs.get(Constants.COLLECTOR, None)
     self.controller = kwargs.get(Constants.CONTROLLER,
                                  DataController(**kwargs))
     self.client = kwargs.get(Constants.CLIENT, None)
Exemplo n.º 12
0
class CollectionController:
    name = Settings.SERVICE_NAME
    monitor = MonitoringProvider()

    def __init__(self, **kwargs):
        self.logger = Logger()
        self.collector = kwargs.get(Constants.COLLECTOR, None)
        self.controller = kwargs.get(Constants.CONTROLLER,
                                     DataController(**kwargs))
        self.client = kwargs.get(Constants.CLIENT, None)

    @http(Constants.GET_REQUEST, get_route(Constants.PING_ROUTE))
    def ping(self, request):
        return self.controller.ping(request)

    @http(Constants.OPTIONS_REQUEST, get_route())
    @http(Constants.OPTIONS_REQUEST, get_route(Constants.RUN_ROUTE))
    def options(self, request):
        return self.controller.options(request)

    @http(Constants.OPTIONS_REQUEST, get_item_route())
    def options_item(self, request, item_id):
        return self.controller.options_item(request, item_id)

    @http(Constants.GET_REQUEST, get_route())
    def get(self, request):
        return self.controller.get(request)

    @http(Constants.POST_REQUEST, get_route(Constants.PURGE_ROUTE))
    def purge(self, request):
        return self.controller.purge(request)

    @http(Constants.GET_REQUEST, get_item_route())
    def get_one(self, request, item_id):
        return self.controller.get_one(request, item_id)

    @http(Constants.GET_REQUEST, get_route(Constants.COUNT_ROUTE))
    def count(self, request):
        return self.controller.count(request)

    @http(Constants.GET_REQUEST, get_route(Constants.HEALTH_ROUTE))
    def health(self, request):
        return self.controller.health(request)

    @http(Constants.GET_REQUEST, get_route(Constants.VERSION_ROUTE))
    def version(self, request):
        return self.controller.version(request)

    @http(Constants.PUT_REQUEST, get_route())
    @http(Constants.DELETE_REQUEST, get_route())
    def bad_verbs(self, request):
        return self.controller.bad_verbs(request)

    @http(Constants.POST_REQUEST, get_route())
    def post(self, request):
        self.logger.info(
            get_log_string(request, Constants.POST_REQUEST, self.name))
        return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE

    @http(Constants.PUT_REQUEST, get_item_route())
    def put(self, request, item_id):
        self.logger.info(
            get_log_string(request, Constants.PUT_REQUEST, self.name, item_id))
        return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE

    @http(Constants.POST_REQUEST, get_route(Constants.COLLECTION_ROUTE))
    def collect(self, request):
        return self.collect_post(request, self.collector, self.logger)

    @http(Constants.GET_REQUEST, get_route(Constants.COLLECTION_ROUTE))
    def collect_result(self, request):
        return self.collect_get(request, self.collector, self.logger)

    @http(Constants.DELETE_REQUEST, get_route(Constants.COLLECTION_ROUTE))
    def collect_purge(self, request):
        return self.collect_delete(request, self.collector, self.logger)

    @http(Constants.DELETE_REQUEST, get_item_route())
    def delete(self, request, item_id):
        self.logger.info(
            get_log_string(request, Constants.DELETE_REQUEST, self.name,
                           item_id))
        return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE

    @staticmethod
    def collect_post(request, collector, logger):
        logger.info(get_log_string(request, Constants.POST_REQUEST, __name__))
        thread = Thread(target=perform_collection, args=(collector, ))
        thread.start()
        return Constants.RECEIVED_SUCCESS_CODE, Constants.COLLECTION_RECEIVED_MESSAGE

    @staticmethod
    def collect_get(request, collector, logger):
        logger.info(get_log_string(request, Constants.GET_REQUEST, __name__))
        result = collector.manager.get_collection_status(collector.name)
        if not result:
            return Constants.SUCCESS_RESPONSE_CODE, Constants.NO_COLLECTION_FOUND_MESSAGE
        return Constants.SUCCESS_RESPONSE_CODE, json.dumps(result, default=str)

    @staticmethod
    def collect_delete(request, collector, logger):
        logger.info(get_log_string(request, Constants.DELETE_REQUEST,
                                   __name__))
        collector.manager.purge_prior_collections()
        return Constants.SUCCESS_RESPONSE_CODE, Constants.PURGE_REQUEST_MESSAGE
Exemplo n.º 13
0
 def __init__(self, http=HttpRequestor()):
     self.http = http
     self.logger = Logger(Settings.SERVICE_NAME)
     self.headers = {Constants.CONTENT_TYPE_HEADER: Constants.CONTENT_TYPE_JSON,
                     Constants.ACCEPT_HEADER: Constants.CONTENT_TYPE_JSON}
Exemplo n.º 14
0
class DynamoDataClient(DataClient):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.logger = Logger()
        self.table_name = kwargs.get(Constants.TABLE, Settings.SERVICE_NAME)
        self.client = kwargs.get(Constants.CLIENT, get_default_dynamo_client())
        self.resource = kwargs.get(Constants.RESOURCE,
                                   get_default_dynamo_resource())
        self._initialize_tables()

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_create'))
    def create(self, model):
        model = self.get_converted_model(model)
        result = self.resource.Table(self.table_name).put_item(Item=model)
        return self.check_status(result)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_update'))
    def update(self, key, model):
        model.id = key
        return self.create(model)

    def get_converted_model(self, model, nest=False):
        empty_keys = list()
        if not isinstance(model, dict):
            model = model.__dict__
        for key, value in model.items():
            if isinstance(value, float):
                model[key] = Decimal(str(value))
                continue
            if not value:
                if key not in empty_keys:
                    empty_keys.append(key)
                continue
            if isinstance(value, dict):
                model[key] = self.get_converted_model(value, True)
                if not model[key]:
                    if key not in empty_keys:
                        empty_keys.append(key)
        for key in empty_keys:
            model.pop(key)
        if not nest:
            if Constants.ID not in model.keys():
                model[Constants.ID] = str(uuid4())
        return model

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_get'))
    def get(self, key):
        self.logger.debug(f'Get item on dynamo for id: {key}')
        self.create_table(self.table_name)
        return self.resource.Table(self.table_name).get_item(Key={
            Constants.ID: key
        }).get(Constants.DYNAMO_ITEM_KEY, None)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_get_specific'))
    def get_specific(self, id_value, table_name):
        self.logger.debug(
            f'Get specific item on dynamo for id: {id_value} from {table_name}'
        )
        self.create_table(self.table_name)
        return self.resource.Table(
            self.table_name).get_item(Key={
                Constants.ID: id_value
            }).get(Constants.DYNAMO_ITEM_KEY, None)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_find'))
    def find(self, key, value):
        self.logger.debug(f'Find called on dynamo key: {key} val: {value}')
        all_items = self.get_all()
        return self.find_item_in_list(all_items, **{key: value})

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_get_all'))
    def get_all(self):
        self.logger.debug(f'Get all called on dynamo')
        self.create_table(self.table_name)
        return self.resource.Table(self.table_name).scan().get(
            Constants.DYNAMO_ITEMS_KEY, [])

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_count'))
    def count(self):
        return self.resource.Table(self.table_name).scan().get(
            Constants.DYNAMO_COUNT_KEY, 0)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_purge'))
    def purge(self):
        self.logger.debug('Purge called on dynamo...')
        success = True
        items = self.get_all()
        for item in items:
            success = success and self.delete(item.get(Constants.ID))
        return success

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'dynamo_delete'))
    def delete(self, key):
        self.logger.debug(f'Delete on dynamo called id: {key}')
        result = self.resource.Table(
            self.table_name).delete_item(Key={Constants.ID: key})
        return self.check_status(result)

    @staticmethod
    def check_status(result):
        return result.get(Constants.DYNAMO_RESPONSE_METADATA, {}).get(
            Constants.DYNAMO_SUCCESS_STATUS,
            Constants.BAD_REQUEST_CODE) == Constants.SUCCESS_RESPONSE_CODE

    @log_exception
    def table_exists(self, table_name):
        try:
            return self.resource.Table(table_name).table_status == 'ACTIVE'
        except Exception:  # pylint: disable=broad-except
            return False

    @log_exception
    def delete_table(self, table_name):
        try:
            return self.check_status(
                self.client.delete_table(TableName=table_name))
        except Exception:  # pylint: disable=broad-except
            return False

    @log_exception
    def filter(self, **kwargs):
        if not kwargs:
            items = self.get_all()
            return items, 0, len(items), len(items)
        offset, limit, query = get_query(**kwargs)
        all_items = self.get_all()
        return self.find_items_in_list(all_items, offset, limit, **query)

    @log_exception
    def delete_db(self):
        self.logger.debug('Drop db on dynamo called.')
        return self.delete_table(self.table_name)

    def create_table(self, table_name):
        try:
            if not self.table_exists(table_name):
                self.resource.create_table(
                    AttributeDefinitions=[Constants.DYNAMO_ID_TABLE_ATTR],
                    KeySchema=[Constants.DYNAMO_ID_TABLE_KEY],
                    ProvisionedThroughput=Constants.DEFAULT_DYNAMO_THROUGHPUT,
                    TableName=table_name)
            return True
        except Exception as ex:  # pylint: disable=broad-except
            self.logger.info(f'Error creating dynamo table. {ex}',
                             exc_info=True)
            return False

    @staticmethod
    def _get_dictionary_set(items_dictionary):
        converted_list = list()
        for key, value in items_dictionary.items():
            converted_list.append(f'{key}|{value}')
        return set(converted_list)

    def find_item_in_list(self, all_items, **kwargs):
        args_set = self._get_dictionary_set(kwargs)
        match_list = list()
        for item in all_items:
            item_set = self._get_dictionary_set(item)
            if len(item_set.intersection(args_set)) == len(args_set):
                match_list.append(item)
        return match_list

    def find_items_in_list(self, all_items, offset, limit, **kwargs):
        self.logger.info(f'Find called on dynamo with {offset}, {limit}')
        match_list = self.find_item_in_list(all_items, **kwargs)
        return match_list, offset, limit, len(match_list)

    def _tag_table(self, table_arn):
        try:
            self.client.tag_resource(ResourceArn=table_arn,
                                     Tags=Constants.DYNAMO_TAGS)
        except Exception:  # pylint: disable=broad-except
            pass

    def _initialize_tables(self):
        if self.create_table(self.table_name):
            self._tag_table(self.resource.Table(self.table_name).table_arn)

    def get_status(self):
        return self.table_exists(self.table_name)
Exemplo n.º 15
0
 def log_metric_for_checks(self, worker_ctx, metric_key, metric_value=Constants.EMPTY, logger=Logger(__name__)):
     request_url = self.get_request_url(worker_ctx)
     if 'infrastructure_get' in metric_key:
         logger.debug(f'Metric log for {request_url} - {metric_key}: {metric_value}')
Exemplo n.º 16
0
class MongoDataClient(DataClient):
    """ Data client for the mongodb nosql document data store. """

    def __init__(self, **kwargs):
        """ Initialization for mongodb with support for TDD. """
        super().__init__(**kwargs)
        self.db_name = Settings.MONGO_DB_NAME
        collection_name = kwargs.get(Constants.TABLE, Settings.SERVICE_NAME)
        self.host = kwargs.get(Constants.HOST, Settings.MONGO_URL)
        self.port = kwargs.get(Constants.PORT, Settings.MONGO_PORT)
        self.client = kwargs.get(Constants.CLIENT, MongoClient(self.host, self.port, serverSelectionTimeoutMS=20))
        self.collection = None
        self.logger = Logger()
        self.database = self.client[self.db_name]
        self._select_collection(collection_name)

    def get_health(self):
        try:
            return self.database.command(Constants.MONGO_STATS_COMMAND)
        except ServerSelectionTimeoutError:
            return {Constants.HEALTH: Constants.MONGO_CONNECTION_HEALTH_ERROR.format(host=self.host, port=self.port)}

    @log_exception
    def _select_collection(self, collection_name):
        collection = self.get_collection_name(collection_name)
        self.collection = self.client[self.db_name][collection]

    @log_exception
    def rename_table(self, old_name, new_name):
        self.logger.debug(f'Rename table called on data client. old: {old_name} new: {new_name}')
        self.database[old_name].rename(new_name, dropTarget=True)

    @log_exception
    def table_exists(self, table_name):
        self.logger.debug(f'Existence check on table: {table_name}')
        return table_name in self.database.collection_names()

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_create'))
    def create(self, model):
        if isinstance(model, BaseModel):
            model = model.__dict__
        result = self.collection.insert_one(model)
        return result.inserted_id is not None

    @log_exception
    def restore(self, data):
        self.logger.debug(f'Restoring data...')
        result = self.collection.insert_many(data)
        return result.inserted_ids is not None

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_get'))
    def get(self, key):
        self.logger.debug(f'Get item for id: {key}')
        return self.collection.find_one({Constants.DB_ID_KEY: ObjectId(key)})

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_update'))
    def update(self, key, model):
        self.logger.debug(f'Update item for id: {key}')
        if isinstance(model, BaseModel):
            model = model.__dict__
            model.pop(Constants.ID)
        return self.collection.find_one_and_replace({Constants.DB_ID_KEY: ObjectId(key)}, model, upsert=True)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_get_specific'))
    def get_specific(self, id_value, collection):
        self.logger.debug(f'Get specific item for id: {id_value} from {collection}')
        self.collection = self.client[self.db_name][collection]
        return self.collection.find_one({Constants.DB_ID_KEY: id_value})

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_get_all'))
    def get_all(self):
        self.logger.debug(f'Get all called')
        return self.convert_cursor_to_array(self.collection.find())

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_find'))
    def find(self, key, value):
        self.logger.debug(f'Find called key: {key} val: {value}')
        return self.collection.find_one({key: value})

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_count'))
    def count(self):
        self.logger.debug('Count called')
        return self.collection.find().count(True)

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_purge'))
    def purge(self):
        self.logger.debug('Purge called')
        return self.collection.drop()

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(Settings.SERVICE_NAME, 'mongo_read'))
    def read(self, offset, limit, query):
        self.logger.debug(f'Read called offset: {offset} limit: {limit} query: {query}')
        count = self.collection.find(query).count()
        cursor = self.collection.find(query).skip(offset).limit(limit)
        return self.convert_cursor_to_array(cursor), offset, limit, count

    @log_exception
    @monitor(monitor_name=MonitoringProvider.get_monitor_prefix(
        Settings.SERVICE_NAME, 'mongo_delete'))
    def delete(self, key):
        self.logger.debug(f'Delete called id: {key}')
        result = self.collection.delete_one({Constants.DB_ID_KEY: ObjectId(key)})
        return result.deleted_count == 1

    @log_exception
    def delete_db(self):
        self.logger.debug('Drop db called.')
        self.client.drop_database(self.db_name)

    @log_exception
    def get_server_info(self):
        self.logger.debug('Queries DB for server info')
        return self.client.server_info()

    @staticmethod
    def convert_cursor_to_array(cursor):
        documents = []
        if cursor is not None:
            for document in cursor:
                documents.append(document)
        return documents

    @staticmethod
    def get_collection_name(model):
        if model:
            if isinstance(model, str):
                return model
            return model.__name__
        return 'not_set'

    def get_status(self):
        pass

    def filter(self, **kwargs):
        offset, limit, query = get_query(**kwargs)
        return self.read(offset, limit, query)
Exemplo n.º 17
0
 def __init__(self, data_client):
     self.data_client = data_client
     self.logger = Logger()
Exemplo n.º 18
0
class DataHandler:
    def __init__(self, data_client):
        self.data_client = data_client
        self.logger = Logger()

    @log_exception
    def handle_get_request_single(self, item_id):
        item = self.data_client.get(item_id)
        if item:
            return Constants.SUCCESS_RESPONSE_CODE, self.to_json(item)
        return Constants.RESOURCE_NOT_FOUND_CODE, Constants.RESOURCE_NOT_FOUND_MESSAGE

    def handle_get_request(self, request=None):
        try:
            result = []
            items, offset, limit, count = self.get_filtered_data(request)
            for item in items:
                result.append(item)
            data = OrderedDict()
            data[Settings.SERVICE_NAME] = result
            data['offset'] = offset
            data['limit'] = limit
            data['total'] = count

            if limit & limit < 0:
                raise ValueError
            return Constants.SUCCESS_RESPONSE_CODE, self.to_json(data)
        # pylint: disable=broad-except
        except (ValueError, Exception) as ex:
            self.logger.error(f'Error in general handle_get_request ex: {ex}',
                              exc_info=True)
            return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE

    def get_filtered_data(self, request):
        if request:
            return self.data_client.filter(**request.args)
        return self.data_client.filter()

    @log_exception
    def handle_post_request(self, payload):
        if payload is None:
            return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE
        if self.data_client.create(payload):
            return Constants.CREATED_SUCCESS_CODE, self.to_json(payload)
        error = "Failed to create new item: {}".format(payload)
        return error

    @log_exception
    def handle_restore_request(self, payload):
        if payload is None:
            return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE
        if self.data_client.restore(payload):
            return Constants.CREATED_SUCCESS_CODE, self.to_json(payload)
        error = "Failed to restore items: {}".format(payload)
        return error

    @log_exception
    def handle_count_request(self):
        return Constants.SUCCESS_RESPONSE_CODE, self.to_json(
            self.data_client.count())

    @log_exception
    def handle_purge_request(self):
        self.data_client.purge()
        return Constants.SUCCESS_RESPONSE_CODE, Constants.PURGE_REQUEST_MESSAGE

    @log_exception
    def handle_delete_request(self, item_id):
        result = self.data_client.delete(item_id)
        if result:
            return Constants.SUCCESS_RESPONSE_CODE, Constants.DELETE_REQUEST_MESSAGE
        return Constants.RESOURCE_NOT_FOUND_CODE, Constants.RESOURCE_NOT_FOUND_MESSAGE

    @log_exception
    def handle_update_request(self, item_id, payload):
        if payload is None:
            return Constants.BAD_REQUEST_CODE, Constants.BAD_REQUEST_MESSAGE
        if self.data_client.delete(item_id):
            return self.handle_post_request(payload)
        return Constants.RESOURCE_NOT_FOUND_CODE, Constants.RESOURCE_NOT_FOUND_MESSAGE

    @staticmethod
    @log_exception
    def to_json(model):
        return json.dumps(model, default=str)