diff --git a/ODataJClient/test-service/src/main/java/com/msopentech/odatajclient/testservice/utils/Commons.java b/ODataJClient/test-service/src/main/java/com/msopentech/odatajclient/testservice/utils/Commons.java index 403f3bce5..a075c7f80 100644 --- a/ODataJClient/test-service/src/main/java/com/msopentech/odatajclient/testservice/utils/Commons.java +++ b/ODataJClient/test-service/src/main/java/com/msopentech/odatajclient/testservice/utils/Commons.java @@ -57,7 +57,7 @@ public abstract class Commons { protected final static Map sequence = new HashMap(); - protected final static Set mediaContent = new HashSet(); + public final static Set mediaContent = new HashSet(); protected final static Map linkInfo = new EnumMap(ODataVersion.class); @@ -65,12 +65,14 @@ public abstract class Commons { static { sequence.put("Customer", 1000); sequence.put("CustomerInfo", 1000); + sequence.put("Car", 1000); sequence.put("Message", 1000); sequence.put("Order", 1000); sequence.put("ComputerDetail", 1000); sequence.put("AllGeoTypesSet", 1000); mediaContent.add("CustomerInfo"); + mediaContent.add("Car"); } public static String getEntityURI(final String entitySetName, final String entityKey) { diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java index 43f47bb42..12032c583 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -282,7 +282,7 @@ public abstract class AbstractServices { @POST @Path("/{entitySetName}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) - @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM}) public Response postNewEntity( @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, @@ -291,7 +291,6 @@ public abstract class AbstractServices { // default AbstractUtilities utils = xml; - try { final Accept acceptType = Accept.parse(accept, getVersion()); @@ -300,11 +299,18 @@ public abstract class AbstractServices { } utils = getUtilities(acceptType); - final InputStream res = utils.addOrReplaceEntity(entitySetName, IOUtils.toInputStream(entity)); + + final InputStream res; + + if (utils.isMediaContent(entitySetName)) { + res = utils.addMediaEntity(entitySetName, IOUtils.toInputStream(entity)); + } else { + res = utils.addOrReplaceEntity(entitySetName, IOUtils.toInputStream(entity)); + } final Response response; if ("return-no-content".equalsIgnoreCase(prefer)) { - res.close(); + IOUtils.closeQuietly(res); response = utils.createResponse(null, null, acceptType, Response.Status.NO_CONTENT); } else { response = utils.createResponse(res, null, acceptType, Response.Status.CREATED); @@ -498,6 +504,28 @@ public abstract class AbstractServices { } } + @GET + @Path("/{entitySetName}({entityId})/$value") + public Response getMediaEntity( + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId) { + + try { + if (!accept.contains("*/*") && !accept.contains("application/octet-stream")) { + throw new UnsupportedMediaTypeException("Unsupported media type"); + } + + final AbstractUtilities utils = getUtilities(null); + final Map.Entry entityInfo = utils.readMediaEntity(entitySetName, entityId); + return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), getVersion()), null); + + } catch (Exception e) { + LOG.error("Error retrieving entity", e); + return xml.createFaultResponse(accept, e); + } + } + @DELETE @Path("/{entitySetName}/{entityId}") public Response removeEntityKeyAsSegment( @@ -689,6 +717,42 @@ public abstract class AbstractServices { return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); } + @PUT + @Produces({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.WILDCARD, MediaType.APPLICATION_OCTET_STREAM}) + @Path("/{entitySetName}({entityId})/$value") + public Response replaceMediaEntity( + @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + String value) { + try { + + final AbstractUtilities utils = getUtilities(null); + + InputStream res = utils.putMediaInMemory(entitySetName, entityId, IOUtils.toInputStream(value)); + + final Response response; + if ("return-content".equalsIgnoreCase(prefer)) { + response = xml.createResponse(res, null, null, Response.Status.OK); + } else { + res.close(); + response = xml.createResponse(null, null, null, Response.Status.NO_CONTENT); + } + + if (StringUtils.isNotBlank(prefer)) { + response.getHeaders().put("Preference-Applied", Collections.singletonList(prefer)); + } + + return response; + + } catch (Exception e) { + LOG.error("Error retrieving entity", e); + return xml.createFaultResponse(Accept.JSON.toString(), e); + } + } + /** * Replace property. * @@ -710,7 +774,43 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, final String changes) { - return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); + if (xml.isMediaContent(entitySetName + "/" + path)) { + return replaceMediaProperty(prefer, entitySetName, entityId, path, format, changes); + } else { + return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false); + } + } + + private Response replaceMediaProperty( + final String prefer, + final String entitySetName, + final String entityId, + final String path, + final String format, + final String value) { + try { + final AbstractUtilities utils = getUtilities(null); + + InputStream res = utils.putMediaInMemory(entitySetName, entityId, path, IOUtils.toInputStream(value)); + + final Response response; + if ("return-content".equalsIgnoreCase(prefer)) { + response = xml.createResponse(res, null, null, Response.Status.OK); + } else { + res.close(); + response = xml.createResponse(null, null, null, Response.Status.NO_CONTENT); + } + + if (StringUtils.isNotBlank(prefer)) { + response.getHeaders().put("Preference-Applied", Collections.singletonList(prefer)); + } + + return response; + + } catch (Exception e) { + LOG.error("Error retrieving entity", e); + return xml.createFaultResponse(Accept.JSON.toString(), e); + } } /** @@ -755,7 +855,6 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { - final String basePath = Commons.getEntityBasePath(entitySetName, entityId); AbstractUtilities utils = null; try { Accept acceptType = null; @@ -766,10 +865,7 @@ public abstract class AbstractServices { } utils = getUtilities(acceptType); - return utils.createResponse( - getPath(acceptType, entitySetName, entityId, path, true), - Commons.getETag(basePath, getVersion()), - acceptType); + return navigateProperty(acceptType, entitySetName, entityId, path, true); } catch (Exception e) { return (utils == null ? xml : utils).createFaultResponse(accept, e); @@ -795,45 +891,69 @@ public abstract class AbstractServices { @PathParam("path") String path, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) { + // default utilities + final AbstractUtilities utils = xml; + try { - Accept acceptType = null; - if (StringUtils.isNotBlank(format)) { - acceptType = Accept.valueOf(format.toUpperCase()); - } else if (StringUtils.isNotBlank(accept)) { - acceptType = Accept.parse(accept, getVersion(), null); - } - - final String basePath = Commons.getEntityBasePath(entitySetName, entityId); - - InputStream stream; - - try { - final LinkInfo linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML); - final Map.Entry> links = xml.extractLinkURIs(linkInfo.getLinks()); - - switch (acceptType) { - case JSON: - case JSON_FULLMETA: - case JSON_NOMETA: - stream = json.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed()); - stream = json.wrapJsonEntities(stream); - break; - default: - stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed()); + if (utils.isMediaContent(entitySetName + "/" + path)) { + return navigateStreamedEntity(entitySetName, entityId, path); + } else { + Accept acceptType = null; + if (StringUtils.isNotBlank(format)) { + acceptType = Accept.valueOf(format.toUpperCase()); + } else if (StringUtils.isNotBlank(accept)) { + acceptType = Accept.parse(accept, getVersion(), null); } - } catch (NotFoundException e) { - // if the given path is not about any link then search for property - LOG.info("Retrieve property {}", path); - stream = getPath(acceptType, entitySetName, entityId, path, false); - } - return xml.createResponse(stream, Commons.getETag(basePath, getVersion()), acceptType); + try { + return navigateEntity(acceptType, entitySetName, entityId, path); + } catch (NotFoundException e) { + // if the given path is not about any link then search for property + return navigateProperty(acceptType, entitySetName, entityId, path, false); + } + } } catch (Exception e) { - return xml.createFaultResponse(accept, e); + return utils.createFaultResponse(accept, e); } } - private InputStream getPath( + private Response navigateStreamedEntity( + String entitySetName, + String entityId, + String path) throws Exception { + + final AbstractUtilities utils = getUtilities(null); + final Map.Entry entityInfo = utils.readMediaEntity(entitySetName, entityId, path); + return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), getVersion()), null); + } + + private Response navigateEntity( + final Accept acceptType, + String entitySetName, + String entityId, + String path) throws Exception { + final String basePath = Commons.getEntityBasePath(entitySetName, entityId); + + final LinkInfo linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML); + final Map.Entry> links = xml.extractLinkURIs(linkInfo.getLinks()); + + InputStream stream; + + switch (acceptType) { + case JSON: + case JSON_FULLMETA: + case JSON_NOMETA: + stream = json.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed()); + stream = json.wrapJsonEntities(stream); + break; + default: + stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed()); + } + + return xml.createResponse(stream, Commons.getETag(basePath, getVersion()), acceptType); + } + + private Response navigateProperty( final Accept acceptType, final String entitySetName, final String entityId, @@ -861,7 +981,7 @@ public abstract class AbstractServices { stream = utils.getProperty(entitySetName, entityId, pathElements, edmType); } - return stream; + return xml.createResponse(stream, Commons.getETag(basePath, getVersion()), acceptType); } /** diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java index b7c5acd00..2d93c6786 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java @@ -64,7 +64,7 @@ public abstract class AbstractUtilities { } public boolean isMediaContent(final String entityName) { - return Commons.mediaContent.contains(entityName); + return Commons.mediaContent.containsKey(entityName); } /** @@ -164,7 +164,7 @@ public abstract class AbstractUtilities { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); IOUtils.copy(is, bos); - is.close(); + IOUtils.closeQuietly(is); // ----------------------------------------- // 0. Retrieve navigation links to be mantained @@ -195,7 +195,7 @@ public abstract class AbstractUtilities { final String entityKey = key == null ? getDefaultEntryKey( entitySetName, new ByteArrayInputStream(bos.toByteArray()), getDefaultFormat()) : key; - final String path = entitySetName + File.separatorChar + Commons.getEntityKey(entityKey) + File.separatorChar; + final String path = Commons.getEntityBasePath(entitySetName, entityKey); // ----------------------------------------- // ----------------------------------------- @@ -268,6 +268,72 @@ public abstract class AbstractUtilities { return fo.getContent().getInputStream(); } + public InputStream addMediaEntity( + final String entitySetName, + final InputStream is) throws Exception { + + // ----------------------------------------- + // 0. Get default entry key and path (N.B. operation will consume/close the stream; use a copy instead) + // ----------------------------------------- + final String entityKey = getDefaultEntryKey(entitySetName, null, getDefaultFormat()); + final String path = Commons.getEntityBasePath(entitySetName, entityKey); + // ----------------------------------------- + + // ----------------------------------------- + // 1. save the media entity value + // ----------------------------------------- + fsManager.putInMemory(is, fsManager.getAbsolutePath(path + MEDIA_CONTENT_FILENAME, null)); + IOUtils.closeQuietly(is); + // ----------------------------------------- + + // ----------------------------------------- + // 2. save entity as atom + // ----------------------------------------- + final String entityURI = Commons.getEntityURI(entitySetName, entityKey); + String entity = "" + + "" + + "" + DEFAULT_SERVICE_URL + entityURI + "" + + "" + + "" + + "" + + "" + + "" + + "" + entityKey + "" + + "" + + "" + + ""; + + fsManager.putInMemory( + IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + ENTITY, Accept.ATOM)); + // ----------------------------------------- + + // ----------------------------------------- + // 3. save entity as json + // ----------------------------------------- + entity = "{" + + "\"odata.metadata\": \"" + DEFAULT_SERVICE_URL + "/$metadata#" + entitySetName + "/@Element\"," + + "\"odata.type\": \"Microsoft.Test.OData.Services.AstoriaDefaultService." + entitySetName + "\"," + + "\"odata.id\": \"" + DEFAULT_SERVICE_URL + entityURI + "\"," + + "\"odata.editLink\": \"" + entityURI + "\"," + + "\"odata.mediaEditLink\": \"" + entityURI + "/$value\"," + + "\"odata.mediaReadLink\": \"" + entityURI + "/$value\"," + + "\"odata.mediaContentType\": \"*/*\"," + + "\"" + Commons.mediaContent.get(entitySetName) + "\": " + entityKey + "," + + "\"Description\": null" + "}"; + + fsManager.putInMemory( + IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + ENTITY, Accept.JSON_FULLMETA)); + // ----------------------------------------- + + return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue(); + } + public void putLinksInMemory( final String basePath, final String entitySetName, @@ -319,20 +385,39 @@ public abstract class AbstractUtilities { if (accept != null) { builder.header("Content-Type", accept.toString()); + } else { + builder.header("Content-Type", "*/*"); } if (status != null) { builder.status(status); } + int contentLength = 0; + if (entity != null) { - if (accept != null && (Accept.JSON == accept || Accept.JSON_NOMETA == accept)) { - builder.entity(Commons.changeFormat(entity, accept)); - } else { - builder.entity(entity); + try { + final InputStream toBeStreamedBack; + + if (accept != null && (Accept.JSON == accept || Accept.JSON_NOMETA == accept)) { + toBeStreamedBack = Commons.changeFormat(entity, accept); + } else { + toBeStreamedBack = entity; + } + + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(toBeStreamedBack, bos); + IOUtils.closeQuietly(toBeStreamedBack); + + contentLength = bos.size(); + builder.entity(new ByteArrayInputStream(bos.toByteArray())); + } catch (IOException ioe) { + LOG.error("Error streaming response entity back", ioe); } } + builder.header("Content-Length", contentLength); + return builder.build(); } @@ -400,10 +485,10 @@ public abstract class AbstractUtilities { } res = keyBuilder.toString(); } catch (Exception e) { - int messageId = sequence.get(entitySetName) + 1; + final int messageId; if (sequence.containsKey(entitySetName)) { - res = "MessageId=" + String.valueOf(messageId) - + ",FromUsername=1"; + messageId = sequence.get(entitySetName) + 1; + res = "MessageId=" + String.valueOf(messageId) + ",FromUsername=1"; } else { throw new Exception(String.format("Unable to retrieve entity key value for %s", entitySetName)); } @@ -474,6 +559,19 @@ public abstract class AbstractUtilities { } } sequence.put(entitySetName, Integer.valueOf(res)); + } else if ("Car".equals(entitySetName)) { + try { + final Map value = + getPropertyValues(entity, Collections.singletonList("VIN")); + res = value.isEmpty() ? null : IOUtils.toString(value.values().iterator().next()); + } catch (Exception e) { + if (sequence.containsKey(entitySetName)) { + res = String.valueOf(sequence.get(entitySetName) + 1); + } else { + throw new Exception(String.format("Unable to retrieve entity key value for %s", entitySetName)); + } + } + sequence.put(entitySetName, Integer.valueOf(res)); } else { throw new Exception(String.format("EntitySet '%s' not found", entitySetName)); } @@ -523,6 +621,32 @@ public abstract class AbstractUtilities { return linkInfo; } + public InputStream putMediaInMemory( + final String entitySetName, final String entityId, final InputStream value) + throws IOException { + return putMediaInMemory(entitySetName, entityId, null, value); + } + + public InputStream putMediaInMemory( + final String entitySetName, final String entityId, final String name, final InputStream value) + throws IOException { + final FileObject fo = fsManager.putInMemory(value, fsManager.getAbsolutePath( + Commons.getEntityBasePath(entitySetName, entityId) + (name == null ? MEDIA_CONTENT_FILENAME : name), null)); + + return fo.getContent().getInputStream(); + } + + public Map.Entry readMediaEntity(final String entitySetName, final String entityId) { + return readMediaEntity(entitySetName, entityId, null); + } + + public Map.Entry readMediaEntity( + final String entitySetName, final String entityId, final String name) { + final String basePath = Commons.getEntityBasePath(entitySetName, entityId); + return new SimpleEntry(basePath, fsManager.readFile(basePath + + (name == null ? MEDIA_CONTENT_FILENAME : name))); + } + public Map.Entry readEntity( final String entitySetName, final String entityId, final Accept accept) { if (accept == Accept.XML || accept == Accept.TEXT) { @@ -661,7 +785,7 @@ public abstract class AbstractUtilities { throws Exception; public abstract Map.Entry> extractLinkURIs(final InputStream is) throws Exception; - + public abstract Map.Entry> extractLinkURIs( final String entitySetName, final String entityId, final String linkName) throws Exception; } \ No newline at end of file diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java index 46e1a1412..233e03d9b 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java @@ -36,11 +36,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; @@ -57,7 +55,7 @@ public abstract class Commons { protected final static Map sequence = new HashMap(); - protected final static Set mediaContent = new HashSet(); + protected final static Map mediaContent = new HashMap(); protected final static Map linkInfo = new EnumMap(ODataVersion.class); @@ -65,12 +63,15 @@ public abstract class Commons { static { sequence.put("Customer", 1000); sequence.put("CustomerInfo", 1000); + sequence.put("Car", 1000); sequence.put("Message", 1000); sequence.put("Order", 1000); sequence.put("ComputerDetail", 1000); sequence.put("AllGeoTypesSet", 1000); - mediaContent.add("CustomerInfo"); + mediaContent.put("CustomerInfo", "CustomerinfoId"); + mediaContent.put("Car", "VIN"); + mediaContent.put("Car/Photo", null); } public static String getEntityURI(final String entitySetName, final String entityKey) { diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java index 59fdc3519..72309c226 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java @@ -72,6 +72,8 @@ public class Constants { public final static String ENTITY = "entity"; + public final static String MEDIA_CONTENT_FILENAME = "$value.bin"; + public final static String SKIP_TOKEN = "skiptoken"; public final static String FILTER = "filter"; diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java index 396d14b5f..d368da985 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java @@ -70,6 +70,7 @@ public class FSManager { } public FileObject putInMemory(final InputStream is, final String path) throws IOException { + System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA scrivo "+path); final FileObject memObject = fsManager.resolveFile(MEM_PREFIX + path); if (memObject.exists()) { @@ -84,10 +85,17 @@ public class FSManager { IOUtils.copy(is, os); IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); + + System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA inserito valore "+ + IOUtils.toString(memObject.getContent().getInputStream())); return memObject; } + public InputStream readFile(final String relativePath) { + return readFile(relativePath, null); + } + public InputStream readFile(final String relativePath, final Accept accept) { final String path = getAbsolutePath(relativePath, accept); LOG.info("Read {}", path); diff --git a/fit/src/main/resources/v3/Car/12/$value.bin b/fit/src/main/resources/v3/Car/12/$value.bin new file mode 100644 index 000000000..e69de29bb diff --git a/fit/src/main/resources/v3/Car/12/entity.full.json b/fit/src/main/resources/v3/Car/12/entity.full.json new file mode 100644 index 000000000..6b5a05026 --- /dev/null +++ b/fit/src/main/resources/v3/Car/12/entity.full.json @@ -0,0 +1,13 @@ +{ + "odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/$metadata#Car/@Element", + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.Car", + "odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Car(12)", + "odata.editLink": "Car(12)", + "odata.mediaEditLink": "Car(12)/$value", + "odata.mediaReadLink": "Car(12)/$value", + "odata.mediaContentType": "*/*", + "Photo@odata.mediaEditLink": "Car(12)/Photo", + "Video@odata.mediaEditLink": "Car(12)/Video", + "VIN": 12, + "Description": "lx" +} \ No newline at end of file diff --git a/fit/src/main/resources/v3/Car/12/entity.xml b/fit/src/main/resources/v3/Car/12/entity.xml new file mode 100644 index 000000000..057f42bd7 --- /dev/null +++ b/fit/src/main/resources/v3/Car/12/entity.xml @@ -0,0 +1,39 @@ + + + + http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Car(12) + + + + <updated>2014-03-19T09:53:35Z</updated> + <author> + <name /> + </author> + <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/edit-media/Photo" title="Photo" href="Car(12)/Photo" /> + <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/edit-media/Video" title="Video" href="Car(12)/Video" /> + <link rel="edit-media" title="Car" href="Car(12)/$value" /> + <content type="*/*" src="Car(12)/$value" /> + <m:properties> + <d:VIN m:type="Edm.Int32">12</d:VIN> + <d:Description>lx</d:Description> + </m:properties> +</entry> \ No newline at end of file diff --git a/fit/src/main/resources/v3/Car/14/$value.bin b/fit/src/main/resources/v3/Car/14/$value.bin new file mode 100644 index 000000000..e69de29bb diff --git a/fit/src/main/resources/v3/Car/15/$value.bin b/fit/src/main/resources/v3/Car/15/$value.bin new file mode 100644 index 000000000..e69de29bb diff --git a/fit/src/main/resources/v3/Car/15/entity.full.json b/fit/src/main/resources/v3/Car/15/entity.full.json new file mode 100644 index 000000000..5b5b8c491 --- /dev/null +++ b/fit/src/main/resources/v3/Car/15/entity.full.json @@ -0,0 +1,13 @@ +{ + "odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/$metadata#Car/@Element", + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.Car", + "odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Car(15)", + "odata.editLink": "Car(15)", + "odata.mediaEditLink": "Car(15)/$value", + "odata.mediaReadLink": "Car(15)/$value", + "odata.mediaContentType": "*/*", + "Photo@odata.mediaEditLink": "Car(15)/Photo", + "Video@odata.mediaEditLink": "Car(15)/Video", + "VIN": 15, + "Description": "kphszztczthjacvjnttrarxru" +} \ No newline at end of file diff --git a/fit/src/main/resources/v3/Car/15/entity.xml b/fit/src/main/resources/v3/Car/15/entity.xml new file mode 100644 index 000000000..01ac09cac --- /dev/null +++ b/fit/src/main/resources/v3/Car/15/entity.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + 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. + +--> +<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml"> + <id>http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Car(15)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Car" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="Car" href="Car(15)" /> + <title /> + <updated>2014-03-19T11:23:02Z</updated> + <author> + <name /> + </author> + <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/edit-media/Photo" title="Photo" href="Car(15)/Photo" /> + <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/edit-media/Video" title="Video" href="Car(15)/Video" /> + <link rel="edit-media" title="Car" href="Car(15)/$value" /> + <content type="*/*" src="Car(15)/$value" /> + <m:properties> + <d:VIN m:type="Edm.Int32">15</d:VIN> + <d:Description>kphszztczthjacvjnttrarxru</d:Description> + </m:properties> +</entry> \ No newline at end of file diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java index 3d42632f5..d74ce63a4 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java @@ -68,7 +68,8 @@ public class ODataStreamUpdateRequestImpl return (StreamUpdateStreamManager) streamManager; } - public class StreamUpdateStreamManagerImpl extends AbstractODataStreamManager<ODataStreamUpdateResponse> { + public class StreamUpdateStreamManagerImpl extends AbstractODataStreamManager<ODataStreamUpdateResponse> + implements StreamUpdateStreamManager { /** * Private constructor. diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/MediaEntityTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/MediaEntityTestITCase.java index 004378c25..6f0401f28 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/MediaEntityTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/MediaEntityTestITCase.java @@ -40,15 +40,12 @@ import org.apache.olingo.client.api.domain.ODataEntity; import org.apache.olingo.client.api.domain.ODataProperty; import org.apache.olingo.client.api.format.ODataMediaFormat; import org.apache.olingo.client.api.format.ODataPubFormat; -import org.apache.olingo.client.api.http.HttpClientException; import org.apache.olingo.client.api.uri.URIBuilder; -import org.junit.Ignore; import org.junit.Test; public class MediaEntityTestITCase extends AbstractV3TestITCase { @Test - @Ignore public void read() throws Exception { final URIBuilder<?> builder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Car").appendKeySegment(12).appendValueSegment(); @@ -64,7 +61,6 @@ public class MediaEntityTestITCase extends AbstractV3TestITCase { } @Test(expected = ODataClientErrorException.class) - @Ignore public void readWithXmlError() throws Exception { final URIBuilder<?> builder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Car").appendKeySegment(12).appendValueSegment(); @@ -76,7 +72,6 @@ public class MediaEntityTestITCase extends AbstractV3TestITCase { } @Test(expected = ODataClientErrorException.class) - @Ignore public void readWithJsonError() throws Exception { final URIBuilder<?> builder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Car").appendKeySegment(12).appendValueSegment(); @@ -88,57 +83,31 @@ public class MediaEntityTestITCase extends AbstractV3TestITCase { } @Test - @Ignore public void updateMediaEntityAsAtom() throws Exception { updateMediaEntity(ODataPubFormat.ATOM, 14); } @Test - @Ignore public void updateMediaEntityAsJson() throws Exception { updateMediaEntity(ODataPubFormat.JSON, 15); } @Test - @Ignore public void createMediaEntityAsAtom() throws Exception { createMediaEntity(ODataPubFormat.ATOM, IOUtils.toInputStream("buffered stream sample")); } @Test - @Ignore public void createMediaEntityAsJson() throws Exception { createMediaEntity(ODataPubFormat.JSON, IOUtils.toInputStream("buffered stream sample")); } @Test - @Ignore public void issue137() throws Exception { createMediaEntity(ODataPubFormat.JSON, this.getClass().getResourceAsStream("/sample.png")); } @Test - @Ignore - public void issue136() throws Exception { - byte[] input = new byte[65000]; - for (int i = 0; i < 65000; i++) { - input[i] = (byte) i; - } - createMediaEntity(ODataPubFormat.ATOM, new ByteArrayInputStream(input)); - } - - @Test(expected = HttpClientException.class) - @Ignore - public void issue136FailsWithException() throws Exception { - byte[] input = new byte[68000]; - for (int i = 0; i < 68000; i++) { - input[i] = (byte) i; - } - createMediaEntity(ODataPubFormat.ATOM, new ByteArrayInputStream(input)); - } - - @Test - @Ignore public void updateNamedStream() throws Exception { URIBuilder<?> builder = client.getURIBuilder(testStaticServiceRootURL). appendEntitySetSegment("Car").appendKeySegment(16).appendNavigationSegment("Photo"); @@ -176,9 +145,6 @@ public class MediaEntityTestITCase extends AbstractV3TestITCase { final ODataMediaEntityUpdateResponse updateRes = streamManager.getResponse(); assertEquals(204, updateRes.getStatusCode()); - builder = client.getURIBuilder(testStaticServiceRootURL). - appendEntitySetSegment("Car").appendKeySegment(id).appendValueSegment(); - final ODataMediaRequest retrieveReq = client.getRetrieveRequestFactory().getMediaRequest(builder.build()); final ODataRetrieveResponse<InputStream> retrieveRes = retrieveReq.execute(); diff --git a/lib/client-core/src/test/resources/sample.png b/lib/client-core/src/test/resources/sample.png new file mode 100644 index 000000000..399ee46a2 Binary files /dev/null and b/lib/client-core/src/test/resources/sample.png differ diff --git a/pom.xml b/pom.xml index 285513718..e74a19bc6 100644 --- a/pom.xml +++ b/pom.xml @@ -369,6 +369,7 @@ <exclude>**/META-INF/services/*</exclude> <exclude>**/*.txt</exclude> <exclude>**/*.ini</exclude> + <exclude>**/*.bin</exclude> <exclude>**/MANIFEST.MF</exclude> <exclude>.gitignore</exclude> <exclude>.git/**</exclude>