/* * 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.fail; import java.net.URI; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; 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.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientInlineEntity; import org.apache.olingo.client.api.domain.ClientLink; import org.apache.olingo.client.api.domain.ClientObjectFactory; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.junit.Test; public class BindingITCase extends AbstractParamTecSvcITCase { 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_COMP_NAV = SERVICE_NAMESPACE+"."+"CTCompNav"; private static final String CT_TWO_PRIM = SERVICE_NAMESPACE+"."+"CTTwoPrim"; private static final String CT_ALL_PRIM = SERVICE_NAMESPACE+"."+"CTAllPrim"; private static final String CT_NAV_FIVE_PROP = SERVICE_NAMESPACE+"."+"CTNavFiveProp"; private static final String PROPERTY_INT16 = "PropertyInt16"; private static final String PROPERTY_STRING = "PropertyString"; private static final String PROPERTY_COMP_NAV = "PropertyCompNav"; private static final String PROPERTY_COMP_COMP_NAV = "PropertyCompCompNav"; 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_ONE = "NavPropertyETTwoKeyNavOne"; private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany"; @Test public void createBindingSimple() throws EdmPrimitiveTypeException { ODataClient client = getClient(); final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build(); // Create entity (EntitySet: ESKeyNav, Type: ETKeyNav) ClientObjectFactory factory = getFactory(); final ClientEntity entity = factory.newEntity(ET_KEY_NAV); entity.getProperties() .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16((short) 42))); entity.getProperties() .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("42"))); entity.getProperties() .add(factory.newComplexProperty(PROPERTY_COMP_NAV, factory.newComplexValue(CT_NAV_FIVE_PROP) .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16((short) 42))))); entity.getProperties() .add(factory.newComplexProperty(PROPERTY_COMP_ALL_PRIM, factory.newComplexValue(CT_ALL_PRIM) .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("42"))))); entity.getProperties() .add(factory.newComplexProperty(PROPERTY_COMP_TWO_PRIM, factory.newComplexValue(CT_TWO_PRIM) .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16 ((short) 42))) .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("42"))))); entity.getProperties() .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV, factory.newComplexValue(CT_COMP_NAV) .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder() .buildString("42"))) .add(factory.newComplexProperty(PROPERTY_COMP_NAV, factory.newComplexValue(CT_NAV_FIVE_PROP) .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16((short) 42))))))); // Bind existing entities via binding synatx entity.addLink(factory.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 ClientLink navLinkOne = factory.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment( ES_KEY_NAV).appendKeySegment(1).build()); final ClientLink navLinkMany1 = factory.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment( ES_KEY_NAV).appendKeySegment(2).build()); final ClientLink navLinkMany2 = factory.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment( ES_KEY_NAV).appendKeySegment(3).build()); HashMap<String, Object> combinedKey = new HashMap<String, Object>(); combinedKey.put(PROPERTY_INT16, 1); combinedKey.put(PROPERTY_STRING, "1"); final ClientLink navLink2Many = factory.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); EdmEnabledODataClient edmEnabledClient = getEdmEnabledClient(); final ODataEntityCreateResponse<ClientEntity> createResponse = edmEnabledClient.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 = edmEnabledClient.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<ClientEntity> entityGetRequest = edmEnabledClient.getRetrieveRequestFactory().getEntityRequest(entityGetURI); entityGetRequest.addCustomHeader(HttpHeader.COOKIE, cookie); final ODataRetrieveResponse<ClientEntity> entityGetResponse = entityGetRequest.execute(); // NAV_PROPERTY_ET_KEY_NAV_ONE assertShortOrInt(1, entityGetResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) .asInlineEntity().getEntity().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class)); // NAV_PROPERTY_ET_KEY_NAV_MANY(0) Iterator<ClientEntity> iterator = entityGetResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY) .asInlineEntitySet().getEntitySet().getEntities().iterator(); assertShortOrInt(2, iterator.next().getProperty(PROPERTY_INT16).getPrimitiveValue() .toCastValue(Short.class)); // NAV_PROPERTY_ET_KEY_NAV_MANY(1) assertShortOrInt(3, iterator.next().getProperty(PROPERTY_INT16).getPrimitiveValue() .toCastValue(Short.class)); // NAV_PROPERTY_ET_TWO_KEY_NAV_MANY(0) assertShortOrInt(1, entityGetResponse.getBody() .getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet().getEntities() .iterator().next().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class)); assertEquals("1", entityGetResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY) .asInlineEntitySet().getEntitySet().getEntities().iterator().next() .getProperty(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<ClientEntity> etTwoKeyNavEntityRequest = edmEnabledClient.getRetrieveRequestFactory().getEntityRequest(etTwoKeyNavEntityURI); etTwoKeyNavEntityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); final ODataRetrieveResponse<ClientEntity> etTwoKeyNavEntityResponse = etTwoKeyNavEntityRequest.execute(); assertEquals(entityInt16Key, etTwoKeyNavEntityResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) .asInlineEntity().getEntity().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class)); } @Test public void updateBinding() throws Exception { // 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 URI entityURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build(); // ESKeyNav(1).NavPropertyETKeyNavOne = ESKeyNav(2) // ESKeyNav(1).NavPropertyETKeyNavMany = { ESKeyNav(1), ESKeyNav(2) } // => Replace NavPropertyETKeyNavOne with ESKeyNav(3) // => Add to NavPropertyETKeyNavOne ESKeyNav(3) final ClientEntity entity = getFactory().newEntity(ET_KEY_NAV); final ClientLink navLinkOne = getFactory().newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build()); final ClientLink navLinkMany = getFactory().newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build()); entity.addLink(navLinkOne); entity.addLink(navLinkMany); final EdmEnabledODataClient edmEnabledClient = getEdmEnabledClient(); final ODataEntityUpdateResponse<ClientEntity> updateResponse = edmEnabledClient.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 = getClient().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<ClientEntity> entityRequest = edmEnabledClient.getRetrieveRequestFactory().getEntityRequest(entityGetURI); entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); final ODataRetrieveResponse<ClientEntity> entityResponse = entityRequest.execute(); assertShortOrInt(3, entityResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) .asInlineEntity().getEntity().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class)); assertEquals(3, entityResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet() .getEntitySet().getEntities().size()); Iterator<ClientEntity> iterator = entityResponse.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY) .asInlineEntitySet().getEntitySet().getEntities().iterator(); assertEquals(Short.valueOf((short) 1), iterator.next().getProperty(PROPERTY_INT16).getPrimitiveValue() .toCastValue(Short.class)); assertEquals(Short.valueOf((short) 2), iterator.next().getProperty(PROPERTY_INT16).getPrimitiveValue() .toCastValue(Short.class)); assertEquals(Short.valueOf((short) 3), iterator.next().getProperty(PROPERTY_INT16).getPrimitiveValue() .toCastValue(Short.class)); } @Test public void missingEntity() { // Update an existing entity, use a URI to a not existing entity // Perform the request to a single navigation property and a collection navigation property as well. // Expected: Not Found (404) final URI entityURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build(); // Request to single (non collection) navigation property ClientEntity entity = getFactory().newEntity(ET_KEY_NAV); final ClientLink navLinkOne = getFactory().newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(42).build()); entity.addLink(navLinkOne); try { getEdmEnabledClient().getCUDRequestFactory() .getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute(); fail(); } catch (ODataClientErrorException e) { assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode()); } // Request to collection navigation propetry entity = getFactory().newEntity(ET_KEY_NAV); final ClientLink navLinkMany = getFactory().newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build()); entity.addLink(navLinkMany); try { getEdmEnabledClient().getCUDRequestFactory() .getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute(); } catch (ODataClientErrorException e) { assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode()); } } @Test public void deepInsertWithBindingSameNavigationProperty() { final ClientObjectFactory factory = getFactory(); final ClientEntity entity = factory.newEntity(ET_KEY_NAV); entity.getProperties().add(factory.newPrimitiveProperty(PROPERTY_STRING, factory .newPrimitiveValueBuilder() .buildString("1"))); entity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_TWO_PRIM, factory.newComplexValue (CT_TWO_PRIM) .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16 ((short) 1))) .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("1"))))); final ClientEntity innerEntity = factory.newEntity(ET_KEY_NAV); innerEntity.getProperties().add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder() .buildString("2"))); innerEntity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_TWO_PRIM, factory.newComplexValue(CT_TWO_PRIM) .add(factory.newPrimitiveProperty(PROPERTY_INT16, factory.newPrimitiveValueBuilder().buildInt16((short) 1))) .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("2"))))); innerEntity.addLink(factory.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_TWO_KEY_NAV) .appendKeySegment(new LinkedHashMap<String, Object>() { private static final long serialVersionUID = 1L; { put(PROPERTY_INT16, 3); put(PROPERTY_STRING, "1"); } }).build())); final ClientInlineEntity inlineLink = factory.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity); entity.addLink(inlineLink); entity.addLink(factory.newEntityNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, getClient().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 = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV) .appendKeySegment(3) .build(); entity.addLink(factory.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, bindingURI)); final URI targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build(); final ODataEntityCreateResponse<ClientEntity> response = getEdmEnabledClient().getCUDRequestFactory().getEntityCreateRequest(targetURI, entity).execute(); assertEquals(HttpStatusCode.CREATED.getStatusCode(), response.getStatusCode()); if (isJson()) { assertEquals(1, response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) .asInlineEntity() .getEntity() .getProperty(PROPERTY_COMP_TWO_PRIM) .getComplexValue() .get(PROPERTY_INT16) .getPrimitiveValue() .toValue()); } } }