Merge branch 'pr54'

This commit is contained in:
Ramesh Reddy 2019-09-01 20:24:41 -05:00
commit 9e94d9521f
4 changed files with 175 additions and 13 deletions

View File

@ -277,10 +277,20 @@ public class DataRequest extends ServiceRequest {
public boolean assertHttpMethod(ODataResponse response) throws ODataHandlerException {
// the create/update/delete to navigation property is done through references
// see # 11.4.6
if (!getNavigations().isEmpty() && !isGET()) {
return methodNotAllowed(response, httpMethod(),
"create/update/delete to navigation property is done through references",
allowedMethods());
if (!getNavigations().isEmpty()) {
if (isPOST()) {
UriResourceNavigation last = getNavigations().getLast();
if (!(getEntitySet().getRelatedBindingTarget(last.getProperty().getName())
instanceof EdmEntitySet)) {
return methodNotAllowed(response, httpMethod(),
"navigation updates must be to an entity contained in an entity set",
allowedMethods());
}
} else if (!isGET()) {
return methodNotAllowed(response, httpMethod(),
"update/delete to navigation property is done through references",
allowedMethods());
}
}
if ((isGET() || isDELETE()) && getReturnRepresentation() != ReturnRepresentation.NONE) {
@ -315,13 +325,14 @@ public class DataRequest extends ServiceRequest {
public void execute(ServiceHandler handler, ODataResponse response)
throws ODataLibraryException, ODataApplicationException {
ContextURL contextURL = getContextURL(odata);
EntityResponse entityResponse = EntityResponse.getInstance(DataRequest.this,
getContextURL(odata), false, response);
contextURL, false, response);
if (isGET()) {
if (isCollection()) {
handler.read(DataRequest.this,
EntitySetResponse.getInstance(DataRequest.this, getContextURL(odata), false, response));
EntitySetResponse.getInstance(DataRequest.this, contextURL, false, response));
} else {
handler.read(DataRequest.this,entityResponse);
}
@ -338,24 +349,37 @@ public class DataRequest extends ServiceRequest {
} else if (ifNoneMatch) {
// 11.4.4
entityResponse = EntityResponse.getInstance(DataRequest.this,
getContextURL(odata), false, response, getReturnRepresentation());
contextURL, false, response, getReturnRepresentation());
handler.createEntity(DataRequest.this, getEntityFromClient(), entityResponse);
} else {
handler.upsertEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
entityResponse);
}
} else if (isPOST()) {
entityResponse = EntityResponse.getInstance(DataRequest.this,
getContextURL(odata), false, response, getReturnRepresentation());
handler.createEntity(DataRequest.this, getEntityFromClient(),entityResponse);
if (!getNavigations().isEmpty()) {
entityResponse = EntityResponse.getInstance(DataRequest.this,
contextURL, false, response, getReturnRepresentation());
UriResourceNavigation last = getNavigations().getLast();
EdmEntityType navigationType = last.getProperty().getType();
Entity entity = getEntityFromClient(navigationType);
handler.createEntity(DataRequest.this, entity,entityResponse);
} else {
entityResponse = EntityResponse.getInstance(DataRequest.this,
contextURL, false, response, getReturnRepresentation());
handler.createEntity(DataRequest.this, getEntityFromClient(),entityResponse);
}
} else if (isDELETE()) {
handler.deleteEntity(DataRequest.this, getETag(), entityResponse);
}
}
private Entity getEntityFromClient() throws DeserializerException {
return getEntityFromClient(getEntitySet().getEntityType());
}
private Entity getEntityFromClient(EdmEntityType entityType) throws DeserializerException {
ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
return deserializer.entity(getODataRequest().getBody(), getEntitySet().getEntityType()).getEntity();
return deserializer.entity(getODataRequest().getBody(), entityType).getEntity();
}
@Override

View File

@ -493,7 +493,7 @@ public class TripPinDataModel {
map = new HashMap<String, Object>();
this.peopleLinks.put((String) parentEntity.getProperty(key).getValue(), map);
}
map.put("Photo", childEntity.getProperty(key).getValue());
map.put("Photo", ((Long)childEntity.getProperty("Id").getValue()).intValue());
setLink(parentEntity, navigation, childEntity);
} else if (type.getName().equals("Trip") && navigation.equals("PlanItems")) {
Map<String, Object> map = this.tripLinks.get(parentEntity.getProperty(key).getValue());

View File

@ -238,7 +238,12 @@ public class TripPinHandler implements ServiceHandler {
public void createEntity(DataRequest request, Entity entity, EntityResponse response)
throws ODataLibraryException, ODataApplicationException {
EdmEntitySet edmEntitySet = request.getEntitySet();
if (!request.getNavigations().isEmpty()) {
UriResourceNavigation lastNavigation = request.getNavigations().getLast();
edmEntitySet = (EdmEntitySet)edmEntitySet.getRelatedBindingTarget(lastNavigation.getProperty().getName());
}
Entity created = this.dataModel.createEntity(edmEntitySet, entity, request.getODataRequest().getRawBaseUri());
try {
@ -271,6 +276,25 @@ public class TripPinHandler implements ServiceHandler {
} catch (URISyntaxException e) {
throw new ODataApplicationException(e.getMessage(), 500, Locale.getDefault());
}
if (!request.getNavigations().isEmpty()) {
UriResourceNavigation lastNavigation = request.getNavigations().getLast();
String parentRequest = request.getODataRequest().getRawRequestUri();
parentRequest = parentRequest.substring(0, parentRequest.lastIndexOf('/'));
DataRequest bindingRequest;
try {
bindingRequest = request.parseLink(new URI(parentRequest));
} catch (URISyntaxException e) {
throw new ODataApplicationException(e.getMessage(), 500, Locale.getDefault());
}
Entity reference = this.dataModel.getEntity(bindingRequest.getEntitySet().getName(),
bindingRequest.getKeyPredicates());
this.dataModel.addNavigationLink(lastNavigation.getProperty().getName(), reference, created);
}
response.writeCreatedEntity(edmEntitySet, created);
}

View File

@ -552,6 +552,46 @@ public class TripPinServiceTest {
assertTrue(node.get("value").isArray());
assertEquals("scottketchum", ((ArrayNode)node.get("value")).get(1).get("UserName").asText());
}
@Ignore("4.01 style binding not supported")
@Test
public void testCreateEntityWithLinkToRelatedEntitiesIds() throws Exception {
String payload = "{\n" +
" \"UserName\":\"olingo\",\n" +
" \"FirstName\":\"Olingo\",\n" +
" \"LastName\":\"Apache\",\n" +
" \"Emails\":[\n" +
" \"olingo@apache.org\"\n" +
" ],\n" +
" \"AddressInfo\":[\n" +
" {\n" +
" \"Address\":\"100 apache Ln.\",\n" +
" \"City\":{\n" +
" \"CountryRegion\":\"United States\",\n" +
" \"Name\":\"Boise\",\n" +
" \"Region\":\"ID\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"Gender\":\"0\",\n" +
" \"Concurrency\":635585295719432047,\n" +
"\"Friends\":[" +
"{\"@id\": \"People('russellwhyte')\"},\n" +
"{\"@id\": \"People('scottketchum')\"}\n" +
"]"+
"}";
HttpPost postRequest = new HttpPost(baseURL + "/People");
postRequest.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));
postRequest.setHeader("Prefer", "return=minimal");
HttpResponse response = httpSend(postRequest, 204);
EntityUtils.consumeQuietly(response.getEntity());
response = httpGET(baseURL+"/People('olingo')/Friends", 200);
JsonNode node = getJSONNode(response);
assertEquals(baseURL+"/$metadata#People", node.get("@odata.context").asText());
assertTrue(node.get("value").isArray());
assertEquals("scottketchum", ((ArrayNode)node.get("value")).get(1).get("UserName").asText());
}
@Test
public void testUpdatePrimitiveProperty() throws Exception {
@ -779,6 +819,80 @@ public class TripPinServiceTest {
node = getJSONNode(response);
assertNull("/People('russellwhyte')", ((ArrayNode) node.get("value")).get(2));
}
@Test
public void testAddEntityToNavigationFailsNotEntitySet() throws Exception {
// adding to an entity that is not part of an entity set
// goes against a few assumptions in downstream code, so
// not handling for now
String msg = "{\n" +
"\"TripId\": 1010,\n" +
"\"Description\": \"The trip of a lifetime.\",\n" +
"\"Name\": \"Grand Prize\",\n" +
"\"Budget\": 100000\n" +
"}";
String editUrl = baseURL + "/People('vincentcalabrese')/Trips";
HttpPost postRequest = new HttpPost(editUrl);
postRequest.setEntity(new StringEntity(msg, ContentType.APPLICATION_JSON));
postRequest.addHeader("Content-Type", "application/json;odata.metadata=minimal");
HttpResponse response = httpSend(postRequest, 405);
EntityUtils.consumeQuietly(response.getEntity());
}
@Test
public void testAddEntityToNavigation() throws Exception {
String msg = "{\n" +
"\"Id\": 1010,\n" +
"\"Name\": \"Grand Prize\"\n" +
"}";
String editUrl = baseURL + "/People('vincentcalabrese')/Photo";
HttpPost postRequest = new HttpPost(editUrl);
postRequest.setEntity(new StringEntity(msg, ContentType.APPLICATION_JSON));
postRequest.addHeader("Content-Type", "application/json;odata.metadata=minimal");
HttpResponse response = httpSend(postRequest, 201);
EntityUtils.consumeQuietly(response.getEntity());
response = httpGET(baseURL+"/People('vincentcalabrese')/Photo", 200);
JsonNode node = getJSONNode(response);
assertEquals(baseURL+"/$metadata#Photos/$entity", node.get("@odata.context").asText());
assertEquals("Grand Prize", node.get("Name").asText());
}
@Test
public void testAddEntityToNavigationSelf() throws Exception {
String payload = "{\n" +
" \"UserName\":\"olingo\",\n" +
" \"FirstName\":\"Olingo\",\n" +
" \"LastName\":\"Apache\",\n" +
" \"Emails\":[\n" +
" \"olingo@apache.org\"\n" +
" ],\n" +
" \"AddressInfo\":[\n" +
" {\n" +
" \"Address\":\"100 apache Ln.\",\n" +
" \"City\":{\n" +
" \"CountryRegion\":\"United States\",\n" +
" \"Name\":\"Boise\",\n" +
" \"Region\":\"ID\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"Gender\":\"0\",\n" +
" \"Concurrency\":635585295719432047\n" +
"}";
String editUrl = baseURL + "/People('vincentcalabrese')/Friends";
HttpPost postRequest = new HttpPost(editUrl);
postRequest.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));
postRequest.addHeader("Content-Type", "application/json;odata.metadata=minimal");
HttpResponse response = httpSend(postRequest, 201);
EntityUtils.consumeQuietly(response.getEntity());
response = httpGET(baseURL+"/People('vincentcalabrese')/Friends", 200);
JsonNode node = getJSONNode(response);
assertEquals(baseURL+"/$metadata#People", node.get("@odata.context").asText());
assertTrue(node.get("value").isArray());
assertEquals("olingo", ((ArrayNode)node.get("value")).get(2).get("UserName").asText());
}
@Test
public void testDeleteReference() throws Exception {