Explorar el Código

HUE-4932 [metadata] Add list_tags to the metadata API

Romain Rigaux hace 9 años
padre
commit
dd34d2d

+ 8 - 0
apps/metastore/src/metastore/templates/metastore.mako

@@ -1172,6 +1172,14 @@ ${ sqlContextPopover.sqlContextPopover() }
 
 <script type="text/javascript" charset="utf-8">
 
+  function list_tags() {
+    $.post("${ url('metadata:list_tags') }", { // '/metadata/api/navigator/list_tags/'
+      // prefix: 'bla'
+    }, function(data) {
+      console.log(JSON.stringify(data));
+    });
+  }
+
   function pieChartDataTransformer(rawDatum) {
     var _data = [];
     $(rawDatum.counts).each(function (cnt, item) {

+ 18 - 0
desktop/libs/metadata/src/metadata/navigator_api.py

@@ -85,6 +85,24 @@ def search_entities(request):
   return JsonResponse(response)
 
 
+@error_handler
+def list_tags(request):
+  api = NavigatorApi()
+
+  prefix = request.POST.get('prefix')
+  offset = request.POST.get('offset', 0)
+  limit = request.POST.get('limit', 100)
+
+  data = api.search_entities_interactive(facetFields=['tags'], facetPrefix=prefix, limit=0, offset=offset)
+
+  response = {
+    'tags': data['facets']['tags'],
+    'status': 0
+  }
+
+  return JsonResponse(response)
+
+
 @error_handler
 def find_entity(request):
   response = {'status': -1}

+ 35 - 5
desktop/libs/metadata/src/metadata/navigator_client.py

@@ -20,14 +20,15 @@ import json
 import logging
 import re
 
-from desktop.lib.rest.http_client import HttpClient, RestException
 from desktop.lib.rest import resource
+from desktop.lib.rest.http_client import HttpClient, RestException
 
 from hadoop.conf import HDFS_CLUSTERS
 
 from metadata.conf import NAVIGATOR
 
 
+_JSON_CONTENT_TYPE = 'application/json'
 LOG = logging.getLogger(__name__)
 VERSION = 'v9'
 
@@ -57,7 +58,7 @@ class NavigatorApi(object):
 
     self._client = HttpClient(self._api_url, logger=LOG)
     self._client.set_basic_auth(self._username, self._password)
-    self._root = resource.Resource(self._client)
+    self._root = resource.Resource(self._client, urlencode=False) # For search_entities_interactive
 
     self.__headers = {}
     self.__params = ()
@@ -65,13 +66,12 @@ class NavigatorApi(object):
 
   def search_entities(self, query_s, limit=100, offset=0, **filters):
     """
-    GET /api/v3/entities?query=()
-    http://cloudera.github.io/navigator/apidocs/v3/path__v3_entities.html
+    Solr edismax query parser syntax.
+
     :param query_s: a query string of search terms (e.g. - sales quarterly);
       Currently the search will perform an OR boolean search for all terms (split on whitespace), against a whitelist
       of search_fields.
       TODO: support smarter boolean searching with arbitrary ordering and precedence of conditionals
-    :param filters: TODO: IMPLEMENT ME, required to support property search
     """
     search_fields = ('originalName', 'originalDescription', 'name', 'description', 'tags')
     entity_types = ('DATABASE', 'TABLE', 'PARTITION', 'FIELD', 'FILE', 'OPERATION')
@@ -112,6 +112,36 @@ class NavigatorApi(object):
       raise NavigatorApiException(msg)
 
 
+  def search_entities_interactive(self, query=None, limit=100, offset=0, facetFields=None, facetPrefix=None, facetRanges=None, filterQueries=None, firstClassEntitiesOnly=None):
+    try:
+      pagination = {
+        'offset': offset,
+        'limit': limit,
+      }
+
+      body = {'query': query or '*'}
+
+      if facetFields is not None:
+        body['facetFields'] = facetFields
+      if facetPrefix is not None:
+        body['facetPrefix'] = facetPrefix
+      if facetRanges is not None:
+        body['facetRanges'] = query
+      if filterQueries is not None:
+        body['filterQueries'] = query
+      if firstClassEntitiesOnly is not None:
+        body['firstClassEntitiesOnly'] = firstClassEntitiesOnly
+
+      print json.dumps(body)
+      response = self._root.post('interactive/entities?limit=%(limit)s&offset=%(offset)s' % pagination, data=json.dumps(body), contenttype=_JSON_CONTENT_TYPE)
+
+      return response
+    except RestException, e:
+      msg = 'Failed to search for entities with search query: %s' % body
+      LOG.exception(msg)
+      raise NavigatorApiException(msg)
+
+
   def find_entity(self, source_type, type, name, **filters):
     """
     GET /api/v3/entities?query=((sourceType:<source_type>)AND(type:<type>)AND(originalName:<name>))

+ 1 - 0
desktop/libs/metadata/src/metadata/urls.py

@@ -25,6 +25,7 @@ urlpatterns = patterns('metadata.navigator_api',
   url(r'^api/navigator/get_entity/?$', 'get_entity', name='get_entity'),
   url(r'^api/navigator/add_tags/?$', 'add_tags', name='add_tags'),
   url(r'^api/navigator/delete_tags/?$', 'delete_tags', name='delete_tags'),
+  url(r'^api/navigator/list_tags/?$', 'list_tags', name='list_tags'),
   url(r'^api/navigator/update_properties/?$', 'update_properties', name='update_properties'),
   url(r'^api/navigator/delete_properties/?$', 'delete_properties', name='delete_properties'),
   url(r'^api/navigator/lineage/?$', 'get_lineage', name='get_lineage'),