[OLINGO-545] TecSvc: Request validation added
This commit is contained in:
parent
97a0178432
commit
583c4bd078
|
@ -30,8 +30,10 @@ import static org.junit.Assert.fail;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
||||||
import org.apache.olingo.client.api.ODataClient;
|
import org.apache.olingo.client.api.ODataClient;
|
||||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||||
|
@ -266,6 +268,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
|
||||||
ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim"));
|
ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim"));
|
||||||
newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64",
|
newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64",
|
||||||
factory.newPrimitiveValueBuilder().buildInt32(42)));
|
factory.newPrimitiveValueBuilder().buildInt32(42)));
|
||||||
|
|
||||||
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(32767)
|
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(32767)
|
||||||
.build();
|
.build();
|
||||||
final ODataEntityUpdateRequest<ODataEntity> request = client.getCUDRequestFactory().getEntityUpdateRequest(
|
final ODataEntityUpdateRequest<ODataEntity> request = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||||
|
@ -373,6 +376,12 @@ public class BasicITCase extends AbstractBaseTestITCase {
|
||||||
ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim"));
|
ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim"));
|
||||||
newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64",
|
newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64",
|
||||||
factory.newPrimitiveValueBuilder().buildInt32(42)));
|
factory.newPrimitiveValueBuilder().buildInt32(42)));
|
||||||
|
newEntity.addLink(factory.newEntityNavigationLink("NavPropertyETTwoPrimOne",
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment("ESTwoPrim")
|
||||||
|
.appendKeySegment(32766)
|
||||||
|
.build()));
|
||||||
|
|
||||||
final ODataEntityCreateRequest<ODataEntity> createRequest = client.getCUDRequestFactory().getEntityCreateRequest(
|
final ODataEntityCreateRequest<ODataEntity> createRequest = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build(),
|
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build(),
|
||||||
newEntity);
|
newEntity);
|
||||||
|
@ -518,6 +527,18 @@ public class BasicITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder().buildInt16((short) 2)))
|
.add(of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder().buildInt16((short) 2)))
|
||||||
.add(of.newPrimitiveProperty("PropertySingle", of.newPrimitiveValueBuilder().buildSingle(2.0f))))))));
|
.add(of.newPrimitiveProperty("PropertySingle", of.newPrimitiveValueBuilder().buildSingle(2.0f))))))));
|
||||||
|
|
||||||
|
entity.addLink(of.newEntityNavigationLink("NavPropertyETTwoKeyNavOne",
|
||||||
|
getClient().newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment("ESTwoKeyNav")
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
{
|
||||||
|
put("PropertyInt16", 1);
|
||||||
|
put("PropertyString", "1");
|
||||||
|
}
|
||||||
|
}).build()));
|
||||||
|
|
||||||
final ODataEntityCreateResponse<ODataEntity> response = getClient().getCUDRequestFactory().getEntityCreateRequest(
|
final ODataEntityCreateResponse<ODataEntity> response = getClient().getCUDRequestFactory().getEntityCreateRequest(
|
||||||
getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESKeyNav").build(),
|
getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESKeyNav").build(),
|
||||||
entity).execute();
|
entity).execute();
|
||||||
|
@ -576,6 +597,23 @@ public class BasicITCase extends AbstractBaseTestITCase {
|
||||||
assertNull(innerComplexProperty2.get("NotAvailableProperty"));
|
assertNull(innerComplexProperty2.get("NotAvailableProperty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexPropertyWithNotNullablePrimitiveValue() {
|
||||||
|
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||||
|
final ODataObjectFactory of = client.getObjectFactory();
|
||||||
|
|
||||||
|
// PropertyComp is null, but the primitive values in PropertyComp must not be null
|
||||||
|
final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETMixPrimCollComp"));
|
||||||
|
final URI targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESMixPrimCollComp").build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.getCUDRequestFactory().getEntityCreateRequest(targetURI, entity).execute();
|
||||||
|
fail("Expecting bad request");
|
||||||
|
} catch (ODataClientErrorException e) {
|
||||||
|
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ODataClient getClient() {
|
protected ODataClient getClient() {
|
||||||
ODataClient odata = ODataClientFactory.getClient();
|
ODataClient odata = ODataClientFactory.getClient();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static org.junit.Assert.fail;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
||||||
import org.apache.olingo.client.api.ODataClient;
|
import org.apache.olingo.client.api.ODataClient;
|
||||||
|
@ -69,9 +70,9 @@ public class BindingITCase extends AbstractBaseTestITCase {
|
||||||
private static final String PROPERTY_COMP_ALL_PRIM = "PropertyCompAllPrim";
|
private static final String PROPERTY_COMP_ALL_PRIM = "PropertyCompAllPrim";
|
||||||
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
|
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
|
||||||
private static final String NAV_PROPERTY_ET_KEY_NAV_MANY = "NavPropertyETKeyNavMany";
|
private static final String NAV_PROPERTY_ET_KEY_NAV_MANY = "NavPropertyETKeyNavMany";
|
||||||
|
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_ONE = "NavPropertyETTwoKeyNavOne";
|
||||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateBindingSimple() throws EdmPrimitiveTypeException {
|
public void testCreateBindingSimple() throws EdmPrimitiveTypeException {
|
||||||
final ODataClient client = getClient();
|
final ODataClient client = getClient();
|
||||||
|
@ -101,6 +102,17 @@ public class BindingITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
||||||
|
|
||||||
// Bind existing entities via binding synatx
|
// Bind existing entities via binding synatx
|
||||||
|
entity.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE,
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 3109256773218160485L;
|
||||||
|
{
|
||||||
|
put(PROPERTY_INT16, 3);
|
||||||
|
put(PROPERTY_STRING, "1");
|
||||||
|
}
|
||||||
|
}).build()));
|
||||||
|
|
||||||
final ODataLink navLinkOne =
|
final ODataLink navLinkOne =
|
||||||
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
|
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
|
||||||
.appendEntitySetSegment(
|
.appendEntitySetSegment(
|
||||||
|
@ -331,10 +343,31 @@ public class BindingITCase extends AbstractBaseTestITCase {
|
||||||
innerEntity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
innerEntity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 1)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 1)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("2")))));
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("2")))));
|
||||||
|
innerEntity.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE,
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 3109256773218160485L;
|
||||||
|
{
|
||||||
|
put(PROPERTY_INT16, 3);
|
||||||
|
put(PROPERTY_STRING, "1");
|
||||||
|
}
|
||||||
|
}).build()));
|
||||||
|
|
||||||
final ODataInlineEntity inlineLink = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
|
final ODataInlineEntity inlineLink = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
|
||||||
entity.addLink(inlineLink);
|
entity.addLink(inlineLink);
|
||||||
|
|
||||||
|
entity.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE,
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 3109256773218160485L;
|
||||||
|
{
|
||||||
|
put(PROPERTY_INT16, 3);
|
||||||
|
put(PROPERTY_STRING, "1");
|
||||||
|
}
|
||||||
|
}).build()));
|
||||||
|
|
||||||
final URI bindingURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
|
final URI bindingURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
|
||||||
.appendKeySegment(3)
|
.appendKeySegment(3)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.fit.tecsvc.client;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -27,8 +28,12 @@ import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
||||||
import org.apache.olingo.client.api.ODataClient;
|
import org.apache.olingo.client.api.ODataClient;
|
||||||
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
|
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||||
|
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||||
import org.apache.olingo.client.core.ODataClientFactory;
|
import org.apache.olingo.client.core.ODataClientFactory;
|
||||||
|
@ -62,8 +67,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
private static final String CT_TWO_PRIM = "CTTwoPrim";
|
private static final String CT_TWO_PRIM = "CTTwoPrim";
|
||||||
private static final String CT_ALL_PRIM = "CTAllPrim";
|
private static final String CT_ALL_PRIM = "CTAllPrim";
|
||||||
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
|
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
|
||||||
|
private static final String CT_BASE_PRIM_COMP_NAV = "CTBasePrimCompNav";
|
||||||
private static final String PROPERTY_INT16 = "PropertyInt16";
|
private static final String PROPERTY_INT16 = "PropertyInt16";
|
||||||
private static final String PROPERTY_STRING = "PropertyString";
|
private static final String PROPERTY_STRING = "PropertyString";
|
||||||
|
private static final String PROPERTY_COMP = "PropertyComp";
|
||||||
private static final String PROPERTY_COMP_NAV = "PropertyCompNav";
|
private static final String PROPERTY_COMP_NAV = "PropertyCompNav";
|
||||||
private static final String PROPERTY_COMP_COMP_NAV = "PropertyCompCompNav";
|
private static final String PROPERTY_COMP_COMP_NAV = "PropertyCompCompNav";
|
||||||
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
|
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
|
||||||
|
@ -71,6 +78,8 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
|
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
|
||||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_ONE = "NavPropertyETTwoKeyNavOne";
|
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_ONE = "NavPropertyETTwoKeyNavOne";
|
||||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
||||||
|
private static final String COL_PROPERTY_STRING = "CollPropertyString";
|
||||||
|
private static final String EDM_STRING = "Edm.String";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeepInsertExpandedResponse() {
|
public void testDeepInsertExpandedResponse() {
|
||||||
|
@ -96,6 +105,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
||||||
"String Property level 1, complex level 1")))));
|
"String Property level 1, complex level 1")))));
|
||||||
|
firstLevelTwoKeyNav.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
|
firstLevelTwoKeyNav.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_BASE_PRIM_COMP_NAV)));
|
||||||
final ODataInlineEntity firstLevelTwoKeyOneInline =
|
final ODataInlineEntity firstLevelTwoKeyOneInline =
|
||||||
of.newDeepInsertEntity(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, firstLevelTwoKeyNav);
|
of.newDeepInsertEntity(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, firstLevelTwoKeyNav);
|
||||||
entity.addLink(firstLevelTwoKeyOneInline);
|
entity.addLink(firstLevelTwoKeyOneInline);
|
||||||
|
@ -107,6 +120,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 421)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 421)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
||||||
"String Property level 2, complex level 1")))));
|
"String Property level 2, complex level 1")))));
|
||||||
|
secondLevelTwoKeyNav.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
|
secondLevelTwoKeyNav.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_BASE_PRIM_COMP_NAV)));
|
||||||
|
|
||||||
// Binding links
|
// Binding links
|
||||||
secondLevelTwoKeyNav.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, client.newURIBuilder(
|
secondLevelTwoKeyNav.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, client.newURIBuilder(
|
||||||
|
@ -129,6 +146,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
||||||
"String Property level 3, complex level 1")))));
|
"String Property level 3, complex level 1")))));
|
||||||
|
thirdLevelTwoKeyNavMany1.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
|
thirdLevelTwoKeyNavMany1.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_BASE_PRIM_COMP_NAV)));
|
||||||
|
|
||||||
final ODataEntity thirdLevelTwoKeyNavMany2 = of.newEntity(ET_TWO_KEY_NAV);
|
final ODataEntity thirdLevelTwoKeyNavMany2 = of.newEntity(ET_TWO_KEY_NAV);
|
||||||
thirdLevelTwoKeyNavMany2.getProperties().add(
|
thirdLevelTwoKeyNavMany2.getProperties().add(
|
||||||
|
@ -136,6 +157,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 432)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 432)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
||||||
"String Property level 3, complex level 1")))));
|
"String Property level 3, complex level 1")))));
|
||||||
|
thirdLevelTwoKeyNavMany2.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
|
thirdLevelTwoKeyNavMany2.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_BASE_PRIM_COMP_NAV)));
|
||||||
|
|
||||||
final ODataEntitySet entitySetThirdLevelTwoKeyNavMany = of.newEntitySet();
|
final ODataEntitySet entitySetThirdLevelTwoKeyNavMany = of.newEntitySet();
|
||||||
entitySetThirdLevelTwoKeyNavMany.getEntities().add(thirdLevelTwoKeyNavMany1);
|
entitySetThirdLevelTwoKeyNavMany.getEntities().add(thirdLevelTwoKeyNavMany1);
|
||||||
|
@ -150,6 +175,10 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 422)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 422)))
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString(
|
||||||
"String Property level 1, complex level 1")))));
|
"String Property level 1, complex level 1")))));
|
||||||
|
firstLevelTwoKeyNavMany1.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
|
firstLevelTwoKeyNavMany1.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_BASE_PRIM_COMP_NAV)));
|
||||||
|
|
||||||
final ODataEntitySet entitySetfirstLevelTwoKeyNavMany = of.newEntitySet();
|
final ODataEntitySet entitySetfirstLevelTwoKeyNavMany = of.newEntitySet();
|
||||||
entitySetfirstLevelTwoKeyNavMany.getEntities().add(firstLevelTwoKeyNavMany1);
|
entitySetfirstLevelTwoKeyNavMany.getEntities().add(firstLevelTwoKeyNavMany1);
|
||||||
|
@ -172,7 +201,8 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
resultEntityFirstLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE).asInlineEntity().getEntity();
|
resultEntityFirstLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE).asInlineEntity().getEntity();
|
||||||
assertEquals(421, resultEntitySecondLevel.getProperty(PROPERTY_COMP_TWO_PRIM).getComplexValue().get(PROPERTY_INT16)
|
assertEquals(421, resultEntitySecondLevel.getProperty(PROPERTY_COMP_TWO_PRIM).getComplexValue().get(PROPERTY_INT16)
|
||||||
.getPrimitiveValue().toValue());
|
.getPrimitiveValue().toValue());
|
||||||
assertEquals("String Property level 2, complex level 1", resultEntitySecondLevel.getProperty(PROPERTY_COMP_TWO_PRIM)
|
assertEquals("String Property level 2, complex level 1", resultEntitySecondLevel
|
||||||
|
.getProperty(PROPERTY_COMP_TWO_PRIM)
|
||||||
.getComplexValue().get(PROPERTY_STRING)
|
.getComplexValue().get(PROPERTY_STRING)
|
||||||
.getPrimitiveValue().toValue());
|
.getPrimitiveValue().toValue());
|
||||||
|
|
||||||
|
@ -234,6 +264,8 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
|
||||||
inlineEntitySingle.getProperties()
|
inlineEntitySingle.getProperties()
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
|
||||||
|
inlineEntitySingle.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
inlineEntitySingle.getProperties()
|
inlineEntitySingle.getProperties()
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
|
||||||
|
@ -253,6 +285,8 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
inlineEntityCol1.getProperties()
|
inlineEntityCol1.getProperties()
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 441)))));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 441)))));
|
||||||
|
inlineEntityCol1.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
inlineEntityCol1.getProperties()
|
inlineEntityCol1.getProperties()
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 442)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 442)))
|
||||||
|
@ -266,6 +300,8 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
inlineEntityCol2.getProperties()
|
inlineEntityCol2.getProperties()
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 451)))));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 451)))));
|
||||||
|
inlineEntityCol2.getProperties().add(
|
||||||
|
of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)));
|
||||||
inlineEntityCol2.getProperties()
|
inlineEntityCol2.getProperties()
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 452)))
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 452)))
|
||||||
|
@ -412,6 +448,18 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
|
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP)
|
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
||||||
|
entity.addLink(of.newEntityNavigationLink("NavPropertyETTwoKeyNavOne",
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
{
|
||||||
|
put(PROPERTY_INT16, 1);
|
||||||
|
put(PROPERTY_STRING, "1");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()));
|
||||||
|
|
||||||
// Prepare inline entity(EntitySet: ESKeyNav, Type: ETKeyNav)
|
// Prepare inline entity(EntitySet: ESKeyNav, Type: ETKeyNav)
|
||||||
final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV);
|
final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV);
|
||||||
|
@ -436,6 +484,18 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP)
|
.add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder()
|
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder()
|
||||||
.buildInt16((short) 431)))))));
|
.buildInt16((short) 431)))))));
|
||||||
|
innerEntity.addLink(of.newEntityNavigationLink("NavPropertyETTwoKeyNavOne",
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
{
|
||||||
|
put(PROPERTY_INT16, 1);
|
||||||
|
put(PROPERTY_STRING, "1");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()));
|
||||||
|
|
||||||
ODataInlineEntity inlineEntity = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
|
ODataInlineEntity inlineEntity = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
|
||||||
entity.addLink(inlineEntity);
|
entity.addLink(inlineEntity);
|
||||||
|
@ -475,6 +535,108 @@ public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||||
.getPrimitiveValue().toValue());
|
.getPrimitiveValue().toValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsistency() throws EdmPrimitiveTypeException {
|
||||||
|
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||||
|
final ODataObjectFactory of = client.getObjectFactory();
|
||||||
|
final String cookie = getCookie();
|
||||||
|
|
||||||
|
// Do not set PropertyString(Nullable=false)
|
||||||
|
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
|
||||||
|
entity.getProperties().add(
|
||||||
|
of.newCollectionProperty(COL_PROPERTY_STRING,
|
||||||
|
of.newCollectionValue(EDM_STRING).add(
|
||||||
|
of.newPrimitiveValueBuilder().buildString("Test"))));
|
||||||
|
|
||||||
|
final URI targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ODataEntityCreateRequest<ODataEntity> request = client.getCUDRequestFactory()
|
||||||
|
.getEntityCreateRequest(targetURI, entity);
|
||||||
|
request.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||||
|
request.execute();
|
||||||
|
fail("Expecting bad request");
|
||||||
|
} catch (ODataClientErrorException e) {
|
||||||
|
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entity must not be created
|
||||||
|
validateSet(targetURI, cookie, (short) 1, (short) 2, (short) 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidType() throws EdmPrimitiveTypeException {
|
||||||
|
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||||
|
final ODataObjectFactory of = client.getObjectFactory();
|
||||||
|
final String cookie = getCookie();
|
||||||
|
|
||||||
|
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
|
||||||
|
entity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildInt32(1)));
|
||||||
|
final URI targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ODataEntityCreateRequest<ODataEntity> request = client.getCUDRequestFactory()
|
||||||
|
.getEntityCreateRequest(targetURI, entity);
|
||||||
|
request.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||||
|
request.execute();
|
||||||
|
} catch (ODataClientErrorException e) {
|
||||||
|
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
validateSet(targetURI, cookie, (short) 1, (short) 2, (short) 3);
|
||||||
|
|
||||||
|
entity.getProperties().add(
|
||||||
|
of.newCollectionProperty(PROPERTY_STRING,
|
||||||
|
of.newCollectionValue(EDM_STRING).add(
|
||||||
|
of.newPrimitiveValueBuilder().buildString("Test"))));
|
||||||
|
|
||||||
|
try {
|
||||||
|
ODataEntityCreateRequest<ODataEntity> request = client.getCUDRequestFactory()
|
||||||
|
.getEntityCreateRequest(targetURI, entity);
|
||||||
|
request.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||||
|
request.execute();
|
||||||
|
} catch (ODataClientErrorException e) {
|
||||||
|
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
validateSet(targetURI, cookie, (short) 1, (short) 2, (short) 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCookie() {
|
||||||
|
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||||
|
final ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||||
|
.getEntitySetRequest(client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build())
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateSet(final URI uri, final String cookie, final short... keys) throws EdmPrimitiveTypeException {
|
||||||
|
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||||
|
final ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory()
|
||||||
|
.getEntitySetRequest(uri);
|
||||||
|
request.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||||
|
final ODataRetrieveResponse<ODataEntitySet> response = request.execute();
|
||||||
|
|
||||||
|
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||||
|
assertEquals(3, response.getBody().getEntities().size());
|
||||||
|
|
||||||
|
for (final ODataEntity responseEntity : response.getBody().getEntities()) {
|
||||||
|
short propertyInt16 = responseEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class);
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (int i = 0; i < keys.length && !found; i++) {
|
||||||
|
if (propertyInt16 == keys[i]) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
fail("Invalid key " + propertyInt16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ODataClient getClient() {
|
protected ODataClient getClient() {
|
||||||
ODataClient odata = ODataClientFactory.getClient();
|
ODataClient odata = ODataClientFactory.getClient();
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.olingo.fit.tecsvc.client;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
import org.apache.olingo.client.api.ODataClient;
|
import org.apache.olingo.client.api.ODataClient;
|
||||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
|
@ -289,6 +290,11 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase {
|
||||||
entity.getProperties().add(
|
entity.getProperties().add(
|
||||||
objectFactory.newPrimitiveProperty("PropertyInt16", objectFactory.newPrimitiveValueBuilder()
|
objectFactory.newPrimitiveProperty("PropertyInt16", objectFactory.newPrimitiveValueBuilder()
|
||||||
.buildInt16((short) 1)));
|
.buildInt16((short) 1)));
|
||||||
|
entity.addLink(objectFactory.newEntityNavigationLink("NavPropertyETTwoPrimOne",
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment("ESTwoPrim")
|
||||||
|
.appendKeySegment(32766)
|
||||||
|
.build()));
|
||||||
|
|
||||||
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build();
|
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build();
|
||||||
ODataEntityCreateResponse<ODataEntity> createResponse =
|
ODataEntityCreateResponse<ODataEntity> createResponse =
|
||||||
|
@ -921,7 +927,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase {
|
||||||
@Test
|
@Test
|
||||||
public void testNullComplexProperty() {
|
public void testNullComplexProperty() {
|
||||||
// Create a new entry.The complex property PropertyCompComp is set to null. So the structure of the property
|
// Create a new entry.The complex property PropertyCompComp is set to null. So the structure of the property
|
||||||
// is still there, but filled is null value (primitive types)
|
// is still there, but filled is null values (primitive types)
|
||||||
// We define a filter, which returns all entry where PropertyCompComp/PropertyComp/PropertyInt16 is equals to 1
|
// We define a filter, which returns all entry where PropertyCompComp/PropertyComp/PropertyInt16 is equals to 1
|
||||||
|
|
||||||
final ODataClient client = getClient();
|
final ODataClient client = getClient();
|
||||||
|
@ -949,6 +955,19 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase {
|
||||||
"PropertyString",
|
"PropertyString",
|
||||||
factory.newPrimitiveValueBuilder().buildString("Test2")))));
|
factory.newPrimitiveValueBuilder().buildString("Test2")))));
|
||||||
|
|
||||||
|
newEntity.addLink(factory.newEntityNavigationLink("NavPropertyETTwoKeyNavOne",
|
||||||
|
client.newURIBuilder(SERVICE_URI)
|
||||||
|
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||||
|
.appendKeySegment(new LinkedHashMap<String, Object>() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
{
|
||||||
|
put("PropertyInt16", 1);
|
||||||
|
put("PropertyString", "1");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()));
|
||||||
|
|
||||||
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESKeyNav").build();
|
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESKeyNav").build();
|
||||||
ODataEntityCreateRequest<ODataEntity> request =
|
ODataEntityCreateRequest<ODataEntity> request =
|
||||||
client.getCUDRequestFactory().getEntityCreateRequest(uri, newEntity);
|
client.getCUDRequestFactory().getEntityCreateRequest(uri, newEntity);
|
||||||
|
|
|
@ -152,7 +152,6 @@ public class DataProvider {
|
||||||
private Map<String, Object> findFreeComposedKey(final List<Entity> entities, final EdmEntityType entityType)
|
private Map<String, Object> findFreeComposedKey(final List<Entity> entities, final EdmEntityType entityType)
|
||||||
throws DataProviderException {
|
throws DataProviderException {
|
||||||
// Weak key construction
|
// Weak key construction
|
||||||
// 3e € entity: (V k € keys: k !€ e.ki) => e.(k1, k2, k3) !€ entitySet
|
|
||||||
final HashMap<String, Object> keys = new HashMap<String, Object>();
|
final HashMap<String, Object> keys = new HashMap<String, Object>();
|
||||||
for (final String keyName : entityType.getKeyPredicateNames()) {
|
for (final String keyName : entityType.getKeyPredicateNames()) {
|
||||||
final EdmType type = entityType.getProperty(keyName).getType();
|
final EdmType type = entityType.getProperty(keyName).getType();
|
||||||
|
@ -311,10 +310,6 @@ public class DataProvider {
|
||||||
.getKeyPredicatesFromEntityLink(edm, bindingLink, rawBaseUri);
|
.getKeyPredicatesFromEntityLink(edm, bindingLink, rawBaseUri);
|
||||||
final Entity entity = read(edmEntitySetTarget, keys);
|
final Entity entity = read(edmEntitySetTarget, keys);
|
||||||
|
|
||||||
if (entity == null) {
|
|
||||||
throw new DataProviderException("Entity " + bindingLink + " not found", HttpStatusCode.NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
} catch (DeserializerException e) {
|
} catch (DeserializerException e) {
|
||||||
throw new DataProviderException("Invalid entity binding link", HttpStatusCode.BAD_REQUEST);
|
throw new DataProviderException("Invalid entity binding link", HttpStatusCode.BAD_REQUEST);
|
||||||
|
@ -400,9 +395,6 @@ public class DataProvider {
|
||||||
if (edmProperty.isPrimitive()) {
|
if (edmProperty.isPrimitive()) {
|
||||||
if (newProperty != null || !patch) {
|
if (newProperty != null || !patch) {
|
||||||
final Object value = newProperty == null ? null : newProperty.getValue();
|
final Object value = newProperty == null ? null : newProperty.getValue();
|
||||||
if (value == null && !edmProperty.isNullable()) {
|
|
||||||
throw new DataProviderException("Cannot null non-nullable property!", HttpStatusCode.BAD_REQUEST);
|
|
||||||
}
|
|
||||||
property.setValue(property.getValueType(), value);
|
property.setValue(property.getValueType(), value);
|
||||||
}
|
}
|
||||||
} else if (edmProperty.isCollection()) {
|
} else if (edmProperty.isCollection()) {
|
||||||
|
@ -458,8 +450,6 @@ public class DataProvider {
|
||||||
if (edmProperty.getType().getKind() == EdmTypeKind.COMPLEX) {
|
if (edmProperty.getType().getKind() == EdmTypeKind.COMPLEX) {
|
||||||
updateProperty(innerEdmProperty, newProperty, null, patch);
|
updateProperty(innerEdmProperty, newProperty, null, patch);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new DataProviderException("Null is not allowed for property " + edmProperty.getName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.olingo.server.tecsvc.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.ComplexValue;
|
||||||
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
|
import org.apache.olingo.commons.api.data.EntitySet;
|
||||||
|
import org.apache.olingo.commons.api.data.Link;
|
||||||
|
import org.apache.olingo.commons.api.data.Linked;
|
||||||
|
import org.apache.olingo.commons.api.data.Property;
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
|
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||||
|
import org.apache.olingo.server.api.uri.UriHelper;
|
||||||
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;
|
||||||
|
|
||||||
|
public class RequestValidator {
|
||||||
|
private DataProvider provider;
|
||||||
|
private boolean isInsert;
|
||||||
|
private UriHelper uriHelper;
|
||||||
|
private Edm edm;
|
||||||
|
private String rawServiceRoot;
|
||||||
|
|
||||||
|
public RequestValidator(final DataProvider provider, final boolean isInsert, final UriHelper uriHelper,
|
||||||
|
final Edm edm, final String rawServiceRoot) {
|
||||||
|
this.provider = provider;
|
||||||
|
this.isInsert = isInsert;
|
||||||
|
this.uriHelper = uriHelper;
|
||||||
|
this.edm = edm;
|
||||||
|
this.rawServiceRoot = rawServiceRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(final EdmBindingTarget edmBindingTarget, final Entity entity)
|
||||||
|
throws DataProviderException {
|
||||||
|
final List<String> path = new ArrayList<String>();
|
||||||
|
|
||||||
|
validateEntitySetProperties(entity.getProperties(), edmBindingTarget, edmBindingTarget.getEntityType(), path);
|
||||||
|
validateNavigationProperties(entity, edmBindingTarget, edmBindingTarget.getEntityType(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateNavigationProperties(final Linked entity, final EdmBindingTarget edmBindingTarget,
|
||||||
|
final EdmStructuredType edmType, final List<String> path) throws DataProviderException {
|
||||||
|
for (final String navPropertyName : edmType.getNavigationPropertyNames()) {
|
||||||
|
final EdmNavigationProperty edmProperty = edmType.getNavigationProperty(navPropertyName);
|
||||||
|
if(entity == null && !edmProperty.isNullable()) {
|
||||||
|
throw new DataProviderException("Navigation property " + navPropertyName + " must not be null",
|
||||||
|
HttpStatusCode.BAD_REQUEST);
|
||||||
|
} else if(entity != null) {
|
||||||
|
final Link navigationBinding = entity.getNavigationBinding(navPropertyName);
|
||||||
|
final Link navigationLink = entity.getNavigationLink(navPropertyName);
|
||||||
|
final List<String> newPath = new ArrayList<String>(path);
|
||||||
|
newPath.add(edmProperty.getName());
|
||||||
|
final EdmBindingTarget target = edmBindingTarget.getRelatedBindingTarget(buildPath(newPath));
|
||||||
|
|
||||||
|
final ValidatioResult bindingResult = validateBinding(navigationBinding, edmProperty, target);
|
||||||
|
final ValidatioResult linkResult = validateNavigationLink(navigationLink,
|
||||||
|
edmProperty,
|
||||||
|
target);
|
||||||
|
|
||||||
|
if (( isInsert && !edmProperty.isNullable() && (bindingResult != ValidatioResult.FOUND
|
||||||
|
&& linkResult != ValidatioResult.FOUND))
|
||||||
|
|| (!isInsert && !edmProperty.isNullable() && linkResult == ValidatioResult.EMPTY)) {
|
||||||
|
throw new DataProviderException("Navigation property " + navPropertyName + " must not be null",
|
||||||
|
HttpStatusCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildPath(final List<String> path) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
for(final String segment : path) {
|
||||||
|
if(builder.length() > 0) {
|
||||||
|
builder.append("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidatioResult validateBinding(final Link navigationBindung, final EdmNavigationProperty edmProperty,
|
||||||
|
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
|
||||||
|
if(navigationBindung == null) {
|
||||||
|
return ValidatioResult.NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edmProperty.isCollection()) {
|
||||||
|
if(navigationBindung.getBindingLinks().size() == 0) {
|
||||||
|
return ValidatioResult.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final String bindingLink : navigationBindung.getBindingLinks()) {
|
||||||
|
validateLink(bindingLink, edmBindingTarget);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(navigationBindung.getBindingLink() == null) {
|
||||||
|
return ValidatioResult.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateLink(navigationBindung.getBindingLink(), edmBindingTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidatioResult.FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidatioResult validateNavigationLink(final Link navigationLink, final EdmNavigationProperty edmProperty,
|
||||||
|
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
|
||||||
|
if(navigationLink == null) {
|
||||||
|
return ValidatioResult.NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(edmProperty.isCollection()) {
|
||||||
|
final EntitySet inlineEntitySet = navigationLink.getInlineEntitySet();
|
||||||
|
if(!isInsert && inlineEntitySet.getEntities().size() > 0) {
|
||||||
|
throw new DataProvider.DataProviderException("Deep update is not allowed", HttpStatusCode.BAD_REQUEST);
|
||||||
|
} else {
|
||||||
|
for(final Entity entity : navigationLink.getInlineEntitySet().getEntities()) {
|
||||||
|
validate(edmBindingTarget, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final Entity inlineEntity = navigationLink.getInlineEntity();
|
||||||
|
if(!isInsert && inlineEntity != null) {
|
||||||
|
throw new DataProvider.DataProviderException("Deep update is not allowed", HttpStatusCode.BAD_REQUEST);
|
||||||
|
} else if(inlineEntity != null) {
|
||||||
|
validate(edmBindingTarget, navigationLink.getInlineEntity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidatioResult.FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateLink(final String bindingLink, final EdmBindingTarget edmBindungTarget)
|
||||||
|
throws DataProviderException {
|
||||||
|
try {
|
||||||
|
final List<UriParameter> keys = uriHelper.getKeyPredicatesFromEntityLink(edm, bindingLink, rawServiceRoot);
|
||||||
|
final Entity entity = provider.read((EdmEntitySet)edmBindungTarget, keys);
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
|
||||||
|
}
|
||||||
|
} catch (DeserializerException e) {
|
||||||
|
throw new DataProviderException("Invalid binding link", HttpStatusCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateEntitySetProperties(final List<Property> properties, final EdmBindingTarget edmBindingTarget,
|
||||||
|
final EdmEntityType edmType, final List<String> path) throws DataProviderException {
|
||||||
|
validateProperties(properties, edmBindingTarget, edmType, edmType.getKeyPredicateNames(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateProperties(final List<Property> properties, final EdmBindingTarget edmBingingTarget,
|
||||||
|
final EdmStructuredType edmType, final List<String> keyPredicateNames, final List<String> path)
|
||||||
|
throws DataProviderException {
|
||||||
|
|
||||||
|
for(final String propertyName : edmType.getPropertyNames()) {
|
||||||
|
final EdmProperty edmProperty = (EdmProperty) edmType.getProperty(propertyName);
|
||||||
|
|
||||||
|
// Ignore key properties, they are set automatically
|
||||||
|
if(!keyPredicateNames.contains(propertyName)) {
|
||||||
|
final Property property = getProperty(properties, propertyName);
|
||||||
|
|
||||||
|
// Check if all "not nullable" properties are set
|
||||||
|
if(!edmProperty.isNullable()) {
|
||||||
|
if((property != null && property.isNull()) // Update,insert; Property is explicit set to null
|
||||||
|
|| (isInsert && property == null) ) { // Insert; Property not provided
|
||||||
|
throw new DataProviderException("Property " + propertyName + " must not be null",
|
||||||
|
HttpStatusCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate property value
|
||||||
|
validatePropertyValue(property, edmProperty, edmBingingTarget, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validatePropertyValue(final Property property, final EdmProperty edmProperty,
|
||||||
|
final EdmBindingTarget edmBindingTarget, final List<String> path) throws DataProviderException {
|
||||||
|
|
||||||
|
final ArrayList<String> newPath = new ArrayList<String>(path);
|
||||||
|
newPath.add(edmProperty.getName());
|
||||||
|
|
||||||
|
if (edmProperty.isCollection()) {
|
||||||
|
if (edmProperty.getType() instanceof EdmComplexType && property != null) {
|
||||||
|
for (final Object value : property.asCollection()) {
|
||||||
|
validateComplexValue((ComplexValue) value,
|
||||||
|
edmBindingTarget,
|
||||||
|
(EdmComplexType) edmProperty.getType(),
|
||||||
|
newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (edmProperty.getType() instanceof EdmComplexType) {
|
||||||
|
validateComplexValue((property == null) ? null : property.asComplex(),
|
||||||
|
edmBindingTarget,
|
||||||
|
(EdmComplexType) edmProperty.getType(),
|
||||||
|
newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateComplexValue(final ComplexValue value, final EdmBindingTarget edmBindingTarget,
|
||||||
|
final EdmComplexType edmType, final List<String> path) throws DataProviderException {
|
||||||
|
// The whole complex property can be nullable but nested primitive, navigation properties can be not nullable
|
||||||
|
final List<Property> properties = (value == null) ? new ArrayList<Property>() : value.getValue();
|
||||||
|
|
||||||
|
validateProperties(properties, edmBindingTarget, edmType, new ArrayList<String>(0), path);
|
||||||
|
validateNavigationProperties(value, edmBindingTarget, edmType, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Property getProperty(final List<Property> properties, final String name) {
|
||||||
|
for(final Property property : properties) {
|
||||||
|
if(property.getName().equals(name)) {
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum ValidatioResult {
|
||||||
|
FOUND,
|
||||||
|
NOT_FOUND,
|
||||||
|
EMPTY
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,6 +60,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||||
|
import org.apache.olingo.server.tecsvc.data.RequestValidator;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
|
||||||
|
@ -231,16 +232,24 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
|
final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
|
||||||
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
Entity entity = dataProvider.create(edmEntitySet);
|
final Entity entity;
|
||||||
ExpandOption expand = null;
|
ExpandOption expand = null;
|
||||||
if (edmEntityType.hasStream()) { // called from createMediaEntity(...), not directly
|
if (edmEntityType.hasStream()) { // called from createMediaEntity(...), not directly
|
||||||
|
entity = dataProvider.create(edmEntitySet);
|
||||||
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
||||||
requestFormat.toContentTypeString());
|
requestFormat.toContentTypeString());
|
||||||
} else {
|
} else {
|
||||||
final DeserializerResult deserializerResult = odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
final DeserializerResult deserializerResult = odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||||
.entity(request.getBody(), edmEntityType);
|
.entity(request.getBody(), edmEntityType);
|
||||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity,
|
new RequestValidator(dataProvider,
|
||||||
deserializerResult.getEntity(), false, true);
|
true, // Insert
|
||||||
|
odata.createUriHelper(),
|
||||||
|
serviceMetadata.getEdm(),
|
||||||
|
request.getRawBaseUri()
|
||||||
|
).validate(edmEntitySet, deserializerResult.getEntity());
|
||||||
|
|
||||||
|
entity = dataProvider.create(edmEntitySet);
|
||||||
|
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
|
||||||
expand = deserializerResult.getExpandTree();
|
expand = deserializerResult.getExpandTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,8 +274,16 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
||||||
Entity entity = readEntity(uriInfo);
|
Entity entity = readEntity(uriInfo);
|
||||||
checkRequestFormat(requestFormat);
|
checkRequestFormat(requestFormat);
|
||||||
ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
final ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
||||||
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity();
|
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity();
|
||||||
|
|
||||||
|
new RequestValidator(dataProvider,
|
||||||
|
false, // Update
|
||||||
|
odata.createUriHelper(),
|
||||||
|
serviceMetadata.getEdm(),
|
||||||
|
request.getRawBaseUri()
|
||||||
|
).validate(edmEntitySet, changedEntity);
|
||||||
|
|
||||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
||||||
request.getMethod() == HttpMethod.PATCH, false);
|
request.getMethod() == HttpMethod.PATCH, false);
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
|
Loading…
Reference in New Issue