Commit 1776b1f1 by Suma Shivaprasad

BUG-36928 - Changes response code for CREATE to return 201 and also the…

BUG-36928 - Changes response code for CREATE to return 201 and also the definition is relevant cases. BUG-36938 - Changed error response to JSON
parent f4547da3
...@@ -155,7 +155,7 @@ public class HiveMetaStoreBridge { ...@@ -155,7 +155,7 @@ public class HiveMetaStoreBridge {
String entityJSON = InstanceSerialization.toJson(referenceable, true); String entityJSON = InstanceSerialization.toJson(referenceable, true);
LOG.debug("Submitting new entity {} = {}", referenceable.getTypeName(), entityJSON); LOG.debug("Submitting new entity {} = {}", referenceable.getTypeName(), entityJSON);
JSONObject jsonObject = metadataServiceClient.createEntity(entityJSON); JSONObject jsonObject = metadataServiceClient.createEntity(entityJSON);
String guid = jsonObject.getString(MetadataServiceClient.RESULTS); String guid = jsonObject.getString(MetadataServiceClient.GUID);
LOG.debug("created instance for type " + typeName + ", guid: " + guid); LOG.debug("created instance for type " + typeName + ", guid: " + guid);
return new Referenceable(guid, referenceable.getTypeName(), null); return new Referenceable(guid, referenceable.getTypeName(), null);
......
...@@ -49,13 +49,18 @@ import static org.apache.hadoop.metadata.security.SecurityProperties.TLS_ENABLED ...@@ -49,13 +49,18 @@ import static org.apache.hadoop.metadata.security.SecurityProperties.TLS_ENABLED
*/ */
public class MetadataServiceClient { public class MetadataServiceClient {
private static final Logger LOG = LoggerFactory.getLogger(MetadataServiceClient.class); private static final Logger LOG = LoggerFactory.getLogger(MetadataServiceClient.class);
public static final String NAME = "name";
public static final String URI = "id";
public static final String GUID = "GUID";
public static final String DEFINITION = "definition";
public static final String ERROR = "error";
public static final String REQUEST_ID = "requestId"; public static final String REQUEST_ID = "requestId";
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";
private static final String BASE_URI = "api/metadata/"; public static final String BASE_URI = "api/metadata/";
private static final String URI_TYPES = "types"; public static final String URI_TYPES = "types";
private static final String URI_ENTITIES = "entities"; public static final String URI_ENTITIES = "entities";
private static final String URI_TRAITS = "traits"; public static final String URI_TRAITS = "traits";
private static final String URI_SEARCH = "discovery/search"; private static final String URI_SEARCH = "discovery/search";
private WebResource service; private WebResource service;
...@@ -86,6 +91,7 @@ public class MetadataServiceClient { ...@@ -86,6 +91,7 @@ public class MetadataServiceClient {
} }
static enum API { static enum API {
//Type operations //Type operations
CREATE_TYPE(BASE_URI + URI_TYPES, HttpMethod.POST), CREATE_TYPE(BASE_URI + URI_TYPES, HttpMethod.POST),
GET_TYPE(BASE_URI + URI_TYPES, HttpMethod.GET), GET_TYPE(BASE_URI + URI_TYPES, HttpMethod.GET),
...@@ -96,7 +102,7 @@ public class MetadataServiceClient { ...@@ -96,7 +102,7 @@ public class MetadataServiceClient {
CREATE_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.POST), CREATE_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.POST),
GET_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.GET), GET_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.GET),
UPDATE_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.PUT), UPDATE_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.PUT),
LIST_ENTITY(BASE_URI + URI_ENTITIES + "?type=", HttpMethod.GET), LIST_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.GET),
//Trait operations //Trait operations
ADD_TRAITS(BASE_URI + URI_TRAITS, HttpMethod.POST), ADD_TRAITS(BASE_URI + URI_TRAITS, HttpMethod.POST),
...@@ -128,7 +134,7 @@ public class MetadataServiceClient { ...@@ -128,7 +134,7 @@ public class MetadataServiceClient {
public List<String> listTypes() throws MetadataServiceException { public List<String> listTypes() throws MetadataServiceException {
try { try {
final JSONObject jsonObject = callAPI(API.LIST_TYPES, null); final JSONObject jsonObject = callAPI(API.LIST_TYPES, Response.Status.OK, null);
final JSONArray list = jsonObject.getJSONArray(MetadataServiceClient.RESULTS); final JSONArray list = jsonObject.getJSONArray(MetadataServiceClient.RESULTS);
ArrayList<String> types = new ArrayList<>(); ArrayList<String> types = new ArrayList<>();
for (int index = 0; index < list.length(); index++) { for (int index = 0; index < list.length(); index++) {
...@@ -144,7 +150,7 @@ public class MetadataServiceClient { ...@@ -144,7 +150,7 @@ public class MetadataServiceClient {
public String getType(String typeName) throws MetadataServiceException { public String getType(String typeName) throws MetadataServiceException {
WebResource resource = getResource(API.GET_TYPE, typeName); WebResource resource = getResource(API.GET_TYPE, typeName);
try { try {
JSONObject response = callAPIWithResource(API.GET_TYPE, resource); JSONObject response = callAPIWithResource(API.GET_TYPE, resource, Response.Status.OK);
return response.getString("definition"); return response.getString("definition");
} catch (MetadataServiceException e) { } catch (MetadataServiceException e) {
if (e.getStatus() == ClientResponse.Status.NOT_FOUND) { if (e.getStatus() == ClientResponse.Status.NOT_FOUND) {
...@@ -163,7 +169,7 @@ public class MetadataServiceClient { ...@@ -163,7 +169,7 @@ public class MetadataServiceClient {
* @throws MetadataServiceException * @throws MetadataServiceException
*/ */
public JSONObject createType(String typeAsJson) throws MetadataServiceException { public JSONObject createType(String typeAsJson) throws MetadataServiceException {
return callAPI(API.CREATE_TYPE, typeAsJson); return callAPI(API.CREATE_TYPE, typeAsJson, Response.Status.CREATED);
} }
/** /**
...@@ -173,7 +179,7 @@ public class MetadataServiceClient { ...@@ -173,7 +179,7 @@ public class MetadataServiceClient {
* @throws MetadataServiceException * @throws MetadataServiceException
*/ */
public JSONObject createEntity(String entityAsJson) throws MetadataServiceException { public JSONObject createEntity(String entityAsJson) throws MetadataServiceException {
return callAPI(API.CREATE_ENTITY, entityAsJson); return callAPI(API.CREATE_ENTITY, entityAsJson, Response.Status.CREATED);
} }
/** /**
...@@ -183,9 +189,9 @@ public class MetadataServiceClient { ...@@ -183,9 +189,9 @@ public class MetadataServiceClient {
* @throws MetadataServiceException * @throws MetadataServiceException
*/ */
public Referenceable getEntity(String guid) throws MetadataServiceException { public Referenceable getEntity(String guid) throws MetadataServiceException {
JSONObject jsonResponse = callAPI(API.GET_ENTITY, null, guid); JSONObject jsonResponse = callAPI(API.GET_ENTITY, null, Response.Status.OK, guid);
try { try {
String entityInstanceDefinition = jsonResponse.getString(MetadataServiceClient.RESULTS); String entityInstanceDefinition = jsonResponse.getString(MetadataServiceClient.GUID);
return InstanceSerialization.fromJsonReferenceable(entityInstanceDefinition, true); return InstanceSerialization.fromJsonReferenceable(entityInstanceDefinition, true);
} catch (JSONException e) { } catch (JSONException e) {
throw new MetadataServiceException(e); throw new MetadataServiceException(e);
...@@ -195,7 +201,7 @@ public class MetadataServiceClient { ...@@ -195,7 +201,7 @@ public class MetadataServiceClient {
public JSONObject searchEntity(String searchQuery) throws MetadataServiceException { public JSONObject searchEntity(String searchQuery) throws MetadataServiceException {
WebResource resource = getResource(API.SEARCH); WebResource resource = getResource(API.SEARCH);
resource = resource.queryParam("query", searchQuery); resource = resource.queryParam("query", searchQuery);
return callAPIWithResource(API.SEARCH, resource); return callAPIWithResource(API.SEARCH, resource, Response.Status.OK);
} }
/** /**
...@@ -225,7 +231,7 @@ public class MetadataServiceClient { ...@@ -225,7 +231,7 @@ public class MetadataServiceClient {
public JSONArray searchByDSL(String query) throws MetadataServiceException { public JSONArray searchByDSL(String query) throws MetadataServiceException {
WebResource resource = getResource(API.SEARCH_DSL); WebResource resource = getResource(API.SEARCH_DSL);
resource = resource.queryParam("query", query); resource = resource.queryParam("query", query);
JSONObject result = callAPIWithResource(API.SEARCH_DSL, resource); JSONObject result = callAPIWithResource(API.SEARCH_DSL, resource, Response.Status.OK);
try { try {
return result.getJSONObject("results").getJSONArray("rows"); return result.getJSONObject("results").getJSONArray("rows");
} catch (JSONException e) { } catch (JSONException e) {
...@@ -242,7 +248,7 @@ public class MetadataServiceClient { ...@@ -242,7 +248,7 @@ public class MetadataServiceClient {
public JSONObject searchByGremlin(String gremlinQuery) throws MetadataServiceException { public JSONObject searchByGremlin(String gremlinQuery) throws MetadataServiceException {
WebResource resource = getResource(API.SEARCH_GREMLIN); WebResource resource = getResource(API.SEARCH_GREMLIN);
resource = resource.queryParam("query", gremlinQuery); resource = resource.queryParam("query", gremlinQuery);
return callAPIWithResource(API.SEARCH_GREMLIN, resource); return callAPIWithResource(API.SEARCH_GREMLIN, resource, Response.Status.OK);
} }
/** /**
...@@ -254,7 +260,7 @@ public class MetadataServiceClient { ...@@ -254,7 +260,7 @@ public class MetadataServiceClient {
public JSONObject searchByFullText(String query) throws MetadataServiceException { public JSONObject searchByFullText(String query) throws MetadataServiceException {
WebResource resource = getResource(API.SEARCH_FULL_TEXT); WebResource resource = getResource(API.SEARCH_FULL_TEXT);
resource = resource.queryParam("query", query); resource = resource.queryParam("query", query);
return callAPIWithResource(API.SEARCH_FULL_TEXT, resource); return callAPIWithResource(API.SEARCH_FULL_TEXT, resource, Response.Status.OK);
} }
public String getRequestId(JSONObject json) throws MetadataServiceException { public String getRequestId(JSONObject json) throws MetadataServiceException {
...@@ -275,19 +281,20 @@ public class MetadataServiceClient { ...@@ -275,19 +281,20 @@ public class MetadataServiceClient {
return resource; return resource;
} }
private JSONObject callAPIWithResource(API api, WebResource resource) throws MetadataServiceException { private JSONObject callAPIWithResource(API api, WebResource resource, Response.Status expectedStatus) throws MetadataServiceException {
return callAPIWithResource(api, resource, null); return callAPIWithResource(api, resource, null, expectedStatus);
} }
private JSONObject callAPIWithResource(API api, WebResource resource, Object requestObject) private JSONObject callAPIWithResource(API api, WebResource resource, Object requestObject, Response.Status expectedStatus)
throws MetadataServiceException { throws MetadataServiceException {
ClientResponse clientResponse = resource ClientResponse clientResponse = resource
.accept(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON)
.method(api.getMethod(), ClientResponse.class, requestObject); .method(api.getMethod(), ClientResponse.class, requestObject);
if (clientResponse.getStatus() == Response.Status.OK.getStatusCode()) { if (clientResponse.getStatus() == expectedStatus.getStatusCode()) {
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
System.out.println("response : " + responseAsString);
try { try {
return new JSONObject(responseAsString); return new JSONObject(responseAsString);
} catch (JSONException e) { } catch (JSONException e) {
...@@ -299,8 +306,8 @@ public class MetadataServiceClient { ...@@ -299,8 +306,8 @@ public class MetadataServiceClient {
} }
private JSONObject callAPI(API api, Object requestObject, private JSONObject callAPI(API api, Object requestObject,
String... pathParams) throws MetadataServiceException { Response.Status expectedStatus, String... pathParams) throws MetadataServiceException {
WebResource resource = getResource(api, pathParams); WebResource resource = getResource(api, pathParams);
return callAPIWithResource(api, resource, requestObject); return callAPIWithResource(api, resource, requestObject, expectedStatus);
} }
} }
...@@ -93,18 +93,15 @@ public class DefaultMetadataService implements MetadataService { ...@@ -93,18 +93,15 @@ public class DefaultMetadataService implements MetadataService {
if(typesDef.isEmpty()) if(typesDef.isEmpty())
throw new MetadataException("Invalid type definition"); throw new MetadataException("Invalid type definition");
Map<String, IDataType> typesAdded = typeSystem.defineTypes(typesDef); final Map<String, IDataType> typesAdded = typeSystem.defineTypes(typesDef);
//TODO how do we handle transaction - store failure?? //TODO how do we handle transaction - store failure??
typeStore.store(typeSystem, ImmutableList.copyOf(typesAdded.keySet())); typeStore.store(typeSystem, ImmutableList.copyOf(typesAdded.keySet()));
onTypesAddedToRepo(typesAdded); onTypesAddedToRepo(typesAdded);
JSONObject response = new JSONObject() {{
JSONObject response = new JSONObject(); put("types", typesAdded.keySet());
for (Map.Entry<String, IDataType> entry : typesAdded.entrySet()) { }};
response.put(entry.getKey(), entry.getValue().getName());
}
return response; return response;
} catch (JSONException e) { } catch (JSONException e) {
LOG.error("Unable to create response for types={}", typeDefinition, e); LOG.error("Unable to create response for types={}", typeDefinition, e);
......
...@@ -49,6 +49,8 @@ public class GuiceServletConfig extends GuiceServletContextListener { ...@@ -49,6 +49,8 @@ public class GuiceServletConfig extends GuiceServletContextListener {
static final String HTTP_AUTHENTICATION_ENABLED = "metadata.http.authentication.enabled"; static final String HTTP_AUTHENTICATION_ENABLED = "metadata.http.authentication.enabled";
private Injector injector; private Injector injector;
public static final String BASE_URI = "/api/metadata/";
@Override @Override
protected Injector getInjector() { protected Injector getInjector() {
LOG.info("Loading Guice modules"); LOG.info("Loading Guice modules");
...@@ -77,7 +79,7 @@ public class GuiceServletConfig extends GuiceServletContextListener { ...@@ -77,7 +79,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put(PackagesResourceConfig.PROPERTY_PACKAGES, packages); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, packages);
serve("/api/metadata/*").with(GuiceContainer.class, params); serve(BASE_URI + "*").with(GuiceContainer.class, params);
} }
private void configureAuthenticationFilter() throws ConfigurationException { private void configureAuthenticationFilter() throws ConfigurationException {
......
...@@ -33,11 +33,13 @@ import javax.inject.Inject; ...@@ -33,11 +33,13 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context; import javax.ws.rs.core.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Entity management operations as REST API. * Entity management operations as REST API.
...@@ -50,12 +52,13 @@ import java.util.List; ...@@ -50,12 +52,13 @@ import java.util.List;
public class EntityResource { public class EntityResource {
private static final Logger LOG = LoggerFactory.getLogger(EntityResource.class); private static final Logger LOG = LoggerFactory.getLogger(EntityResource.class);
private static final String GUID = "GUID";
private static final String TRAIT_NAME = "traitName"; private static final String TRAIT_NAME = "traitName";
private final MetadataService metadataService; private final MetadataService metadataService;
@Context
UriInfo uriInfo;
/** /**
* Created by the Guice ServletModule and injected with the * Created by the Guice ServletModule and injected with the
* configured MetadataService. * configured MetadataService.
...@@ -79,11 +82,17 @@ public class EntityResource { ...@@ -79,11 +82,17 @@ public class EntityResource {
LOG.debug("submitting entity {} ", entity); LOG.debug("submitting entity {} ", entity);
final String guid = metadataService.createEntity(entity); final String guid = metadataService.createEntity(entity);
UriBuilder ub = uriInfo.getAbsolutePathBuilder();
URI locationURI = ub.path(guid).build();
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(MetadataServiceClient.RESULTS, guid); response.put(MetadataServiceClient.GUID, guid);
response.put(MetadataServiceClient.URI, locationURI.toURL().toExternalForm());
response.put(MetadataServiceClient.DEFINITION, entity);
return Response.ok(response).build(); return Response.created(locationURI).entity(response).build();
} catch (MetadataException | IOException | IllegalArgumentException e) { } catch (MetadataException | IOException | IllegalArgumentException e) {
LOG.error("Unable to persist entity instance", e); LOG.error("Unable to persist entity instance", e);
throw new WebApplicationException( throw new WebApplicationException(
...@@ -112,30 +121,26 @@ public class EntityResource { ...@@ -112,30 +121,26 @@ public class EntityResource {
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(GUID, guid); response.put(MetadataServiceClient.GUID, guid);
Response.Status status = Response.Status.NOT_FOUND; Response.Status status = Response.Status.NOT_FOUND;
if (entityDefinition != null) { if (entityDefinition != null) {
response.put(MetadataServiceClient.RESULTS, entityDefinition); response.put(MetadataServiceClient.DEFINITION, entityDefinition);
status = Response.Status.OK; status = Response.Status.OK;
} else {
response.put(MetadataServiceClient.ERROR, JSONObject.quote(String.format("An entity with GUID={%s} does not exist", guid)));
} }
return Response.status(status).entity(response).build(); return Response.status(status).entity(response).build();
} catch (MetadataException | IllegalArgumentException e) { } catch (MetadataException | IllegalArgumentException e) {
LOG.error("An entity with GUID={} does not exist", guid, e); LOG.error("An entity with GUID={} does not exist", guid, e);
throw new WebApplicationException(e, Response throw new WebApplicationException(
.status(Response.Status.NOT_FOUND) Servlets.getErrorResponse(e, Response.Status.NOT_FOUND));
.entity(e.getMessage())
.type(MediaType.APPLICATION_JSON)
.build());
} catch (JSONException e) { } catch (JSONException e) {
LOG.error("Unable to get instance definition for GUID {}", guid, e); LOG.error("Unable to get instance definition for GUID {}", guid, e);
throw new WebApplicationException(e, Response throw new WebApplicationException(
.status(Response.Status.INTERNAL_SERVER_ERROR) Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
.entity(e.getMessage())
.type(MediaType.APPLICATION_JSON)
.build());
} }
} }
...@@ -223,7 +228,7 @@ public class EntityResource { ...@@ -223,7 +228,7 @@ public class EntityResource {
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(GUID, guid); response.put(MetadataServiceClient.GUID, guid);
response.put(MetadataServiceClient.RESULTS, new JSONArray(traitNames)); response.put(MetadataServiceClient.RESULTS, new JSONArray(traitNames));
response.put(MetadataServiceClient.TOTAL_SIZE, traitNames.size()); response.put(MetadataServiceClient.TOTAL_SIZE, traitNames.size());
...@@ -257,12 +262,16 @@ public class EntityResource { ...@@ -257,12 +262,16 @@ public class EntityResource {
LOG.debug("Adding trait={} for entity={} ", traitDefinition, guid); LOG.debug("Adding trait={} for entity={} ", traitDefinition, guid);
metadataService.addTrait(guid, traitDefinition); metadataService.addTrait(guid, traitDefinition);
UriBuilder ub = uriInfo.getAbsolutePathBuilder();
URI locationURI = ub.path(guid).build();
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(GUID, guid); response.put(MetadataServiceClient.GUID, guid);
response.put("traitInstance", traitDefinition); response.put(MetadataServiceClient.URI, locationURI.toURL().toExternalForm());
response.put(MetadataServiceClient.DEFINITION, traitDefinition);
return Response.ok(response).build(); return Response.created(locationURI).entity(response).build();
} catch (MetadataException | IOException | IllegalArgumentException e) { } catch (MetadataException | IOException | IllegalArgumentException e) {
LOG.error("Unable to add trait for entity={}", guid, e); LOG.error("Unable to add trait for entity={}", guid, e);
throw new WebApplicationException( throw new WebApplicationException(
...@@ -296,7 +305,7 @@ public class EntityResource { ...@@ -296,7 +305,7 @@ public class EntityResource {
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(GUID, guid); response.put(MetadataServiceClient.GUID, guid);
response.put(TRAIT_NAME, traitName); response.put(TRAIT_NAME, traitName);
return Response.ok(response).build(); return Response.ok(response).build();
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* * <p/>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* * <p/>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...@@ -19,10 +19,14 @@ ...@@ -19,10 +19,14 @@
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 com.google.inject.Guice;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.hadoop.metadata.MetadataException; import org.apache.hadoop.metadata.MetadataException;
import org.apache.hadoop.metadata.MetadataServiceClient; import org.apache.hadoop.metadata.MetadataServiceClient;
import org.apache.hadoop.metadata.services.MetadataService; import org.apache.hadoop.metadata.services.MetadataService;
import org.apache.hadoop.metadata.typesystem.types.DataTypes; import org.apache.hadoop.metadata.typesystem.types.DataTypes;
import org.apache.hadoop.metadata.typesystem.types.IDataType;
import org.apache.hadoop.metadata.web.listeners.GuiceServletConfig;
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;
...@@ -34,10 +38,12 @@ import javax.inject.Inject; ...@@ -34,10 +38,12 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context; import javax.ws.rs.core.*;
import javax.ws.rs.core.MediaType; import java.net.URI;
import javax.ws.rs.core.Response; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* This class provides RESTful API for Types. * This class provides RESTful API for Types.
...@@ -56,6 +62,10 @@ public class TypesResource { ...@@ -56,6 +62,10 @@ public class TypesResource {
private final MetadataService metadataService; private final MetadataService metadataService;
static final String TYPE_ALL = "all"; static final String TYPE_ALL = "all";
private static final String URI_TYPES = "types";
@Context
UriInfo uriInfo;
@Inject @Inject
public TypesResource(MetadataService metadataService) { public TypesResource(MetadataService metadataService) {
...@@ -74,13 +84,25 @@ public class TypesResource { ...@@ -74,13 +84,25 @@ public class TypesResource {
final String typeDefinition = Servlets.getRequestPayload(request); final String typeDefinition = Servlets.getRequestPayload(request);
LOG.debug("creating type with definition {} ", typeDefinition); LOG.debug("creating type with definition {} ", typeDefinition);
JSONObject typesAdded = metadataService.createType(typeDefinition); JSONObject typesJson = metadataService.createType(typeDefinition);
UriBuilder ub = uriInfo.getAbsolutePathBuilder();
final JSONArray typesJsonArray = typesJson.getJSONArray("types");
List<Map<String, String>> typesAddedList = new ArrayList<>();
for (int i = 0; i < typesJsonArray.length(); i++) {
final String name = typesJsonArray.getString(i);
final URI locationUri = ub.path(name).build();
typesAddedList.add(
new HashMap<String, String>() {{
put(MetadataServiceClient.NAME, name);
put(MetadataServiceClient.URI, locationUri.toURL().toExternalForm());
}});
}
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put("types", typesAdded);
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
response.put(MetadataServiceClient.URI_TYPES, typesAddedList);
return Response.ok(response).build(); return Response.status(ClientResponse.Status.CREATED).entity(response).build();
} catch (Exception e) { } catch (Exception e) {
LOG.error("Unable to persist types", e); LOG.error("Unable to persist types", e);
throw new WebApplicationException( throw new WebApplicationException(
...@@ -103,7 +125,7 @@ public class TypesResource { ...@@ -103,7 +125,7 @@ public class TypesResource {
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put("typeName", typeName); response.put("typeName", typeName);
response.put("definition", typeDefinition); response.put(MetadataServiceClient.DEFINITION, typeDefinition);
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
return Response.ok(response).build(); return Response.ok(response).build();
...@@ -124,7 +146,7 @@ public class TypesResource { ...@@ -124,7 +146,7 @@ public class TypesResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response getTypesByFilter(@Context HttpServletRequest request, public Response getTypesByFilter(@Context HttpServletRequest request,
@DefaultValue(TYPE_ALL) @QueryParam("type") String type) { @DefaultValue(TYPE_ALL) @QueryParam("type") String type) {
try { try {
List<String> result = null; List<String> result = null;
if (TYPE_ALL.equals(type)) { if (TYPE_ALL.equals(type)) {
...@@ -140,7 +162,7 @@ public class TypesResource { ...@@ -140,7 +162,7 @@ public class TypesResource {
response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId()); response.put(MetadataServiceClient.REQUEST_ID, Servlets.getRequestId());
return Response.ok(response).build(); return Response.ok(response).build();
} catch(IllegalArgumentException ie) { } catch (IllegalArgumentException ie) {
LOG.error("Unsupported typeName while retrieving type list {}", type); LOG.error("Unsupported typeName while retrieving type list {}", type);
throw new WebApplicationException( throw new WebApplicationException(
Servlets.getErrorResponse("Unsupported type " + type, Response.Status.BAD_REQUEST)); Servlets.getErrorResponse("Unsupported type " + type, Response.Status.BAD_REQUEST));
......
...@@ -20,7 +20,11 @@ package org.apache.hadoop.metadata.web.util; ...@@ -20,7 +20,11 @@ package org.apache.hadoop.metadata.web.util;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.metadata.MetadataServiceClient;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
...@@ -33,6 +37,7 @@ import java.io.StringWriter; ...@@ -33,6 +37,7 @@ import java.io.StringWriter;
*/ */
public final class Servlets { public final class Servlets {
private static final Logger LOG = LoggerFactory.getLogger(Servlets.class);
private Servlets() { private Servlets() {
/* singleton */ /* singleton */
} }
...@@ -97,9 +102,17 @@ public final class Servlets { ...@@ -97,9 +102,17 @@ public final class Servlets {
} }
public static Response getErrorResponse(String message, Response.Status status) { public static Response getErrorResponse(String message, Response.Status status) {
JSONObject errorJson = new JSONObject();
Object errorEntity = JSONObject.quote(message);
try {
errorJson.put(MetadataServiceClient.ERROR, errorEntity);
errorEntity = errorJson;
} catch (JSONException jsonE) {
LOG.warn("Could not construct error Json rensponse");
}
return Response return Response
.status(status) .status(status)
.entity(JSONObject.quote(message)) .entity(errorEntity)
.type(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON)
.build(); .build();
} }
......
...@@ -76,7 +76,7 @@ public abstract class BaseResourceIT { ...@@ -76,7 +76,7 @@ public abstract class BaseResourceIT {
.accept(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON)
.method(HttpMethod.POST, ClientResponse.class, typesAsJSON); .method(HttpMethod.POST, ClientResponse.class, typesAsJSON);
Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(clientResponse.getStatus(), Response.Status.CREATED.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString); Assert.assertNotNull(responseAsString);
...@@ -93,7 +93,7 @@ public abstract class BaseResourceIT { ...@@ -93,7 +93,7 @@ public abstract class BaseResourceIT {
String entityJSON = InstanceSerialization.toJson(referenceable, true); String entityJSON = InstanceSerialization.toJson(referenceable, true);
System.out.println("Submitting new entity= " + entityJSON); System.out.println("Submitting new entity= " + entityJSON);
JSONObject jsonObject = serviceClient.createEntity(entityJSON); JSONObject jsonObject = serviceClient.createEntity(entityJSON);
String guid = jsonObject.getString(MetadataServiceClient.RESULTS); String guid = jsonObject.getString(MetadataServiceClient.GUID);
System.out.println("created instance for type " + typeName + ", guid: " + guid); System.out.println("created instance for type " + typeName + ", guid: " + guid);
// return the reference to created instance with guid // return the reference to created instance with guid
......
...@@ -147,7 +147,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -147,7 +147,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject response = new JSONObject(responseAsString); JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(MetadataServiceClient.REQUEST_ID)); Assert.assertNotNull(response.get(MetadataServiceClient.REQUEST_ID));
final String definition = response.getString(MetadataServiceClient.RESULTS); final String definition = response.getString(MetadataServiceClient.DEFINITION);
Assert.assertNotNull(definition); Assert.assertNotNull(definition);
LOG.debug("tableInstanceAfterGet = " + definition); LOG.debug("tableInstanceAfterGet = " + definition);
InstanceSerialization.fromJsonReferenceable(definition, true); InstanceSerialization.fromJsonReferenceable(definition, true);
...@@ -176,7 +176,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -176,7 +176,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
private String getEntityDefinition(ClientResponse clientResponse) throws Exception { private String getEntityDefinition(ClientResponse clientResponse) throws Exception {
Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode());
JSONObject response = new JSONObject(clientResponse.getEntity(String.class)); JSONObject response = new JSONObject(clientResponse.getEntity(String.class));
final String definition = response.getString(MetadataServiceClient.RESULTS); final String definition = response.getString(MetadataServiceClient.DEFINITION);
Assert.assertNotNull(definition); Assert.assertNotNull(definition);
return definition; return definition;
...@@ -196,6 +196,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -196,6 +196,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString); Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(MetadataServiceClient.ERROR));
} }
@Test(dependsOnMethods = "testSubmitEntity") @Test(dependsOnMethods = "testSubmitEntity")
...@@ -232,6 +235,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -232,6 +235,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString); Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(MetadataServiceClient.ERROR));
} }
@Test @Test
...@@ -311,15 +317,15 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -311,15 +317,15 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
.accept(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON)
.method(HttpMethod.POST, ClientResponse.class, traitInstanceAsJSON); .method(HttpMethod.POST, ClientResponse.class, traitInstanceAsJSON);
Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(clientResponse.getStatus(), Response.Status.CREATED.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString); Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString); JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(MetadataServiceClient.REQUEST_ID)); Assert.assertNotNull(response.get(MetadataServiceClient.REQUEST_ID));
Assert.assertNotNull(response.get("GUID")); Assert.assertNotNull(response.get(MetadataServiceClient.GUID));
Assert.assertNotNull(response.get("traitInstance")); Assert.assertNotNull(response.get(MetadataServiceClient.DEFINITION));
} }
@Test @Test
...@@ -383,6 +389,12 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -383,6 +389,12 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
.method(HttpMethod.DELETE, ClientResponse.class); .method(HttpMethod.DELETE, ClientResponse.class);
Assert.assertEquals(clientResponse.getStatus(), Assert.assertEquals(clientResponse.getStatus(),
Response.Status.BAD_REQUEST.getStatusCode()); Response.Status.BAD_REQUEST.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(MetadataServiceClient.ERROR));
} }
private void createHiveTypes() throws Exception { private void createHiveTypes() throws Exception {
......
...@@ -76,7 +76,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT { ...@@ -76,7 +76,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
.accept(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON)
.method(HttpMethod.POST, ClientResponse.class, typesAsJSON); .method(HttpMethod.POST, ClientResponse.class, typesAsJSON);
Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(clientResponse.getStatus(), Response.Status.CREATED.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class); String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString); Assert.assertNotNull(responseAsString);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment