Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
88391aa8
Commit
88391aa8
authored
Mar 03, 2015
by
Venkatesh Seetharam
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BUG-32592 Add REST API for Search DSL. Contributed by Venkatesh Seetharam
parent
9d01934b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
115 additions
and
21 deletions
+115
-21
MetadataDiscoveryResource.java
...oop/metadata/web/resources/MetadataDiscoveryResource.java
+89
-21
BaseResourceIT.java
.../apache/hadoop/metadata/web/resources/BaseResourceIT.java
+26
-0
MetadataDiscoveryResourceIT.java
...p/metadata/web/resources/MetadataDiscoveryResourceIT.java
+0
-0
No files found.
webapp/src/main/java/org/apache/hadoop/metadata/web/resources/MetadataDiscoveryResource.java
View file @
88391aa8
...
@@ -19,10 +19,8 @@
...
@@ -19,10 +19,8 @@
package
org
.
apache
.
hadoop
.
metadata
.
web
.
resources
;
package
org
.
apache
.
hadoop
.
metadata
.
web
.
resources
;
import
com.google.common.base.Preconditions
;
import
com.google.common.base.Preconditions
;
import
org.apache.hadoop.metadata.discovery.DiscoveryException
;
import
org.apache.hadoop.metadata.MetadataException
;
import
org.apache.hadoop.metadata.discovery.DiscoveryService
;
import
org.apache.hadoop.metadata.discovery.DiscoveryService
;
import
org.apache.hadoop.metadata.types.TypeSystem
;
import
org.apache.hadoop.metadata.web.util.Servlets
;
import
org.apache.hadoop.metadata.web.util.Servlets
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONException
;
import
org.codehaus.jettison.json.JSONException
;
...
@@ -41,7 +39,6 @@ import javax.ws.rs.QueryParam;
...
@@ -41,7 +39,6 @@ import javax.ws.rs.QueryParam;
import
javax.ws.rs.WebApplicationException
;
import
javax.ws.rs.WebApplicationException
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.Response
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -64,9 +61,7 @@ public class MetadataDiscoveryResource {
...
@@ -64,9 +61,7 @@ public class MetadataDiscoveryResource {
private
final
DiscoveryService
discoveryService
;
private
final
DiscoveryService
discoveryService
;
public
static
final
String
RESULTS
=
"results"
;
public
static
final
String
RESULTS
=
"results"
;
public
static
final
String
TOTAL_SIZE
=
"totalSize"
;
// public static final String TOTAL_SIZE = "totalSize";
public
static
final
List
<
String
>
typesList
=
TypeSystem
.
getInstance
().
getTypeNames
();
/**
/**
* Created by the Guice ServletModule and injected with the
* Created by the Guice ServletModule and injected with the
...
@@ -78,11 +73,80 @@ public class MetadataDiscoveryResource {
...
@@ -78,11 +73,80 @@ public class MetadataDiscoveryResource {
public
MetadataDiscoveryResource
(
DiscoveryService
discoveryService
)
{
public
MetadataDiscoveryResource
(
DiscoveryService
discoveryService
)
{
this
.
discoveryService
=
discoveryService
;
this
.
discoveryService
=
discoveryService
;
}
}
/**
* Search using query DSL.
*
* @param query search query in raw gremlin or DSL format falling back to full text.
* @return JSON representing the type and results.
*/
@GET
@GET
@Path
(
"search
/gremlin/{gremlinQuery}
"
)
@Path
(
"search"
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
Response
searchUsingGremlinQuery
(
@PathParam
(
"gremlinQuery"
)
String
gremlinQuery
)
{
public
Response
search
(
@QueryParam
(
"query"
)
String
query
)
{
Preconditions
.
checkNotNull
(
query
,
"query cannot be null"
);
if
(
query
.
startsWith
(
"g."
))
{
// raw gremlin query
return
searchUsingGremlinQuery
(
query
);
}
try
{
JSONObject
response
=
new
JSONObject
();
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
response
.
put
(
"query"
,
query
);
try
{
// fall back to dsl
final
String
jsonResult
=
discoveryService
.
searchByDSL
(
query
);
response
.
put
(
"queryType"
,
"dsl"
);
response
.
put
(
RESULTS
,
new
JSONObject
(
jsonResult
));
}
catch
(
Throwable
throwable
)
{
LOG
.
error
(
"Unable to get entity list for query {} using dsl"
,
query
,
throwable
);
// todo: fall back to full text search
response
.
put
(
"queryType"
,
"full-text"
);
response
.
put
(
RESULTS
,
new
JSONObject
());
}
return
Response
.
ok
(
response
).
build
();
}
catch
(
JSONException
e
)
{
LOG
.
error
(
"Unable to get entity list for query {}"
,
query
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
}
}
@GET
@Path
(
"search/dsl"
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
Response
searchUsingQueryDSL
(
@QueryParam
(
"query"
)
String
dslQuery
)
{
Preconditions
.
checkNotNull
(
dslQuery
,
"dslQuery cannot be null"
);
try
{
final
String
jsonResult
=
discoveryService
.
searchByDSL
(
dslQuery
);
JSONObject
response
=
new
JSONObject
();
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
response
.
put
(
"query"
,
dslQuery
);
response
.
put
(
"queryType"
,
"dsl"
);
response
.
put
(
RESULTS
,
new
JSONObject
(
jsonResult
));
return
Response
.
ok
(
response
).
build
();
}
catch
(
DiscoveryException
e
)
{
LOG
.
error
(
"Unable to get entity list for dslQuery {}"
,
dslQuery
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
BAD_REQUEST
));
}
catch
(
JSONException
e
)
{
LOG
.
error
(
"Unable to get entity list for dslQuery {}"
,
dslQuery
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
}
}
@GET
@Path
(
"search/gremlin"
)
@Produces
(
MediaType
.
APPLICATION_JSON
)
public
Response
searchUsingGremlinQuery
(
@QueryParam
(
"query"
)
String
gremlinQuery
)
{
Preconditions
.
checkNotNull
(
gremlinQuery
,
"gremlinQuery cannot be null"
);
Preconditions
.
checkNotNull
(
gremlinQuery
,
"gremlinQuery cannot be null"
);
try
{
try
{
...
@@ -90,15 +154,17 @@ public class MetadataDiscoveryResource {
...
@@ -90,15 +154,17 @@ public class MetadataDiscoveryResource {
JSONObject
response
=
new
JSONObject
();
JSONObject
response
=
new
JSONObject
();
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
response
.
put
(
"query"
,
gremlinQuery
);
response
.
put
(
"queryType"
,
"gremlin"
);
JSONArray
list
=
new
JSONArray
();
JSONArray
list
=
new
JSONArray
();
for
(
Map
<
String
,
String
>
result
:
results
)
{
for
(
Map
<
String
,
String
>
result
:
results
)
{
list
.
put
(
new
JSONObject
(
result
));
list
.
put
(
new
JSONObject
(
result
));
}
}
response
.
put
(
"results"
,
list
);
response
.
put
(
RESULTS
,
list
);
return
Response
.
ok
(
response
).
build
();
return
Response
.
ok
(
response
).
build
();
}
catch
(
Metadata
Exception
e
)
{
}
catch
(
Discovery
Exception
e
)
{
LOG
.
error
(
"Unable to get entity list for gremlinQuery {}"
,
gremlinQuery
,
e
);
LOG
.
error
(
"Unable to get entity list for gremlinQuery {}"
,
gremlinQuery
,
e
);
throw
new
WebApplicationException
(
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
BAD_REQUEST
));
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
BAD_REQUEST
));
...
@@ -110,7 +176,7 @@ public class MetadataDiscoveryResource {
...
@@ -110,7 +176,7 @@ public class MetadataDiscoveryResource {
}
}
/**
/**
* Return a list of Vertices and Edges that em
i
nate from the provided GUID to the depth specified.
* Return a list of Vertices and Edges that em
a
nate from the provided GUID to the depth specified.
*
*
* GET http://host/api/metadata/discovery/search/relationships/{guid}
* GET http://host/api/metadata/discovery/search/relationships/{guid}
*
*
...
@@ -122,7 +188,8 @@ public class MetadataDiscoveryResource {
...
@@ -122,7 +188,8 @@ public class MetadataDiscoveryResource {
@Path
(
"/search/relationships/{guid}"
)
@Path
(
"/search/relationships/{guid}"
)
@Produces
({
MediaType
.
APPLICATION_JSON
})
@Produces
({
MediaType
.
APPLICATION_JSON
})
public
Response
getLineageResults
(
@PathParam
(
"guid"
)
final
String
guid
,
public
Response
getLineageResults
(
@PathParam
(
"guid"
)
final
String
guid
,
@DefaultValue
(
"1"
)
@QueryParam
(
"depth"
)
final
int
depth
,
@QueryParam
(
"edgesToFollow"
)
final
String
edgesToFollow
)
{
@DefaultValue
(
"1"
)
@QueryParam
(
"depth"
)
final
int
depth
,
@QueryParam
(
"edgesToFollow"
)
final
String
edgesToFollow
)
{
LOG
.
info
(
"Performing GUID lineage search for guid= {}"
,
guid
);
LOG
.
info
(
"Performing GUID lineage search for guid= {}"
,
guid
);
Preconditions
.
checkNotNull
(
guid
,
"Invalid argument: \"guid\" cannot be null."
);
Preconditions
.
checkNotNull
(
guid
,
"Invalid argument: \"guid\" cannot be null."
);
...
@@ -161,7 +228,8 @@ public class MetadataDiscoveryResource {
...
@@ -161,7 +228,8 @@ public class MetadataDiscoveryResource {
@Path
(
"/search/fulltext"
)
@Path
(
"/search/fulltext"
)
@Produces
({
MediaType
.
APPLICATION_JSON
})
@Produces
({
MediaType
.
APPLICATION_JSON
})
public
Response
getFullTextResults
(
@QueryParam
(
"text"
)
final
String
searchText
,
public
Response
getFullTextResults
(
@QueryParam
(
"text"
)
final
String
searchText
,
@DefaultValue
(
"1"
)
@QueryParam
(
"depth"
)
final
int
depth
,
@DefaultValue
(
"guid"
)
@QueryParam
(
"property"
)
final
String
prop
)
{
@DefaultValue
(
"1"
)
@QueryParam
(
"depth"
)
final
int
depth
,
@DefaultValue
(
"guid"
)
@QueryParam
(
"property"
)
final
String
prop
)
{
LOG
.
info
(
"Performing full text search for vertices with property {} matching= {}"
,
prop
,
searchText
);
LOG
.
info
(
"Performing full text search for vertices with property {} matching= {}"
,
prop
,
searchText
);
Preconditions
.
checkNotNull
(
searchText
,
"Invalid argument: \"text\" cannot be null."
);
Preconditions
.
checkNotNull
(
searchText
,
"Invalid argument: \"text\" cannot be null."
);
...
@@ -170,7 +238,8 @@ public class MetadataDiscoveryResource {
...
@@ -170,7 +238,8 @@ public class MetadataDiscoveryResource {
// Parent JSON Object
// Parent JSON Object
JSONObject
response
=
new
JSONObject
();
JSONObject
response
=
new
JSONObject
();
Map
<
String
,
HashMap
<
String
,
JSONObject
>>
resultMap
=
discoveryService
.
textSearch
(
searchText
,
depth
,
prop
);
Map
<
String
,
HashMap
<
String
,
JSONObject
>>
resultMap
=
discoveryService
.
textSearch
(
searchText
,
depth
,
prop
);
try
{
try
{
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
response
.
put
(
"requestId"
,
Thread
.
currentThread
().
getName
());
...
@@ -182,7 +251,8 @@ public class MetadataDiscoveryResource {
...
@@ -182,7 +251,8 @@ public class MetadataDiscoveryResource {
}
}
}
catch
(
JSONException
e
)
{
}
catch
(
JSONException
e
)
{
throw
new
WebApplicationException
(
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
"Search: Error building JSON result set."
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
Servlets
.
getErrorResponse
(
"Search: Error building JSON result set."
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
}
}
LOG
.
debug
(
"JSON result:"
+
response
.
toString
());
LOG
.
debug
(
"JSON result:"
+
response
.
toString
());
...
@@ -202,19 +272,17 @@ public class MetadataDiscoveryResource {
...
@@ -202,19 +272,17 @@ public class MetadataDiscoveryResource {
@Path
(
"/getIndexedFields"
)
@Path
(
"/getIndexedFields"
)
@Produces
({
MediaType
.
APPLICATION_JSON
})
@Produces
({
MediaType
.
APPLICATION_JSON
})
public
Response
getLineageResults
()
{
public
Response
getLineageResults
()
{
JSONObject
response
=
new
JSONObject
();
JSONObject
response
=
new
JSONObject
();
try
{
try
{
response
.
put
(
"indexed_fields:"
,
discoveryService
.
getGraphIndexedFields
());
response
.
put
(
"indexed_fields:"
,
discoveryService
.
getGraphIndexedFields
());
}
catch
(
JSONException
e
)
{
}
catch
(
JSONException
e
)
{
throw
new
WebApplicationException
(
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
"Search: Error building JSON result set."
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
Servlets
.
getErrorResponse
(
"Search: Error building JSON result set."
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
}
}
LOG
.
debug
(
"JSON result:"
+
response
.
toString
());
LOG
.
debug
(
"JSON result:"
+
response
.
toString
());
return
Response
.
ok
(
response
).
build
();
return
Response
.
ok
(
response
).
build
();
}
}
}
}
webapp/src/test/java/org/apache/hadoop/metadata/web/resources/BaseResourceIT.java
View file @
88391aa8
...
@@ -20,6 +20,7 @@ package org.apache.hadoop.metadata.web.resources;
...
@@ -20,6 +20,7 @@ package org.apache.hadoop.metadata.web.resources;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableList
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
org.apache.hadoop.metadata.types.AttributeDefinition
;
import
org.apache.hadoop.metadata.types.AttributeDefinition
;
...
@@ -29,8 +30,13 @@ import org.apache.hadoop.metadata.types.IDataType;
...
@@ -29,8 +30,13 @@ import org.apache.hadoop.metadata.types.IDataType;
import
org.apache.hadoop.metadata.types.Multiplicity
;
import
org.apache.hadoop.metadata.types.Multiplicity
;
import
org.apache.hadoop.metadata.types.TraitType
;
import
org.apache.hadoop.metadata.types.TraitType
;
import
org.apache.hadoop.metadata.types.TypeSystem
;
import
org.apache.hadoop.metadata.types.TypeSystem
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.testng.Assert
;
import
org.testng.annotations.BeforeClass
;
import
org.testng.annotations.BeforeClass
;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriBuilder
;
import
javax.ws.rs.core.UriBuilder
;
public
abstract
class
BaseResourceIT
{
public
abstract
class
BaseResourceIT
{
...
@@ -52,6 +58,26 @@ public abstract class BaseResourceIT {
...
@@ -52,6 +58,26 @@ public abstract class BaseResourceIT {
service
=
client
.
resource
(
UriBuilder
.
fromUri
(
baseUrl
).
build
());
service
=
client
.
resource
(
UriBuilder
.
fromUri
(
baseUrl
).
build
());
}
}
protected
void
sumbitType
(
String
typesAsJSON
,
String
type
)
throws
Exception
{
WebResource
resource
=
service
.
path
(
"api/metadata/types/submit"
)
.
path
(
type
);
ClientResponse
clientResponse
=
resource
.
accept
(
MediaType
.
APPLICATION_JSON
)
.
type
(
MediaType
.
APPLICATION_JSON
)
.
method
(
HttpMethod
.
POST
,
ClientResponse
.
class
,
typesAsJSON
);
Assert
.
assertEquals
(
clientResponse
.
getStatus
(),
Response
.
Status
.
OK
.
getStatusCode
());
String
responseAsString
=
clientResponse
.
getEntity
(
String
.
class
);
Assert
.
assertNotNull
(
responseAsString
);
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertEquals
(
response
.
get
(
"typeName"
),
type
);
Assert
.
assertNotNull
(
response
.
get
(
"types"
));
Assert
.
assertNotNull
(
response
.
get
(
"requestId"
));
}
protected
AttributeDefinition
createUniqueRequiredAttrDef
(
String
name
,
protected
AttributeDefinition
createUniqueRequiredAttrDef
(
String
name
,
IDataType
dataType
)
{
IDataType
dataType
)
{
return
new
AttributeDefinition
(
name
,
dataType
.
getName
(),
return
new
AttributeDefinition
(
name
,
dataType
.
getName
(),
...
...
webapp/src/test/java/org/apache/hadoop/metadata/web/resources/MetadataDiscoveryResourceIT.java
View file @
88391aa8
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment