Example #1
0
    def compute_session_result(self, session_id: int, alert_operator: str,
                               alert_threshold: str,
                               result_data: pandas.DataFrame):
        """Compute aggregated results for the indicator session."""
        log.info('Compute session results.')
        nb_records = len(result_data)
        nb_records_alert = len(result_data.loc[result_data['Alert'] == True])  # pylint: disable=C0121
        nb_records_no_alert = len(
            result_data.loc[result_data['Alert'] == False])  # pylint: disable=C0121

        # Post results to database
        mutation = '''mutation{createSessionResult(input:{sessionResult:{
        alertOperator:"alert_operator",alertThreshold:alert_threshold,nbRecords:nb_records,
        nbRecordsAlert:nb_records_alert,nbRecordsNoAlert:nb_records_no_alert,sessionId:session_id}}){sessionResult{id}}}'''

        # Use replace() instead of format() because of curly braces
        mutation = mutation.replace('alert_operator', alert_operator)
        mutation = mutation.replace('alert_threshold', str(alert_threshold))
        mutation = mutation.replace(
            'nb_records_no_alert', str(nb_records_no_alert)
        )  # Order matters to avoid replacing other strings nb_records
        mutation = mutation.replace(
            'nb_records_alert', str(nb_records_alert)
        )  # Order matters to avoid replacing other strings nb_records
        mutation = mutation.replace(
            'nb_records', str(nb_records)
        )  # Order matters to avoid replacing other strings nb_records
        mutation = mutation.replace('session_id', str(session_id))
        utils.execute_graphql_request(mutation)

        return nb_records_alert
Example #2
0
    def get_data_frame(self, data_source: pandas.DataFrame, request: str,
                       dimensions: str, measures: str):
        """Get data from data source. Return a formatted data frame according to dimensions and measures parameters."""
        # Get data source credentials
        query = '{dataSourceByName(name:"data_source"){id,connectionString,login,dataSourceTypeId}}'
        query = query.replace('data_source', data_source)
        response = utils.execute_graphql_request(query)

        # Get connection object
        if response['data']['dataSourceByName']:
            data_source_id = response['data']['dataSourceByName']['id']
            data_source_type_id = response['data']['dataSourceByName'][
                'dataSourceTypeId']
            connection_string = response['data']['dataSourceByName'][
                'connectionString']
            login = response['data']['dataSourceByName']['login']

        # Get data source password
        query = 'query{allDataSourcePasswords(condition:{id:data_source_id}){nodes{password}}}'
        query = query.replace(
            'data_source_id', str(data_source_id)
        )  # Use replace() instead of format() because of curly braces
        response = utils.execute_graphql_request(query)

        if response['data']['allDataSourcePasswords']['nodes'][0]:
            data_source = response['data']['allDataSourcePasswords']['nodes'][
                0]
            password = data_source['password']

            log.info('Connect to data source.')
            data_source = DataSource()
            connection = data_source.get_connection(data_source_type_id,
                                                    connection_string, login,
                                                    password)
        else:
            error_message = f'Data source {data_source} does not exist.'
            log.error(error_message)
            raise Exception(error_message)

        # Get data frame
        log.info('Execute request on data source.')
        data_frame = pandas.read_sql(request, connection)
        connection.close()

        if data_frame.empty:
            error_message = f'Request on data source {data_source} returned no data.'
            log.error(error_message)
            log.debug('Request: %s.', request)
            raise Exception(error_message)

        # Format data frame
        log.debug('Format data frame.')
        column_names = dimensions + measures
        data_frame.columns = column_names
        for column in dimensions:
            data_frame[column] = data_frame[column].astype(
                str)  # Convert dimension values to string

        return data_frame
Example #3
0
    def test(self, data_source_id):
        log.info(
            'Test connectivity to data source Id {data_source_id}.'.format(
                data_source_id=data_source_id))

        # Get data source
        log.debug('Get data source.')
        query = '''query{dataSourceById(id:data_source_id){dataSourceTypeId,connectionString,login,password}}'''
        query = query.replace(
            'data_source_id', str(data_source_id)
        )  # Use replace() instead of format() because of curly braces
        response = utils.execute_graphql_request(query)

        if response['data']['dataSourceById']:
            data_source = response['data']['dataSourceById']
            data_source_type_id = data_source['dataSourceTypeId']
            connection_string = data_source['connectionString']
            login = data_source['login']
            password = data_source['password']

            # Test connectivity
            try:
                log.debug('Connect to data source.')
                self.get_connection(data_source_type_id, connection_string,
                                    login, password)

                log.info('Connection to data source succeeded.')
                mutation = '''mutation{updateDataSourceById(input:{id:data_source_id,dataSourcePatch:{connectivityStatus:"Success"}}){dataSource{connectivityStatus}}}'''
                mutation = mutation.replace(
                    'data_source_id', str(data_source_id)
                )  # Use replace() instead of format() because of curly braces
                utils.execute_graphql_request(mutation)

            except Exception:
                log.error('Connection to data source failed.')
                error_message = traceback.format_exc()
                log.error(error_message)

                # Update connectivity status
                mutation = '''mutation{updateDataSourceById(input:{id:data_source_id,dataSourcePatch:{connectivityStatus:"Failed"}}){dataSource{connectivityStatus}}}'''
                mutation = mutation.replace(
                    'data_source_id', str(data_source_id)
                )  # Use replace() instead of format() because of curly braces
                utils.execute_graphql_request(mutation)

        else:
            error_message = 'Data source Id {data_source_id} does not exist.'.format(
                data_source_id=data_source_id)
            log.error(error_message)
            raise Exception(error_message)
Example #4
0
    def post(self):
        """
        Execute GraphQL queries and mutations
        Use this endpoint to send http request to the GraphQL API.
        """
        payload = request.json

        # Execute request on GraphQL API
        status, data = utils.execute_graphql_request(payload['query'])

        # Execute batch of indicators
        if status == 200 and 'executeBatch' in payload['query']:
            if 'id' in data['data']['executeBatch']['batch']:
                batch_id = str(data['data']['executeBatch']['batch']['id'])
                batch = Batch()
                batch.execute(batch_id)
            else:
                message = "Batch Id attribute is mandatory in the payload to be able to trigger the batch execution. Example: {'query': 'mutation{executeBatch(input:{indicatorGroupId:1}){batch{id}}}'"
                abort(400, message)

        # Test connectivity to a data source
        if status == 200 and 'testDataSource' in payload['query']:
            if 'id' in data['data']['testDataSource']['dataSource']:
                data_source_id = str(
                    data['data']['testDataSource']['dataSource']['id'])
                data_source = DataSource()
                data = data_source.test(data_source_id)
            else:
                message = "Data Source Id attribute is mandatory in the payload to be able to test the connectivity. Example: {'query': 'mutation{testDataSource(input:{dataSourceId:1}){dataSource{id}}}'"
                abort(400, message)

        if status == 200:
            return jsonify(data)
        else:
            abort(500, data)
Example #5
0
    def update_session_status(self, authorization: str, session_id: int, session_status: str):
        """Update a session status."""

        query = 'mutation updateSessionStatus($id: Int!, $sessionPatch: SessionPatch!){updateSessionById(input:{id: $id, sessionPatch: $sessionPatch}){session{status}}}'
        variables = {'id': session_id, 'sessionPatch': {'status': session_status}}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        return response
Example #6
0
def update_session_status(session_id: int, session_status: str):
    """Update a session status."""
    mutation = '''mutation{updateSessionById(input:{id:session_id,sessionPatch:{status:"session_status"}}){session{status}}}'''
    mutation = mutation.replace('session_id', str(
        session_id))  # Use replace() instead of format() because of curly braces
    # Use replace() instead of format() because of curly braces
    mutation = mutation.replace('session_status', str(session_status))
    data = utils.execute_graphql_request(mutation)
    return data
Example #7
0
    def update_batch_status(self, authorization: str, batch_id: int,
                            batch_status: str):
        """Update a batch status."""

        query = 'mutation updateBatchStatus($id: Int!, $batchPatch: BatchPatch!){updateBatchById(input:{id: $id, batchPatch: $batchPatch}){batch{status}}}'
        variables = {'id': batch_id, 'batchPatch': {'status': batch_status}}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        return response
Example #8
0
    def verify_indicator_parameters(self, authorization: str,
                                    indicator_type_id: int,
                                    parameters: List[dict]):
        """Verify if the list of indicator parameters is valid and return them as a dictionary."""

        # Build dictionary of parameter types referential
        query = 'query{allParameterTypes{nodes{id, name}}}'
        payload = {'query': query}
        response = utils.execute_graphql_request(authorization, payload)

        parameter_types_referential = {}
        for parameter_type in response['data']['allParameterTypes']['nodes']:
            parameter_types_referential[
                parameter_type['id']] = parameter_type['name']

        # Build dictionary of indicator parameters
        indicator_parameters = {}
        for parameter in parameters:
            indicator_parameters[
                parameter['parameterTypeId']] = parameter['value']

        # Verify mandatory parameters exist
        # Alert operator, Alert threshold, Distribution list, Dimensions, Measures, Target, Target request
        missing_parameters = []
        for parameter_type_id in [1, 2, 3, 4, 5, 8, 9]:
            if parameter_type_id not in indicator_parameters:
                parameter_type = parameter_types_referential[parameter_type_id]
                missing_parameters.append(parameter_type)

        # Verify parameters specific to completeness and latency indicator types
        # Source, Source request
        if indicator_type_id in [
                IndicatorType.COMPLETENESS, IndicatorType.LATENCY
        ]:
            for parameter_type_id in [6, 7]:
                if parameter_type_id not in indicator_parameters:
                    parameter_type = parameter_types_referential[
                        parameter_type_id]
                    missing_parameters.append(parameter_type)

        if missing_parameters:
            missing_parameters = ', '.join(missing_parameters)
            error_message = f'Missing parameters: {missing_parameters}.'
            log.error(error_message)
            raise Exception(error_message)

        # Convert distribution list, dimensions and measures parameters to python list
        indicator_parameters[3] = literal_eval(
            indicator_parameters[3])  # Distribution list
        indicator_parameters[4] = literal_eval(
            indicator_parameters[4])  # Dimensions
        indicator_parameters[5] = literal_eval(
            indicator_parameters[5])  # Measures

        return indicator_parameters
Example #9
0
 def update_batch_status(self, batch_id: int, batch_status: str):
     """Update a batch status."""
     mutation = '''mutation{updateBatchById(input:{id:batch_id,batchPatch:{status:"batch_status"}}){batch{status}}}'''
     mutation = mutation.replace(
         'batch_id', str(batch_id)
     )  # Use replace() instead of format() because of curly braces
     mutation = mutation.replace(
         'batch_status', str(batch_status)
     )  # Use replace() instead of format() because of curly braces
     data = utils.execute_graphql_request(mutation)
     return data
Example #10
0
    def compute_session_result(self, authorization: str, session_id: int, alert_operator: str, alert_threshold: str, result_data: pandas.DataFrame):
        """Compute aggregated results for the indicator session."""

        log.info('Compute session results.')
        nb_records = len(result_data)
        nb_records_alert = len(result_data.loc[result_data['Alert'] == True]) # pylint: disable=C0121
        nb_records_no_alert = len(result_data.loc[result_data['Alert'] == False]) # pylint: disable=C0121

        # Post results to database
        query = 'mutation updateSessionResults($id: Int!, $sessionPatch: SessionPatch!){updateSessionById(input:{id: $id, sessionPatch: $sessionPatch}){session{id}}}'
        variables = {}
        variables['id'] = session_id
        variables['sessionPatch'] = {}
        variables['sessionPatch']['alertOperator'] = alert_operator
        variables['sessionPatch']['alertThreshold'] = float(alert_threshold)  # Alert threshold is stored as string in parameters and needs to be converted to float
        variables['sessionPatch']['nbRecordsNoAlert'] = nb_records_no_alert
        variables['sessionPatch']['nbRecordsAlert'] = nb_records_alert
        variables['sessionPatch']['nbRecords'] = nb_records
        payload = {'query': query, 'variables': variables}
        utils.execute_graphql_request(authorization, payload)

        return nb_records_alert
Example #11
0
 def update_batch_status(self, authorization: str, batch_id: int,
                         batch_status: str):
     """Update a batch status."""
     mutation = 'mutation{updateBatchById(input:{id:batch_id,batchPatch:{status:"batch_status"}}){batch{status}}}'
     mutation = mutation.replace(
         'batch_id', str(batch_id)
     )  # Use replace() instead of format() because of curly braces
     mutation = mutation.replace(
         'batch_status', str(batch_status)
     )  # Use replace() instead of format() because of curly braces
     mutation = {'query': mutation}  # Convert to dictionary
     data = utils.execute_graphql_request(authorization, mutation)
     return data
Example #12
0
    def get_data_frame(self, data_source, request, dimensions, measures):
        """Get data from data source. Return a formatted data frame according to dimensions and measures parameters."""
        # Get data source credentials
        query = '''{dataSourceByName(name:"data_source"){connectionString,login,password,dataSourceTypeId}}'''
        query = query.replace('data_source', data_source)
        response = utils.execute_graphql_request(query)

        # Get connection object
        if response['data']['dataSourceByName']:
            data_source_type_id = response['data']['dataSourceByName'][
                'dataSourceTypeId']
            connection_string = response['data']['dataSourceByName'][
                'connectionString']
            login = response['data']['dataSourceByName']['login']
            password = response['data']['dataSourceByName']['password']

            log.info('Connect to data source {data_source}.'.format(
                data_source=data_source))
            data_source = DataSource()
            connection = data_source.get_connection(data_source_type_id,
                                                    connection_string, login,
                                                    password)
        else:
            error_message = 'Data source {data_source} does not exist.'.format(
                data_source=data_source)
            log.error(error_message)
            raise Exception(error_message)

        # Get data frame
        log.info(
            'Execute request on data source.'.format(data_source=data_source))
        data_frame = pandas.read_sql(request, connection)
        connection.close()

        if data_frame.empty:
            error_message = 'Request on data source {data_source} returned no data.'.format(
                data_source=data_source)
            log.error(error_message)
            log.debug('Request: {request}.'.format(request=request))
            raise Exception(error_message)

        # Format data frame
        log.debug('Format data frame.')
        column_names = dimensions + measures
        data_frame.columns = column_names
        for column in dimensions:
            data_frame[column] = data_frame[column].astype(
                str)  # Convert dimension values to string

        return data_frame
Example #13
0
    def get_data_frame(self, authorization: str, data_source: pandas.DataFrame,
                       request: str, dimensions: str, measures: str):
        """Get data from data source. Return a formatted data frame according to dimensions and measures parameters."""

        # Get data source credentials
        query = 'query getDataSource($name: String!){dataSourceByName(name: $name){id, connectionString, login, dataSourceTypeId}}'
        variables = {'name': data_source}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        # Get connection object
        if response['data']['dataSourceByName']:
            data_source_id = response['data']['dataSourceByName']['id']
            data_source_type_id = response['data']['dataSourceByName'][
                'dataSourceTypeId']
            connection_string = response['data']['dataSourceByName'][
                'connectionString']
            login = response['data']['dataSourceByName']['login']

        # Get data source password
        data_source = DataSource()
        password = data_source.get_password(authorization, data_source_id)

        # Connect to data source
        log.info('Connect to data source.')
        connection = data_source.get_connection(data_source_type_id,
                                                connection_string, login,
                                                password)

        # Get data frame
        log.info('Execute request on data source.')
        data_frame = pandas.read_sql(request, connection)
        connection.close()

        if data_frame.empty:
            error_message = f'Request on data source {data_source} returned no data.'
            log.error(error_message)
            log.debug('Request: %s.', request)
            raise Exception(error_message)

        # Format data frame
        log.debug('Format data frame.')
        column_names = dimensions + measures
        data_frame.columns = column_names
        for column in dimensions:
            data_frame[column] = data_frame[column].astype(
                str)  # Convert dimension values to string

        return data_frame
Example #14
0
    def get_password(self, authorization: str, data_source_id: int):
        """Get unencrypted password of a data source. Return the password."""

        query = 'query getDataSourcePassword($id: Int){allDataSourcePasswords(condition:{id: $id}){nodes{password}}}'
        variables = {'id': data_source_id}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        if response['data']['allDataSourcePasswords']['nodes']:
            data_source = response['data']['allDataSourcePasswords']['nodes'][0]
            password = data_source['password']

        else:
            error_message = f'Data source {data_source_id} does not exist.'
            log.error(error_message)
            raise Exception(error_message)

        return password
Example #15
0
    def test(self, authorization: str, data_source_id: int):
        """Test connectivity to a data source and update its connectivity status."""
        log.info('Test connectivity to data source Id %i.', data_source_id)

        # Set connectivity test to running
        query = 'mutation updateDataSourceStatus($id: Int!, $dataSourcePatch: DataSourcePatch!){updateDataSourceById(input:{id: $id, dataSourcePatch: $dataSourcePatch}){dataSource{connectivityStatus}}}'
        variables = {'id': data_source_id, 'dataSourcePatch': {'connectivityStatus': 'Running'}}
        payload = {'query': query, 'variables': variables}
        utils.execute_graphql_request(authorization, payload)

        # Get data source
        log.debug('Get data source.')
        query = 'query getDataSource($id: Int!){dataSourceById(id: $id){dataSourceTypeId, connectionString, login}}'
        variables = {'id': data_source_id}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        if response['data']['dataSourceById']:
            data_source = response['data']['dataSourceById']
            data_source_type_id = data_source['dataSourceTypeId']
            connection_string = data_source['connectionString']
            login = data_source['login']

        # Get data source password
        password = self.get_password(authorization, data_source_id)

        # Test connectivity
        try:
            log.debug('Connect to data source.')
            self.get_connection(data_source_type_id, connection_string, login, password)

            log.info('Connection to data source succeeded.')
            query = 'mutation updateDataSourceStatus($id: Int!, $dataSourcePatch: DataSourcePatch!){updateDataSourceById(input:{id: $id, dataSourcePatch: $dataSourcePatch}){dataSource{connectivityStatus}}}'
            variables = {'id': data_source_id, 'dataSourcePatch': {'connectivityStatus': 'Success'}}
            payload = {'query': query, 'variables': variables}
            utils.execute_graphql_request(authorization, payload)

        except Exception:  # Pylint: disable=broad-except
            log.error('Connection to data source failed.')
            error_message = traceback.format_exc()
            log.error(error_message)

            # Update connectivity status
            query = 'mutation updateDataSourceStatus($id: Int!, $dataSourcePatch: DataSourcePatch!){updateDataSourceById(input:{id: $id, dataSourcePatch: $dataSourcePatch}){dataSource{connectivityStatus}}}'
            variables = {'id': data_source_id, 'dataSourcePatch': {'connectivityStatus': 'Failed'}}
            payload = {'query': query, 'variables': variables}
            utils.execute_graphql_request(authorization, payload)
Example #16
0
    def test(self, data_source_id):
        container_name = 'data-quality-test-data-source-{data_source_id}'.format(
            data_source_id=data_source_id)
        client = docker.from_env()
        client.containers.run(
            name=container_name,
            image='data-quality-scripts',
            network='data-quality-network',
            links={'data-quality-graphql': 'data-quality-graphql'},
            command=['python', 'run.py', 'test_data_source', data_source_id],
            stream=True,
            remove=True)

        # Get connectivity test result
        query = '''query{dataSourceById(id:data_source_id){id,connectivityStatus}}'''
        query = query.replace(
            'data_source_id', str(data_source_id)
        )  # Use replace() instead of format() because of curly braces
        data = utils.execute_graphql_request(query)

        return data
Example #17
0
    def execute(self, authorization: str, batch_id: int):
        log.info('Start execution of batch Id %i.', batch_id)

        # Get list of indicator sessions
        log.debug('Get list of indicator sessions.')
        query = 'query{allSessions(condition:{batchId:batch_id},orderBy:ID_ASC){nodes{id,batchId,indicatorId,userGroupId,indicatorByIndicatorId{name,indicatorTypeId,indicatorTypeByIndicatorTypeId{module,class,method},parametersByIndicatorId{nodes{parameterTypeId,value}}}}}}'
        query = query.replace(
            'batch_id', str(batch_id)
        )  # Use replace() instead of format() because of curly braces
        query = {'query': query}  # Convert to dictionary
        response = utils.execute_graphql_request(authorization, query)

        if response['data']['allSessions']['nodes']:
            # Update batch status to running
            log.debug('Update batch status to Running.')
            self.update_batch_status(authorization, batch_id, 'Running')
            is_error = False  # Variable used to update batch status to Failed if one indicator fails

            # For each indicator session execute corresponding method
            for session in response['data']['allSessions']['nodes']:
                try:
                    module_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['module']
                    class_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['class']
                    method_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['method']
                    class_instance = getattr(sys.modules[module_name],
                                             class_name)()
                    getattr(class_instance, method_name)(authorization,
                                                         session)

                except Exception:  # pylint: disable=broad-except
                    is_error = True
                    error_message = traceback.format_exc()
                    log.error(error_message)

                    # Update session status
                    session_id = session['id']
                    update_session_status(authorization, session_id, 'Failed')

                    # Get error context and send error e-mail
                    indicator_id = session['indicatorId']
                    indicator_name = session['indicatorByIndicatorId']['name']
                    for parameter in session['indicatorByIndicatorId'][
                            'parametersByIndicatorId']['nodes']:
                        if parameter[
                                'parameterTypeId'] == 3:  # Distribution list
                            distribution_list = literal_eval(
                                parameter['value'])
                            utils.send_error(indicator_id, indicator_name,
                                             session_id, distribution_list,
                                             error_message)

            # Update batch status
            if is_error:
                log.debug('Update batch status to Failed.')
                self.update_batch_status(authorization, batch_id, 'Failed')
                log.warning('Batch Id %i completed with errors.', batch_id)
            else:
                log.debug('Update batch status to Success.')
                self.update_batch_status(authorization, batch_id, 'Success')
                log.info('Batch Id %i completed successfully.', batch_id)

        else:
            error_message = f'Batch Id {batch_id} does not exist or has no indicator session.'
            log.error(error_message)
            raise Exception(error_message)
Example #18
0
    def execute(self, authorization: str, batch_id: int):
        log.info('Start execution of batch Id %i.', batch_id)

        # Get list of indicator sessions
        log.debug('Get list of indicator sessions.')
        query = 'query getAllSessions($batchId: Int){allSessions(condition:{batchId: $batchId}, orderBy:ID_ASC){nodes{id, batchId, indicatorId, userGroupId, indicatorByIndicatorId{name, indicatorTypeId, indicatorTypeByIndicatorTypeId{module, class, method}, parametersByIndicatorId{nodes{parameterTypeId, value}}}}}}'
        variables = {'batchId': batch_id}
        payload = {'query': query, 'variables': variables}
        response = utils.execute_graphql_request(authorization, payload)

        if response['data']['allSessions']['nodes']:
            # Update batch status to running
            log.debug('Update batch status to Running.')
            self.update_batch_status(authorization, batch_id, 'Running')
            is_error = False  # Variable used to update batch status to Failed if one indicator fails

            # Loop over each indicator session
            for session in response['data']['allSessions']['nodes']:
                try:
                    # Recreate custom log handler to add session Id to context
                    root_log = logging.getLogger()
                    custom_handler = root_log.handlers[1]
                    root_log.removeHandler(custom_handler)
                    root_log.addHandler(
                        utils.CustomLogHandler(authorization,
                                               batch_id=batch_id,
                                               session_id=session['id']))

                    # For each session execute indicator type method
                    module_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['module']
                    class_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['class']
                    method_name = session['indicatorByIndicatorId'][
                        'indicatorTypeByIndicatorTypeId']['method']
                    class_instance = getattr(sys.modules[module_name],
                                             class_name)()
                    getattr(class_instance, method_name)(authorization,
                                                         session)

                except Exception:  # pylint: disable=broad-except
                    is_error = True
                    error_message = traceback.format_exc()
                    log.error(error_message)

                    # Update session status
                    session_id = session['id']
                    Session().update_session_status(authorization, session_id,
                                                    'Failed')

                    # Get error context and send error e-mail
                    indicator_id = session['indicatorId']
                    indicator_name = session['indicatorByIndicatorId']['name']
                    for parameter in session['indicatorByIndicatorId'][
                            'parametersByIndicatorId']['nodes']:
                        if parameter[
                                'parameterTypeId'] == 3:  # Distribution list
                            distribution_list = literal_eval(
                                parameter['value'])
                            utils.send_error(indicator_id, indicator_name,
                                             session_id, distribution_list,
                                             error_message)

            # Update batch status
            if is_error:
                log.debug('Update batch status to Failed.')
                self.update_batch_status(authorization, batch_id, 'Failed')
                log.warning('Batch Id %i completed with errors.', batch_id)
            else:
                log.debug('Update batch status to Success.')
                self.update_batch_status(authorization, batch_id, 'Success')
                log.info('Batch Id %i completed successfully.', batch_id)

        else:
            error_message = f'Batch Id {batch_id} does not exist or has no indicator session.'
            log.error(error_message)
            raise Exception(error_message)
Example #19
0
    def test(self, authorization: str, data_source_id: int):
        """Test connectivity to a data source and update its connectivity status."""
        log.info('Test connectivity to data source Id %i.', data_source_id)

        # Get data source
        log.debug('Get data source.')
        query = 'query{dataSourceById(id:data_source_id){dataSourceTypeId,connectionString,login}}'
        query = query.replace(
            'data_source_id', str(data_source_id)
        )  # Use replace() instead of format() because of curly braces
        query = {'query': query}  # Convert to dictionary
        response = utils.execute_graphql_request(authorization, query)

        if response['data']['dataSourceById']:
            data_source = response['data']['dataSourceById']
            data_source_type_id = data_source['dataSourceTypeId']
            connection_string = data_source['connectionString']
            login = data_source['login']

        # Get data source password
        query = 'query{allDataSourcePasswords(condition:{id:data_source_id}){nodes{password}}}'
        query = query.replace(
            'data_source_id', str(data_source_id)
        )  # Use replace() instead of format() because of curly braces
        query = {'query': query}  # Convert to dictionary
        response = utils.execute_graphql_request(authorization, query)

        if response['data']['allDataSourcePasswords']['nodes'][0]:
            data_source = response['data']['allDataSourcePasswords']['nodes'][
                0]
            password = data_source['password']

            # Test connectivity
            try:
                log.debug('Connect to data source.')
                self.get_connection(data_source_type_id, connection_string,
                                    login, password)

                log.info('Connection to data source succeeded.')
                mutation = 'mutation{updateDataSourceById(input:{id:data_source_id,dataSourcePatch:{connectivityStatus:"Success"}}){dataSource{connectivityStatus}}}'
                mutation = mutation.replace(
                    'data_source_id', str(data_source_id)
                )  # Use replace() instead of format() because of curly braces
                mutation = {'query': mutation}  # Convert to dictionary
                utils.execute_graphql_request(authorization, mutation)

            except Exception:  # Pylint: disable=broad-except
                log.error('Connection to data source failed.')
                error_message = traceback.format_exc()
                log.error(error_message)

                # Update connectivity status
                mutation = 'mutation{updateDataSourceById(input:{id:data_source_id,dataSourcePatch:{connectivityStatus:"Failed"}}){dataSource{connectivityStatus}}}'
                mutation = mutation.replace(
                    'data_source_id', str(data_source_id)
                )  # Use replace() instead of format() because of curly braces
                mutation = {'query': mutation}  # Convert to dictionary
                utils.execute_graphql_request(authorization, mutation)

        else:
            error_message = f'Data source Id {data_source_id} does not exist.'
            log.error(error_message)
            raise Exception(error_message)