[OLINGO-545] Deep Insert and Navigation Property Binding while creating and updating entities added
Signed-off-by: Michael Bolz <michael.bolz@sap.com>
This commit is contained in:
parent
4c23cd9d8c
commit
7a4b562724
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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.fit.tecsvc.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.cud.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataLink;
|
||||
import org.apache.olingo.commons.api.domain.ODataObjectFactory;
|
||||
import org.apache.olingo.commons.api.domain.ODataValue;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BindingITCase extends AbstractBaseTestITCase {
|
||||
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
|
||||
|
||||
private static final String SERVICE_NAMESPACE = "olingo.odata.test1";
|
||||
private static final String ES_KEY_NAV = "ESKeyNav";
|
||||
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
|
||||
private static final String ET_KEY_NAV_NAME = "ETKeyNav";
|
||||
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
|
||||
private static final String CT_PRIM_COMP = "CTPrimComp";
|
||||
private static final String CT_TWO_PRIM = "CTTwoPrim";
|
||||
private static final String CT_ALL_PRIM = "CTAllPrim";
|
||||
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
|
||||
private static final String PROPERTY_INT16 = "PropertyInt16";
|
||||
private static final String PROPERTY_STRING = "PropertyString";
|
||||
private static final String PROPERTY_COMP = "PropertyComp";
|
||||
private static final String PROPERTY_COMP_COMP = "PropertyCompComp";
|
||||
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
|
||||
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_MANY = "NavPropertyETKeyNavMany";
|
||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
||||
|
||||
@Test
|
||||
public void testCreateBindingSimple() throws EdmPrimitiveTypeException {
|
||||
final ODataClient client = getClient();
|
||||
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
|
||||
final ODataObjectFactory of = client.getObjectFactory();
|
||||
|
||||
// Create entity (EntitySet: ESKeyNav, Type: ETKeyNav)
|
||||
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
||||
|
||||
// Bind existing entities via binding synatx
|
||||
final ODataLink navLinkOne =
|
||||
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(
|
||||
ES_KEY_NAV).appendKeySegment(1).build());
|
||||
final ODataLink navLinkMany1 =
|
||||
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(
|
||||
ES_KEY_NAV).appendKeySegment(2).build());
|
||||
final ODataLink navLinkMany2 =
|
||||
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(
|
||||
ES_KEY_NAV).appendKeySegment(3).build());
|
||||
|
||||
final HashMap<String, Object> combinedKey = new HashMap<String, Object>();
|
||||
combinedKey.put(PROPERTY_INT16, 1);
|
||||
combinedKey.put(PROPERTY_STRING, "1");
|
||||
final ODataLink navLink2Many =
|
||||
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(combinedKey).build());
|
||||
|
||||
entity.addLink(navLinkOne);
|
||||
entity.addLink(navLinkMany1);
|
||||
entity.addLink(navLinkMany2);
|
||||
entity.addLink(navLink2Many);
|
||||
|
||||
final ODataEntityCreateResponse<ODataEntity> createResponse =
|
||||
client.getCUDRequestFactory().getEntityCreateRequest(createURI, entity).execute();
|
||||
final String cookie = createResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next();
|
||||
final Short entityInt16Key =
|
||||
createResponse.getBody().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class);
|
||||
|
||||
// Check the just created entity
|
||||
final URI entityGetURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(entityInt16Key).expand(
|
||||
NAV_PROPERTY_ET_KEY_NAV_ONE, NAV_PROPERTY_ET_KEY_NAV_MANY, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).build();
|
||||
|
||||
final ODataEntityRequest<ODataEntity> entityGetRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(entityGetURI);
|
||||
entityGetRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> entityGetResponse = entityGetRequest.execute();
|
||||
|
||||
// NAV_PROPERTY_ET_KEY_NAV_ONE
|
||||
assertEquals(1, entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// NAV_PROPERTY_ET_KEY_NAV_MANY(0)
|
||||
Iterator<ODataValue> iterator =
|
||||
entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().iterator();
|
||||
assertEquals(2, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// NAV_PROPERTY_ET_KEY_NAV_MANY(1)
|
||||
assertEquals(3, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// NAV_PROPERTY_ET_TWO_KEY_NAV_MANY(0)
|
||||
assertEquals(1, entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
|
||||
.iterator().next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("1", entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
|
||||
.iterator().next().asComplex().get(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
|
||||
// Check if partner navigation link has been set up
|
||||
final URI etTwoKeyNavEntityURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(combinedKey).expand(
|
||||
NAV_PROPERTY_ET_KEY_NAV_ONE).build();
|
||||
final ODataEntityRequest<ODataEntity> etTwoKeyNavEntityRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(etTwoKeyNavEntityURI);
|
||||
etTwoKeyNavEntityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> etTwoKeyNavEntityResponse = etTwoKeyNavEntityRequest.execute();
|
||||
|
||||
assertEquals(entityInt16Key, etTwoKeyNavEntityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE)
|
||||
.getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateBinding() {
|
||||
// The entity MUST NOT contain related entities as inline content. It MAY contain binding information
|
||||
// for navigation properties. For single-valued navigation properties this replaces the relationship.
|
||||
// For collection-valued navigation properties this adds to the relationship.
|
||||
|
||||
final ODataClient client = getClient();
|
||||
final URI entityURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build();
|
||||
final ODataObjectFactory of = client.getObjectFactory();
|
||||
|
||||
// ESKeyNav(1).NavPropertyETKeyNavOne = ESKeyNav(2)
|
||||
// ESKeyNav(1).NavPropertyETKeyNavMany = { ESKeyNav(1), ESKeyNav(2) }
|
||||
// => Replace NavPropertyETKeyNavOne with ESKeyNav(3)
|
||||
// => Add to NavPropertyETKeyNavOne ESKeyNav(3)
|
||||
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
|
||||
final ODataLink navLinkOne =
|
||||
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build());
|
||||
final ODataLink navLinkMany =
|
||||
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build());
|
||||
entity.addLink(navLinkOne);
|
||||
entity.addLink(navLinkMany);
|
||||
|
||||
final ODataEntityUpdateResponse<ODataEntity> updateResponse =
|
||||
client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute();
|
||||
final String cookie = updateResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next();
|
||||
|
||||
// Check if update was successful
|
||||
final URI entityGetURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).expand(
|
||||
NAV_PROPERTY_ET_KEY_NAV_ONE, NAV_PROPERTY_ET_KEY_NAV_MANY).build();
|
||||
final ODataEntityRequest<ODataEntity> entityRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(entityGetURI);
|
||||
entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> entityResponse = entityRequest.execute();
|
||||
|
||||
assertEquals(3, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals(3, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().size());
|
||||
|
||||
Iterator<ODataValue> iterator =
|
||||
entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().iterator();
|
||||
assertEquals(1, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals(2, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals(3, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
ODataClient odata = ODataClientFactory.getV4();
|
||||
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
|
||||
return odata;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* 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.fit.tecsvc.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntitySet;
|
||||
import org.apache.olingo.commons.api.domain.ODataInlineEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
|
||||
import org.apache.olingo.commons.api.domain.ODataObjectFactory;
|
||||
import org.apache.olingo.commons.api.domain.ODataProperty;
|
||||
import org.apache.olingo.commons.api.domain.ODataValue;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DeepInsertITCase extends AbstractBaseTestITCase {
|
||||
|
||||
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
|
||||
private static final String SERVICE_NAMESPACE = "olingo.odata.test1";
|
||||
private static final String ES_KEY_NAV = "ESKeyNav";
|
||||
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
|
||||
private static final String ET_KEY_NAV_NAME = "ETKeyNav";
|
||||
private static final String ET_TWO_KEY_NAV_NAME = "ETTwoKeyNav";
|
||||
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
|
||||
private static final FullQualifiedName ET_TWO_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_TWO_KEY_NAV_NAME);
|
||||
private static final String CT_PRIM_COMP = "CTPrimComp";
|
||||
private static final String CT_TWO_PRIM = "CTTwoPrim";
|
||||
private static final String CT_ALL_PRIM = "CTAllPrim";
|
||||
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
|
||||
private static final String PROPERTY_INT16 = "PropertyInt16";
|
||||
private static final String PROPERTY_STRING = "PropertyString";
|
||||
private static final String PROPERTY_COMP = "PropertyComp";
|
||||
private static final String PROPERTY_COMP_COMP = "PropertyCompComp";
|
||||
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
|
||||
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_TWO_KEY_NAV_ONE = "NavPropertyETTwoKeyNavOne";
|
||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {}
|
||||
|
||||
@Test
|
||||
public void testSimpleDeepInsert() throws EdmPrimitiveTypeException {
|
||||
final ODataClient client = getClient();
|
||||
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
|
||||
final ODataObjectFactory of = client.getObjectFactory();
|
||||
final ODataEntity entity = client.getObjectFactory().newEntity(ET_KEY_NAV);
|
||||
|
||||
// Prepare entity(EntitySet: ESKeyNav, Type: ETKeyNav)
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
||||
|
||||
// Non collection navigation property
|
||||
// Create related entity(EntitySet: ESTwoKeyNav, Type: ETTwoKeyNav, Nav. Property: NavPropertyETTwoKeyNavOne)
|
||||
final ODataEntity inlineEntitySingle = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
|
||||
inlineEntitySingle.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
|
||||
inlineEntitySingle.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
|
||||
inlineEntitySingle.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
|
||||
inlineEntitySingle.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 432)))
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("432")))));
|
||||
|
||||
// Collection navigation property
|
||||
// The navigation property has a partner navigation property named "NavPropertyETKeyNavOne"
|
||||
// Create related entity(EntitySet: ESTwoKeyNav, Type: NavPropertyETTwoKeyNavMany
|
||||
final ODataEntity inlineEntityCol1 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
|
||||
inlineEntityCol1.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 44)));
|
||||
inlineEntityCol1.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("44")));
|
||||
inlineEntityCol1.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 441)))));
|
||||
inlineEntityCol1.getProperties()
|
||||
.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_STRING, of.newPrimitiveValueBuilder().buildString("442")))));
|
||||
|
||||
final ODataEntity inlineEntityCol2 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
|
||||
inlineEntityCol2.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 45)));
|
||||
inlineEntityCol2.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("45")));
|
||||
inlineEntityCol2.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 451)))));
|
||||
inlineEntityCol2.getProperties()
|
||||
.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_STRING, of.newPrimitiveValueBuilder().buildString("452")))));
|
||||
|
||||
final ODataInlineEntity newDeepInsertEntityLink =
|
||||
of.newDeepInsertEntity(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, inlineEntitySingle);
|
||||
final ODataEntitySet newDeepInsertEntitySet = of.newEntitySet();
|
||||
newDeepInsertEntitySet.getEntities().add(inlineEntityCol1);
|
||||
newDeepInsertEntitySet.getEntities().add(inlineEntityCol2);
|
||||
final ODataInlineEntitySet newDeepInsertEntitySetLink =
|
||||
of.newDeepInsertEntitySet(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, newDeepInsertEntitySet);
|
||||
|
||||
entity.addLink(newDeepInsertEntityLink);
|
||||
entity.addLink(newDeepInsertEntitySetLink);
|
||||
|
||||
// Perform create request
|
||||
final ODataEntityCreateResponse<ODataEntity> responseCreate = client.getCUDRequestFactory()
|
||||
.getEntityCreateRequest(createURI, entity)
|
||||
.execute();
|
||||
assertEquals(HttpStatusCode.CREATED.getStatusCode(), responseCreate.getStatusCode());
|
||||
|
||||
final String cookie = responseCreate.getHeader(HttpHeader.SET_COOKIE).toString();
|
||||
|
||||
// Fetch ESKeyNav entity with expand of NavPropertyETTwoKeyNavOne nav. property
|
||||
ODataProperty propertyInt16 = responseCreate.getBody().getProperty(PROPERTY_INT16);
|
||||
final URI esKeyNavURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(
|
||||
propertyInt16.getPrimitiveValue().toValue()).expand(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE,
|
||||
NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).build();
|
||||
|
||||
final ODataEntityRequest<ODataEntity> esKeyNavRequest = client.getRetrieveRequestFactory()
|
||||
.getEntityRequest(esKeyNavURI);
|
||||
esKeyNavRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> esKeyNavResponse = esKeyNavRequest.execute();
|
||||
|
||||
// Check nav. property NavPropertyETTwoKeyNavOne
|
||||
assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE));
|
||||
assertEquals(431, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE).getComplexValue().get(
|
||||
PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// Check nav. property NavPropertyETTwoKeyNavMany
|
||||
assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
|
||||
assertEquals(2, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
|
||||
.size());
|
||||
Iterator<ODataValue> twoKeyNavManyIterator =
|
||||
esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue().iterator();
|
||||
final ODataValue firstTwoKeyNavEnity = twoKeyNavManyIterator.next(); // First entity
|
||||
assertEquals(441, firstTwoKeyNavEnity.asComplex().get(PROPERTY_COMP).getValue().asComplex().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
final ODataValue secondTwoKeyNavEnity = twoKeyNavManyIterator.next(); // Second entity
|
||||
assertEquals(451, secondTwoKeyNavEnity.asComplex().get(PROPERTY_COMP).getValue().asComplex().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// Fetch ESTwoKeyNav entities and check if available and the partner relation have been set up
|
||||
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavOne)
|
||||
Map<String, Object> composedKey = new HashMap<String, Object>();
|
||||
composedKey.put(PROPERTY_INT16, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE)
|
||||
.getComplexValue().get(PROPERTY_INT16)
|
||||
.getPrimitiveValue().toValue());
|
||||
composedKey.put(PROPERTY_STRING, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE)
|
||||
.getComplexValue().get(PROPERTY_STRING)
|
||||
.getPrimitiveValue().toValue());
|
||||
|
||||
final URI esTwoKeyNavEntitySingleURI = client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(ES_TWO_KEY_NAV)
|
||||
.appendKeySegment(composedKey)
|
||||
.build();
|
||||
|
||||
final ODataEntityRequest<ODataEntity> esTwoKeyNavSingleRequest = client.getRetrieveRequestFactory()
|
||||
.getEntityRequest(esTwoKeyNavEntitySingleURI);
|
||||
esTwoKeyNavSingleRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavSingleResponse = esTwoKeyNavSingleRequest.execute();
|
||||
assertEquals(431, esTwoKeyNavSingleResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(0))
|
||||
composedKey.clear();
|
||||
composedKey.put(PROPERTY_INT16, firstTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
composedKey.put(PROPERTY_STRING, firstTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue()
|
||||
.toValue());
|
||||
|
||||
URI esTwoKeyNavEntityManyOneURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey)
|
||||
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
|
||||
|
||||
final ODataEntityRequest<ODataEntity> esTwoKeyNavManyOneRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyOneURI);
|
||||
esTwoKeyNavManyOneRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavManyOneResponse = esTwoKeyNavManyOneRequest.execute();
|
||||
|
||||
assertEquals(441, esTwoKeyNavManyOneResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertNotNull(esTwoKeyNavManyOneResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue());
|
||||
assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyOneResponse.getBody().getProperty(
|
||||
NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(1))
|
||||
composedKey.clear();
|
||||
composedKey.put(PROPERTY_INT16, secondTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
composedKey.put(PROPERTY_STRING, secondTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue()
|
||||
.toValue());
|
||||
|
||||
URI esTwoKeyNavEntityManyTwoURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey)
|
||||
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
|
||||
|
||||
final ODataEntityRequest<ODataEntity> esTwoKeyNavManyTwoRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyTwoURI);
|
||||
esTwoKeyNavManyTwoRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavManyTwoResponse = esTwoKeyNavManyTwoRequest.execute();
|
||||
|
||||
assertEquals(451, esTwoKeyNavManyTwoResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
|
||||
PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertNotNull(esTwoKeyNavManyTwoResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue());
|
||||
assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyTwoResponse.getBody().getProperty(
|
||||
NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeepInsertSameEntitySet() throws EdmPrimitiveTypeException {
|
||||
final ODataClient client = getClient();
|
||||
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
|
||||
final ODataObjectFactory of = client.getObjectFactory();
|
||||
final ODataEntity entity = client.getObjectFactory().newEntity(ET_KEY_NAV);
|
||||
|
||||
// Prepare entity(EntitySet: ESKeyNav, Type: ETKeyNav)
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
|
||||
entity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
|
||||
entity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
|
||||
|
||||
// Prepare inline entity(EntitySet: ESKeyNav, Type: ETKeyNav)
|
||||
final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV);
|
||||
innerEntity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
|
||||
innerEntity.getProperties()
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
|
||||
innerEntity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
|
||||
innerEntity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))));
|
||||
innerEntity.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))));
|
||||
innerEntity
|
||||
.getProperties()
|
||||
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))
|
||||
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
|
||||
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder()
|
||||
.buildInt16((short) 431)))))));
|
||||
|
||||
ODataInlineEntity inlineEntity = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
|
||||
entity.addLink(inlineEntity);
|
||||
|
||||
final ODataEntityCreateResponse<ODataEntity> responseCreate =
|
||||
client.getCUDRequestFactory().getEntityCreateRequest(createURI, entity).execute();
|
||||
final String cookie = responseCreate.getHeader(HttpHeader.SET_COOKIE).iterator().next();
|
||||
final Short esKeyNavEntityKey =
|
||||
responseCreate.getBody().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class);
|
||||
|
||||
// Fetch Entity
|
||||
URI fetchEntityURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(esKeyNavEntityKey)
|
||||
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
|
||||
|
||||
ODataEntityRequest<ODataEntity> entityRequest = client.getRetrieveRequestFactory().getEntityRequest(fetchEntityURI);
|
||||
entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
final ODataRetrieveResponse<ODataEntity> entityResponse = entityRequest.execute();
|
||||
|
||||
// Check values
|
||||
assertEquals(431, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
|
||||
PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
|
||||
Short innerEntityInt16Key =
|
||||
entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16)
|
||||
.getPrimitiveValue().toCastValue(Short.class);
|
||||
|
||||
final URI innerEntityURI =
|
||||
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(innerEntityInt16Key)
|
||||
.build();
|
||||
final ODataEntityRequest<ODataEntity> innerRequest =
|
||||
client.getRetrieveRequestFactory().getEntityRequest(innerEntityURI);
|
||||
innerRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
ODataRetrieveResponse<ODataEntity> innerResponse = innerRequest.execute();
|
||||
|
||||
assertEquals(431, innerResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16)
|
||||
.getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
ODataClient odata = ODataClientFactory.getV4();
|
||||
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
|
||||
return odata;
|
||||
}
|
||||
}
|
|
@ -137,12 +137,11 @@ public class OrderBySystemQueryITCase extends AbstractBaseTestITCase {
|
|||
|
||||
private ODataRetrieveResponse<ODataEntitySet> sendRequest(String entitySet, String orderByString) {
|
||||
final ODataClient client = getClient();
|
||||
String escapedFilterString = escapeFilterString(orderByString);
|
||||
|
||||
final URI uri =
|
||||
client.newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment(entitySet)
|
||||
.orderBy(escapedFilterString)
|
||||
.orderBy(orderByString)
|
||||
.build();
|
||||
|
||||
ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory().getEntitySetRequest(uri);
|
||||
|
@ -158,11 +157,7 @@ public class OrderBySystemQueryITCase extends AbstractBaseTestITCase {
|
|||
assertEquals(errorCode.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeFilterString(String filterString) {
|
||||
return filterString.replace(" ", "%20");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
ODataClient odata = ODataClientFactory.getV4();
|
||||
|
|
|
@ -29,15 +29,15 @@ import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
|||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.api.uri.QueryOption;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntitySet;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
||||
public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
|
||||
private static final String PROPERTY_INT16 = "PropertyInt16";
|
||||
private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
|
||||
private static final String ES_ALL_PRIM = "ESAllPrim";
|
||||
|
@ -51,7 +51,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.COUNT, "true")
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.COUNT, "true")
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -83,14 +83,14 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.TOP, new Integer(5).toString())
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
assertEquals(5, response.getBody().getEntities().size());
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
CommonODataEntity entity = response.getBody().getEntities().get(i);
|
||||
ODataEntity entity = response.getBody().getEntities().get(i);
|
||||
assertEquals(new Integer(i + 1).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
|
||||
}
|
||||
}
|
||||
|
@ -103,14 +103,14 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.SKIP, new Integer(5).toString())
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
assertEquals(10, response.getBody().getEntities().size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CommonODataEntity entity = response.getBody().getEntities().get(i);
|
||||
ODataEntity entity = response.getBody().getEntities().get(i);
|
||||
assertEquals(new Integer(i + 6).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.SKIP, new Integer(503).toString())
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -139,7 +139,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.SKIP, new Integer(10000).toString())
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -158,7 +158,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.TOP, new Integer(43).toString()) // 102, 101, ...., 59
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -169,7 +169,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
|
||||
// Check first 10 entities
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CommonODataEntity entity = response.getBody().getEntities().get(i);
|
||||
ODataEntity entity = response.getBody().getEntities().get(i);
|
||||
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
|
||||
id--;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
assertEquals(Integer.valueOf(105), response.getBody().getCount());
|
||||
assertEquals(10, response.getBody().getEntities().size());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CommonODataEntity entity = response.getBody().getEntities().get(i);
|
||||
ODataEntity entity = response.getBody().getEntities().get(i);
|
||||
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
|
||||
id--;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
assertEquals(Integer.valueOf(105), response.getBody().getCount());
|
||||
assertEquals(3, response.getBody().getEntities().size());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CommonODataEntity entity = response.getBody().getEntities().get(i);
|
||||
ODataEntity entity = response.getBody().getEntities().get(i);
|
||||
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
|
||||
id--;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.appendEntitySetSegment(ES_SERVER_SIDE_PAGING)
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -234,7 +234,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.COUNT, Boolean.TRUE.toString())
|
||||
.build();
|
||||
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
|
||||
|
@ -273,7 +273,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.build();
|
||||
|
||||
try {
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
fail();
|
||||
|
@ -291,7 +291,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
.addQueryOption(QueryOption.TOP, new Integer(-5).toString())
|
||||
.build();
|
||||
try {
|
||||
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
|
||||
.getEntitySetRequest(uri)
|
||||
.execute();
|
||||
fail();
|
||||
|
@ -301,7 +301,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected CommonODataClient<?> getClient() {
|
||||
protected ODataClient getClient() {
|
||||
ODataClient odata = ODataClientFactory.getV4();
|
||||
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
|
||||
return odata;
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* 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
|
||||
|
@ -18,8 +18,10 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -29,24 +31,39 @@ 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.Property;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
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.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.data.EntityImpl;
|
||||
import org.apache.olingo.commons.core.data.EntitySetImpl;
|
||||
import org.apache.olingo.commons.core.data.LinkImpl;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmInt16;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmInt32;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmInt64;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
|
||||
public class DataProvider {
|
||||
|
||||
protected static final String MEDIA_PROPERTY_NAME = "$value";
|
||||
private static final String KEY_NAME = "PropertyInt16";
|
||||
// private static final String KEY_NAME = "PropertyInt16";
|
||||
|
||||
private Map<String, EntitySet> data;
|
||||
final private Map<String, EntitySet> data;
|
||||
private Edm edm;
|
||||
private OData odata;
|
||||
|
||||
public DataProvider() {
|
||||
data = new DataCreator().getData();
|
||||
|
@ -116,35 +133,97 @@ public class DataProvider {
|
|||
}
|
||||
}
|
||||
|
||||
// public Entity create(final EdmEntitySet edmEntitySet) throws DataProviderException {
|
||||
// final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||
// List<Entity> entities = readAll(edmEntitySet).getEntities();
|
||||
// Entity entity = new EntityImpl();
|
||||
// final List<String> keyNames = edmEntityType.getKeyPredicateNames();
|
||||
// if (keyNames.size() == 1 && keyNames.get(0).equals(KEY_NAME)) {
|
||||
// entity.addProperty(DataCreator.createPrimitive(KEY_NAME, findFreeKeyValue(entities)));
|
||||
// } else {
|
||||
// throw new DataProviderException("Key construction not supported!");
|
||||
// }
|
||||
// createProperties(edmEntityType, entity.getProperties());
|
||||
// entities.add(entity);
|
||||
// return entity;
|
||||
// }
|
||||
//
|
||||
// private Integer findFreeKeyValue(final List<Entity> entities) {
|
||||
// Integer result = 0;
|
||||
// boolean free;
|
||||
// do {
|
||||
// ++result;
|
||||
// free = true;
|
||||
// for (final Entity entity : entities) {
|
||||
// if (result.equals(entity.getProperty(KEY_NAME).getValue())) {
|
||||
// free = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// } while (!free);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public Entity create(final EdmEntitySet edmEntitySet) throws DataProviderException {
|
||||
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||
List<Entity> entities = readAll(edmEntitySet).getEntities();
|
||||
Entity entity = new EntityImpl();
|
||||
final List<String> keyNames = edmEntityType.getKeyPredicateNames();
|
||||
if (keyNames.size() == 1 && keyNames.get(0).equals(KEY_NAME)) {
|
||||
entity.addProperty(DataCreator.createPrimitive(KEY_NAME, findFreeKeyValue(entities)));
|
||||
} else {
|
||||
throw new DataProviderException("Key construction not supported!");
|
||||
final EntitySet entitySet = readAll(edmEntitySet);
|
||||
final List<Entity> entities = entitySet.getEntities();
|
||||
final Map<String, Object> newKey = findFreeComposedKey(entities, edmEntitySet.getEntityType());
|
||||
final Entity newEntity = new EntityImpl();
|
||||
|
||||
for (final String keyName : edmEntityType.getKeyPredicateNames()) {
|
||||
newEntity.addProperty(DataCreator.createPrimitive(keyName, newKey.get(keyName)));
|
||||
}
|
||||
createProperties(edmEntityType, entity.getProperties());
|
||||
entities.add(entity);
|
||||
return entity;
|
||||
|
||||
createProperties(edmEntityType, newEntity.getProperties());
|
||||
entities.add(newEntity);
|
||||
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
private Integer findFreeKeyValue(final List<Entity> entities) {
|
||||
Integer result = 0;
|
||||
boolean free;
|
||||
do {
|
||||
++result;
|
||||
free = true;
|
||||
for (final Entity entity : entities) {
|
||||
if (result.equals(entity.getProperty(KEY_NAME).getValue())) {
|
||||
free = false;
|
||||
break;
|
||||
private Map<String, Object> findFreeComposedKey(final List<Entity> entities, final EdmEntityType entityType)
|
||||
throws DataProviderException {
|
||||
// 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>();
|
||||
for (final String keyName : entityType.getKeyPredicateNames()) {
|
||||
final EdmType type = entityType.getProperty(keyName).getType();
|
||||
Object newValue = null;
|
||||
|
||||
if (type instanceof EdmInt16 || type instanceof EdmInt32 || type instanceof EdmInt64) {
|
||||
// Integer keys
|
||||
newValue = Integer.valueOf(1);
|
||||
|
||||
while (!isFree(newValue, keyName, entities)) {
|
||||
newValue = ((Integer) newValue) + 1;
|
||||
}
|
||||
} else if (type instanceof EdmString) {
|
||||
// String keys
|
||||
newValue = String.valueOf(1);
|
||||
int i = 0;
|
||||
|
||||
while (!isFree(newValue, keyName, entities)) {
|
||||
newValue = String.valueOf(i);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
throw new DataProviderException("Key type not supported");
|
||||
}
|
||||
} while (!free);
|
||||
return result;
|
||||
|
||||
keys.put(keyName, newValue);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
private boolean isFree(final Object value, final String keyPropertyName, final List<Entity> entities) {
|
||||
for (final Entity entity : entities) {
|
||||
if (value != null && value.equals(entity.getProperty(keyPropertyName).getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void createProperties(final EdmStructuredType type, List<Property> properties) throws DataProviderException {
|
||||
|
@ -173,10 +252,14 @@ public class DataProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public void update(final EdmEntitySet edmEntitySet, Entity entity, final Entity changedEntity, final boolean patch)
|
||||
throws DataProviderException {
|
||||
public void update(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity,
|
||||
final Entity changedEntity, final boolean patch,
|
||||
final boolean isInsert) throws DataProviderException {
|
||||
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final List<String> keyNames = entityType.getKeyPredicateNames();
|
||||
|
||||
// Update Properties
|
||||
for (final String propertyName : entityType.getPropertyNames()) {
|
||||
if (!keyNames.contains(propertyName)) {
|
||||
updateProperty(entityType.getStructuralProperty(propertyName),
|
||||
|
@ -185,8 +268,140 @@ public class DataProvider {
|
|||
patch);
|
||||
}
|
||||
}
|
||||
|
||||
// Deep insert (only if not an update)
|
||||
if (isInsert) {
|
||||
handleDeepInsert(rawBaseUri, edmEntitySet, entity, changedEntity);
|
||||
} else if (isInsert && changedEntity.getNavigationLinks().size() != 0) {
|
||||
throw new DataProviderException("Deep inserts are not allowed in update operations using PUT or PATCH requests.");
|
||||
}
|
||||
|
||||
if (!changedEntity.getNavigationBindings().isEmpty()) {
|
||||
throw new DataProviderException("Binding operations are not yet supported.");
|
||||
applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings());
|
||||
}
|
||||
}
|
||||
|
||||
private void applyNavigationBinding(final String rawBaseUri, final EdmEntitySet edmEntitySet,
|
||||
final Entity entity, final List<Link> navigationBindings) throws DataProviderException {
|
||||
|
||||
for (final Link link : navigationBindings) {
|
||||
final EdmNavigationProperty edmNavProperty = edmEntitySet.getEntityType().getNavigationProperty(link.getTitle());
|
||||
final EdmEntitySet edmTargetEntitySet =
|
||||
(EdmEntitySet) edmEntitySet.getRelatedBindingTarget(edmNavProperty.getName());
|
||||
|
||||
if (edmNavProperty.isCollection()) {
|
||||
for (final String bindingLink : link.getBindingLinks()) {
|
||||
final Entity destEntity = getEntityByURI(rawBaseUri, edmTargetEntitySet, bindingLink);
|
||||
createLink(edmNavProperty, entity, destEntity);
|
||||
}
|
||||
} else {
|
||||
final String bindingLink = link.getBindingLink();
|
||||
final Entity destEntity = getEntityByURI(rawBaseUri, edmTargetEntitySet, bindingLink);
|
||||
createLink(edmNavProperty, entity, destEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Entity getEntityByURI(final String rawBaseUri, final EdmEntitySet edmEntitySetTarget,
|
||||
final String bindingLink) throws DataProviderException {
|
||||
|
||||
try {
|
||||
final List<UriParameter> keys = odata.createUriHelper()
|
||||
.getKeyPredicatesFromEntityLink(edm, bindingLink, rawBaseUri);
|
||||
final Entity entity = read(edmEntitySetTarget, keys);
|
||||
|
||||
if(entity == null) {
|
||||
throw new DataProviderException("Entity " + bindingLink + " not found");
|
||||
}
|
||||
|
||||
return entity;
|
||||
} catch (DeserializerException e) {
|
||||
throw new DataProviderException("Invalid entity binding link", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeepInsert(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity,
|
||||
final Entity changedEntity)
|
||||
throws DataProviderException {
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
|
||||
for (final String navPropertyName : entityType.getNavigationPropertyNames()) {
|
||||
final Link navigationLink = changedEntity.getNavigationLink(navPropertyName);
|
||||
|
||||
if (navigationLink != null) {
|
||||
// Deep inserts are not allowed in update operations, so we can be sure, that we do not override
|
||||
// a navigation link!
|
||||
final EdmNavigationProperty navigationProperty = entityType.getNavigationProperty(navPropertyName);
|
||||
final EdmBindingTarget target = edmEntitySet.getRelatedBindingTarget(navPropertyName);
|
||||
final EdmEntityType inlineEntityType = navigationProperty.getType();
|
||||
|
||||
if (navigationProperty.isCollection()) {
|
||||
final List<Entity> entities =
|
||||
createInlineEntities(rawBaseUri, target, inlineEntityType, navigationLink.getInlineEntitySet());
|
||||
|
||||
for (final Entity inlineEntity : entities) {
|
||||
createLink(navigationProperty, entity, inlineEntity);
|
||||
}
|
||||
} else {
|
||||
final Entity inlineEntity =
|
||||
createInlineEntity(rawBaseUri, target, inlineEntityType, navigationLink.getInlineEntity());
|
||||
createLink(navigationProperty, entity, inlineEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Entity> createInlineEntities(final String rawBaseUri, final EdmBindingTarget target,
|
||||
final EdmEntityType type, final EntitySet changedEntitsSet) throws DataProviderException {
|
||||
List<Entity> entities = new ArrayList<Entity>();
|
||||
|
||||
for (final Entity newEntity : changedEntitsSet.getEntities()) {
|
||||
entities.add(createInlineEntity(rawBaseUri, target, type, newEntity));
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
private Entity createInlineEntity(final String rawBaseUri, final EdmBindingTarget target,
|
||||
final EdmEntityType type, final Entity changedEntity) throws DataProviderException {
|
||||
|
||||
final Entity inlineEntity = create((EdmEntitySet) target);
|
||||
update(rawBaseUri, (EdmEntitySet) target, inlineEntity, changedEntity, false, true);
|
||||
|
||||
return inlineEntity;
|
||||
}
|
||||
|
||||
private void createLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity,
|
||||
final Entity destEntity) {
|
||||
setLink(navigationProperty, srcEntity, destEntity);
|
||||
|
||||
final EdmNavigationProperty partnerNavigationProperty = navigationProperty.getPartner();
|
||||
if (partnerNavigationProperty != null) {
|
||||
setLink(partnerNavigationProperty, destEntity, srcEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Duplicated code in DataCreator
|
||||
private void setLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity,
|
||||
final Entity destEntity) {
|
||||
|
||||
Link link = srcEntity.getNavigationLink(navigationProperty.getName());
|
||||
if (link == null) {
|
||||
link = new LinkImpl();
|
||||
link.setTitle(navigationProperty.getName());
|
||||
srcEntity.getNavigationLinks().add(link);
|
||||
}
|
||||
|
||||
if (navigationProperty.isCollection()) {
|
||||
if (link.getInlineEntitySet() == null) {
|
||||
link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
|
||||
link.setInlineEntitySet(new EntitySetImpl());
|
||||
}
|
||||
|
||||
link.getInlineEntitySet().getEntities().add(destEntity);
|
||||
} else {
|
||||
link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
|
||||
link.setInlineEntity(destEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +453,14 @@ public class DataProvider {
|
|||
entity.setMediaContentType(type);
|
||||
}
|
||||
|
||||
public void setEdm(final Edm edm) {
|
||||
this.edm = edm;
|
||||
}
|
||||
|
||||
public void setOData(final OData odata) {
|
||||
this.odata = odata;
|
||||
}
|
||||
|
||||
public static class DataProviderException extends ODataApplicationException {
|
||||
private static final long serialVersionUID = 5098059649321796156L;
|
||||
|
||||
|
|
|
@ -53,8 +53,12 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
|||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.SystemQueryOptions;
|
||||
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.OrderByHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.ServerSidePagingHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
|
||||
|
||||
/**
|
||||
* Technical Processor for entity-related functionality.
|
||||
|
@ -83,9 +87,17 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
entitySet.getEntities().addAll(entitySetInitial.getEntities());
|
||||
|
||||
// Apply system query options
|
||||
SystemQueryOptions.applySystemQueryOptions(entitySet, edmEntitySet, uriInfo);
|
||||
ServerSidePagingHandler.applyServerSidePaging(entitySet, request.getRawRequestUri(), uriInfo);
|
||||
|
||||
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
|
||||
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
|
||||
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
|
||||
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
|
||||
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
|
||||
|
||||
ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(),
|
||||
entitySet,
|
||||
edmEntitySet,
|
||||
request.getRawRequestUri());
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
|
@ -114,7 +126,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
EntitySet entitySet = readEntityCollection(uriInfo);
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
|
@ -150,7 +162,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
@Override
|
||||
public void readMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType responseFormat) throws ODataApplicationException, SerializerException {
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
final Entity entity = readEntity(uriInfo);
|
||||
response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity)));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
|
@ -167,7 +179,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
@Override
|
||||
public void createEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
|
@ -182,10 +194,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
||||
requestFormat.toContentTypeString());
|
||||
} else {
|
||||
dataProvider.update(edmEntitySet, entity,
|
||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity,
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.entity(request.getBody(), edmEntityType),
|
||||
false);
|
||||
false, true);
|
||||
}
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(responseFormat);
|
||||
|
@ -204,21 +216,22 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
@Override
|
||||
public void updateEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
||||
Entity entity = readEntity(uriInfo);
|
||||
checkRequestFormat(requestFormat);
|
||||
ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
||||
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType());
|
||||
dataProvider.update(edmEntitySet, entity, changedEntity, request.getMethod() == HttpMethod.PATCH);
|
||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
||||
request.getMethod() == HttpMethod.PATCH, false);
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
Entity entity = readEntity(uriInfo);
|
||||
checkRequestFormat(requestFormat);
|
||||
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
||||
|
@ -244,7 +257,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
private void setCount(EntitySet entitySet) {
|
||||
// TODO: set count (correctly) and next link
|
||||
if (entitySet.getCount() == null) {
|
||||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ public abstract class TechnicalProcessor implements Processor {
|
|||
|
||||
protected OData odata;
|
||||
protected DataProvider dataProvider;
|
||||
protected ServiceMetadata serviceMetadata;
|
||||
|
||||
protected TechnicalProcessor(final DataProvider dataProvider) {
|
||||
this.dataProvider = dataProvider;
|
||||
|
@ -54,6 +55,9 @@ public abstract class TechnicalProcessor implements Processor {
|
|||
@Override
|
||||
public void init(final OData odata, final ServiceMetadata serviceMetadata) {
|
||||
this.odata = odata;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
this.dataProvider.setOData(odata);
|
||||
this.dataProvider.setEdm(serviceMetadata.getEdm());
|
||||
}
|
||||
|
||||
protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* 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.processor.queryoptions;
|
||||
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
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.OrderByHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
|
||||
|
||||
public class SystemQueryOptions {
|
||||
public static void applySystemQueryOptions(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
|
||||
final UriInfo uriInfo) throws ODataApplicationException {
|
||||
|
||||
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
|
||||
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
|
||||
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
|
||||
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
|
||||
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
|
||||
}
|
||||
}
|
|
@ -27,5 +27,4 @@ public class CountHandler {
|
|||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
|
|||
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.FilterRuntimeException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand;
|
||||
|
||||
public class OrderByHandler {
|
||||
|
@ -44,7 +43,7 @@ public class OrderByHandler {
|
|||
|
||||
try {
|
||||
applyOrderByOptionInternal(orderByOption, entitySet, edmEntitySet);
|
||||
} catch (FilterRuntimeException e) {
|
||||
} catch (SystemQueryOptionsRuntimeException e) {
|
||||
if (e.getCause() instanceof ODataApplicationException) {
|
||||
// Throw the nested exception, to send the correct HTTP status code in the HTTP response
|
||||
throw (ODataApplicationException) e.getCause();
|
||||
|
@ -93,9 +92,9 @@ public class OrderByHandler {
|
|||
|
||||
result = item.isDescending() ? result * -1 : result;
|
||||
} catch (ODataApplicationException e) {
|
||||
throw new FilterRuntimeException(e);
|
||||
throw new SystemQueryOptionsRuntimeException(e);
|
||||
} catch (ExpressionVisitException e) {
|
||||
throw new FilterRuntimeException(e);
|
||||
throw new SystemQueryOptionsRuntimeException(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -23,22 +23,23 @@ import java.net.URISyntaxException;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.Encoder;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||
|
||||
public class ServerSidePagingHandler {
|
||||
private static final int MAX_PAGE_SIZE = 10;
|
||||
private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
|
||||
|
||||
public static void
|
||||
applyServerSidePaging(final EntitySet entitySet, final String rawRequestUri, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
if (shouldApplyServerSidePaging(entitySet)) {
|
||||
public static void applyServerSidePaging(final SkipTokenOption skipTokenOption, final EntitySet entitySet,
|
||||
final EdmEntitySet edmEntitySet, final String rawRequestUri) throws ODataApplicationException {
|
||||
|
||||
if (shouldApplyServerSidePaging(edmEntitySet)) {
|
||||
final int maxPageSize = getMaxPageSize();
|
||||
final int page = getPage(uriInfo.getSkipTokenOption());
|
||||
final int page = getPage(skipTokenOption);
|
||||
final int itemsToSkip = maxPageSize * page;
|
||||
|
||||
if (itemsToSkip <= entitySet.getEntities().size()) {
|
||||
|
@ -48,16 +49,15 @@ public class ServerSidePagingHandler {
|
|||
|
||||
// Determine if a new next Link has to be provided
|
||||
if (remainingItems > maxPageSize) {
|
||||
entitySet.setNext(createNextLink(uriInfo, rawRequestUri, page + 1));
|
||||
entitySet.setNext(createNextLink(rawRequestUri, page + 1));
|
||||
}
|
||||
} else {
|
||||
throw new ODataApplicationException("Invalid skiptoken", HttpStatusCode.BAD_REQUEST.getStatusCode(),
|
||||
Locale.ROOT);
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static URI createNextLink(final UriInfo uriInfo, final String rawRequestUri, final Integer page)
|
||||
private static URI createNextLink(final String rawRequestUri, final Integer page)
|
||||
throws ODataApplicationException {
|
||||
|
||||
try {
|
||||
|
@ -99,8 +99,8 @@ public class ServerSidePagingHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean shouldApplyServerSidePaging(final EntitySet entitySet) {
|
||||
return true;
|
||||
private static boolean shouldApplyServerSidePaging(final EdmEntitySet edmEntitySet) {
|
||||
return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName());
|
||||
}
|
||||
|
||||
private static int getMaxPageSize() {
|
||||
|
|
|
@ -16,23 +16,15 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor.queryoptions.expression;
|
||||
package org.apache.olingo.server.tecsvc.processor.queryoptions.options;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
|
||||
public class FilterRuntimeException extends ODataRuntimeException {
|
||||
public class SystemQueryOptionsRuntimeException extends ODataRuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FilterRuntimeException(Exception cause) {
|
||||
public SystemQueryOptionsRuntimeException(Exception cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public FilterRuntimeException(String msg, Exception cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public FilterRuntimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue