@Test public void testMissingEntity() { // 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 ODataClient client = getClient(); final URI entityURI = client .newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV) .appendKeySegment(1) .build(); final ClientObjectFactory of = client.getObjectFactory(); // Request to single (non collection) navigation property ClientEntity entity = of.newEntity(ET_KEY_NAV); final ClientLink navLinkOne = of.newEntityNavigationLink( NAV_PROPERTY_ET_KEY_NAV_ONE, client .newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV) .appendKeySegment(42) .build()); entity.addLink(navLinkOne); try { client .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 = of.newEntity(ET_KEY_NAV); final ClientLink navLinkMany = of.newEntitySetNavigationLink( NAV_PROPERTY_ET_KEY_NAV_MANY, client .newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_KEY_NAV) .appendKeySegment(3) .build()); entity.addLink(navLinkMany); try { client .getCUDRequestFactory() .getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity) .execute(); } catch (ODataClientErrorException e) { assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode()); } }
@Test public void errorWithContinueOnErrorPreferHeader() throws Exception { ODataClient client = getClient(); client.getConfiguration().setContinueOnError(true); final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); final BatchManager payload = request.payloadManager(); appendGetRequest(payload, "ESAllPrim", 32767, false); // Without error appendGetRequest(payload, "ESAllPrim", 42, false); // Error ( Key does not exist ) appendGetRequest(payload, "ESAllPrim", 0, false); // Without error // Fetch result final ODataBatchResponse response = payload.getResponse(); assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); assertEquals( PreferenceName.CONTINUE_ON_ERROR.getName(), response.getHeader(HttpHeader.PREFERENCE_APPLIED).iterator().next()); final Iterator<ODataBatchResponseItem> bodyIterator = response.getBody(); // Check first get request assertTrue(bodyIterator.hasNext()); ODataBatchResponseItem item = bodyIterator.next(); assertFalse(item.isChangeset()); ODataResponse oDataResponse = item.next(); assertNotNull(oDataResponse); assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode()); assertEquals(1, oDataResponse.getHeader(HttpHeader.ODATA_VERSION).size()); assertEquals("4.0", oDataResponse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]); assertEquals(1, oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).size()); assertEquals("605", oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]); assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType()); // Check second get request assertTrue(bodyIterator.hasNext()); item = bodyIterator.next(); assertFalse(item.isChangeset()); oDataResponse = item.next(); assertNotNull(oDataResponse); assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResponse.getStatusCode()); // Check if third request is available assertTrue(bodyIterator.hasNext()); item = bodyIterator.next(); assertFalse(item.isChangeset()); oDataResponse = item.next(); assertNotNull(oDataResponse); assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode()); assertEquals(1, oDataResponse.getHeader(HttpHeader.ODATA_VERSION).size()); assertEquals("4.0", oDataResponse.getHeader(HttpHeader.ODATA_VERSION).iterator().next()); assertEquals(1, oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).size()); assertEquals("517", oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).iterator().next()); assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType()); }
@Test public void badRequestInChangeSet() { /* * A bad request (status code >= 400) without "continue on error prefer header" in a changeset * should return a single response with Content-Type: application/http * * See: * OData Version 4.0 Part 1: Protocol Plus Errata 01 * 11.7.4 Responding to a Batch Request * * When a request within a change set fails, the change set response is not represented using * the multipart/mixed media type. Instead, a single response, using the application/http media type * and a Content-Transfer-Encoding header with a value of binary, is returned that applies to all requests * in the change set and MUST be formatted according to the Error Handling defined * for the particular response format. */ // Try to create entity, with invalid type ClientObjectFactory factory = getFactory(); final ClientEntity entity = factory.newEntity(ES_NOT_AVAILABLE); entity .getProperties() .add( factory.newPrimitiveProperty( PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("1"))); final ODataBatchRequest batchRequest = getClient().getBatchRequestFactory().getBatchRequest(SERVICE_URI); final BatchManager payloadManager = batchRequest.payloadManager(); final ODataChangeset changeset = payloadManager.addChangeset(); final URI targetURI = getClient() .newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_NOT_AVAILABLE_NAME) .build(); final ODataEntityCreateRequest<ClientEntity> createRequest = getClient().getCUDRequestFactory().getEntityCreateRequest(targetURI, entity); changeset.addRequest(createRequest); final ODataBatchResponse response = payloadManager.getResponse(); assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); // Check response items final Iterator<ODataBatchResponseItem> responseBodyIter = response.getBody(); assertTrue(responseBodyIter.hasNext()); final ODataBatchResponseItem changeSetResponse = responseBodyIter.next(); assertTrue(changeSetResponse.isChangeset()); assertTrue(changeSetResponse.hasNext()); final ODataResponse updateResponse = changeSetResponse.next(); assertTrue(changeSetResponse.isBreaking()); assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), updateResponse.getStatusCode()); assertContentType(updateResponse.getContentType()); }
@Override public void readPrimitiveValue( ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format) throws ODataApplicationException, SerializerException { // First we have to figure out which entity set the requested entity is in final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); // Next we fetch the requested entity from the database final Entity entity; try { entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet); } catch (DataProviderException e) { throw new ODataApplicationException(e.getMessage(), 500, Locale.ENGLISH); } if (entity == null) { // If no entity was found for the given key we throw an exception. throw new ODataApplicationException( "No entity found for this key", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } else { // Next we get the property value from the entity and pass the value to serialization UriResourceProperty uriProperty = (UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 1); EdmProperty edmProperty = uriProperty.getProperty(); Property property = entity.getProperty(edmProperty.getName()); if (property == null) { throw new ODataApplicationException( "No property found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } else { if (property.getValue() == null) { response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); } else { String value = String.valueOf(property.getValue()); ByteArrayInputStream serializerContent = new ByteArrayInputStream(value.getBytes(Charset.forName("UTF-8"))); response.setContent(serializerContent); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString()); } } } }
@Override public void readEntity( final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestedContentType) throws ODataApplicationException, SerializerException { // First we have to figure out which entity set the requested entity is in final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); // Next we fetch the requested entity from the database Entity entity; try { entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet); } catch (DataProviderException e) { throw new ODataApplicationException(e.getMessage(), 500, Locale.ENGLISH); } if (entity == null) { // If no entity was found for the given key we throw an exception. throw new ODataApplicationException( "No entity found for this key", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } else { // If an entity was found we proceed by serializing it and sending it to the client. ODataSerializer serializer = odata.createSerializer(requestedContentType); final ExpandOption expand = uriInfo.getExpandOption(); final SelectOption select = uriInfo.getSelectOption(); InputStream serializedContent = serializer .entity( edm, edmEntitySet.getEntityType(), entity, EntitySerializerOptions.with() .contextURL( isODataMetadataNone(requestedContentType) ? null : getContextUrl(edmEntitySet, true, expand, select, null)) .expand(expand) .select(select) .build()) .getContent(); response.setContent(serializedContent); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); } }
@Test public void errorWithoutContinueOnErrorPreferHeader() throws URISyntaxException { final ODataBatchRequest request = getClient().getBatchRequestFactory().getBatchRequest(SERVICE_URI); final BatchManager payload = request.payloadManager(); appendGetRequest(payload, "ESAllPrim", 32767, false); // Without error appendGetRequest(payload, "ESAllPrim", 42, false); // Error ( Key does not exist ) appendGetRequest(payload, "ESAllPrim", 0, false); // Without error // Fetch result final ODataBatchResponse response = payload.getResponse(); assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); final Iterator<ODataBatchResponseItem> iter = response.getBody(); // Check first get request assertTrue(iter.hasNext()); ODataBatchResponseItem item = iter.next(); assertFalse(item.isChangeset()); ODataResponse oDataResponse = item.next(); assertNotNull(oDataResponse); assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode()); assertEquals(1, oDataResponse.getHeader("OData-Version").size()); assertEquals("4.0", oDataResponse.getHeader("OData-Version").toArray()[0]); assertEquals(1, oDataResponse.getHeader("Content-Length").size()); assertEquals("605", oDataResponse.getHeader("Content-Length").toArray()[0]); assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType()); // Check second get request assertTrue(iter.hasNext()); item = iter.next(); assertFalse(item.isChangeset()); oDataResponse = item.next(); assertNotNull(oDataResponse); assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResponse.getStatusCode()); // Check if third request is available assertFalse(iter.hasNext()); }
private void readProperty( ODataResponse response, UriInfo uriInfo, ContentType contentType, boolean complex) throws ODataApplicationException, SerializerException { // To read a property we have to first get the entity out of the entity set final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); Entity entity; try { entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet); } catch (DataProviderException e) { throw new ODataApplicationException( e.getMessage(), HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH); } if (entity == null) { // If no entity was found for the given key we throw an exception. throw new ODataApplicationException( "No entity found for this key", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } else { // Next we get the property value from the entity and pass the value to serialization UriResourceProperty uriProperty = (UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 1); EdmProperty edmProperty = uriProperty.getProperty(); Property property = entity.getProperty(edmProperty.getName()); if (property == null) { throw new ODataApplicationException( "No property found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } else { if (property.getValue() == null) { response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); } else { ODataSerializer serializer = odata.createSerializer(contentType); final ContextURL contextURL = isODataMetadataNone(contentType) ? null : getContextUrl(edmEntitySet, true, null, null, edmProperty.getName()); InputStream serializerContent = complex ? serializer .complex( edm, (EdmComplexType) edmProperty.getType(), property, ComplexSerializerOptions.with().contextURL(contextURL).build()) .getContent() : serializer .primitive( edm, (EdmPrimitiveType) edmProperty.getType(), property, PrimitiveSerializerOptions.with() .contextURL(contextURL) .scale(edmProperty.getScale()) .nullable(edmProperty.isNullable()) .precision(edmProperty.getPrecision()) .maxLength(edmProperty.getMaxLength()) .unicode(edmProperty.isUnicode()) .build()) .getContent(); response.setContent(serializerContent); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString()); } } } }