Example #1
0
def put_table_description() -> Response:

    @action_logging
    def _log_put_table_description(*, table_key: str, description: str, source: str) -> None:
        pass  # pragma: no cover

    try:
        args = request.get_json()
        table_endpoint = _get_table_endpoint()

        table_key = get_query_param(args, 'key')

        description = get_query_param(args, 'description')
        src = get_query_param(args, 'source')

        table_uri = TableUri.from_uri(table_key)
        if not is_table_editable(table_uri.schema, table_uri.table):
            return make_response('', HTTPStatus.FORBIDDEN)

        url = '{0}/{1}/description'.format(table_endpoint, table_key)
        _log_put_table_description(table_key=table_key, description=description, source=src)

        response = request_metadata(url=url, method='PUT', data=json.dumps({'description': description}))
        status_code = response.status_code

        if status_code == HTTPStatus.OK:
            message = 'Success'
        else:
            message = 'Update table description failed'

        payload = jsonify({'msg': message})
        return make_response(payload, status_code)
    except Exception as e:
        payload = jsonify({'msg': 'Encountered exception: ' + str(e)})
        return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)
Example #2
0
    def test_from_uri_factory(self) -> None:
        params = [('db', 'cluster', 'schema', 'table'),
                  ('db_underscore', 'cluster.with.dots', 'schema',
                   'table/with/slashes'),
                  ('db.dot', 'cluster.dot', 'schema', 'table.dot'),
                  ('hive_table', 'demo', 'test_schema', 'test_table')]

        for db, cluster, schema, table in params:
            with self.subTest():
                _uri = f'{db}://{cluster}.{schema}/{table}'
                uri = TableUri.from_uri(_uri)
                self.assertEqual(db, uri.database)
                self.assertEqual(cluster, uri.cluster)
                self.assertEqual(schema, uri.schema)
                self.assertEqual(table, uri.table)
Example #3
0
 def test_simple_constructor(self) -> None:
     uri = TableUri("db", "clstr", "schm", "tbl")
     self.assertEqual('db://clstr.schm/tbl', str(uri))
Example #4
0
 def test_from_uri_factory(self) -> None:
     uri = TableUri.from_uri("db://clstr.with.dots.schm/tbl/with/slashes")
     self.assertEqual(uri.database, 'db')
     self.assertEqual(uri.cluster, 'clstr.with.dots')
     self.assertEqual(uri.schema, 'schm')
     self.assertEqual(uri.table, 'tbl/with/slashes')
Example #5
0
def _update_search_tag(table_key: str, method: str, tag: str) -> int:
    """
    call the search service endpoint to get whole table information uniquely identified by table_key
    update tags list, call search service endpoint again to write back the updated field
    TODO: we should update dashboard tag in the future
    :param table_key: table key e.g. 'database://cluster.schema/table'
    :param method: PUT or DELETE
    :param tag: tag name to be put/delete
    :return: HTTP status code
    """
    searchservice_base = app.config['SEARCHSERVICE_BASE']
    searchservice_get_table_url = f'{searchservice_base}/search_table'

    # searchservice currently doesn't allow colon or / inside filters, thus can't get item based on key
    # table key e.g: 'database://cluster.schema/table'
    table_uri = TableUri.from_uri(table_key)

    request_param_map = {
        'search_request': {
            'type': 'AND',
            'filters': {
                'database': [table_uri.database],
                'schema': [table_uri.schema],
                'table': [table_uri.table],
                'cluster': [table_uri.cluster]
            }
        },
        'query_term': ''
    }

    get_table_response = request_search(url=searchservice_get_table_url,
                                        method='POST',
                                        json=request_param_map)
    get_status_code = get_table_response.status_code
    if get_status_code != HTTPStatus.OK:
        LOGGER.info(
            f'Fail to get table info from serviceservice, http status code: {get_status_code}'
        )
        LOGGER.debug(get_table_response.text)
        return get_status_code

    raw_data_map = json.loads(get_table_response.text)
    # key is unique, thus (database, cluster, schema, table) should uniquely identify the table
    if len(raw_data_map['results']) > 1:
        LOGGER.error(f'Error! Duplicate table key: {table_key}')
    table = raw_data_map['results'][0]

    old_tags_list = table['tags']
    new_tags_list = [item for item in old_tags_list if item['tag_name'] != tag]
    if method != 'DELETE':
        new_tags_list.append({'tag_name': tag})
    table['tags'] = new_tags_list

    # remove None values
    pruned_table = {k: v for k, v in table.items() if v is not None}

    post_param_map = {"data": pruned_table}
    searchservice_update_url = f'{searchservice_base}/document_table'
    update_table_response = request_search(url=searchservice_update_url,
                                           method='PUT',
                                           json=post_param_map)
    update_status_code = update_table_response.status_code
    if update_status_code != HTTPStatus.OK:
        LOGGER.info(
            f'Fail to update table info in searchservice, http status code: {update_status_code}'
        )
        LOGGER.debug(update_table_response.text)
        return update_table_response.status_code

    return HTTPStatus.OK