[OLINGO-175] providing (V3) Media entity CRUD

This commit is contained in:
fmartelli 2014-03-19 16:11:38 +01:00
parent 8f3541c2da
commit 87b5e7db66
17 changed files with 423 additions and 94 deletions

View File

@ -57,7 +57,7 @@ public abstract class Commons {
protected final static Map<String, Integer> sequence = new HashMap<String, Integer>();
protected final static Set<String> mediaContent = new HashSet<String>();
public final static Set<String> mediaContent = new HashSet<String>();
protected final static Map<ODataVersion, MetadataLinkInfo> linkInfo =
new EnumMap<ODataVersion, MetadataLinkInfo>(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) {

View File

@ -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<String, InputStream> 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.<Object>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.<Object>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<String, List<String>> 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<String, InputStream> 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<String, List<String>> 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);
}
/**

View File

@ -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 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<entry xml:base=\"" + DEFAULT_SERVICE_URL + "\" "
+ "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>" + DEFAULT_SERVICE_URL + entityURI + "</id>"
+ "<category term=\"Microsoft.Test.OData.Services.AstoriaDefaultService." + entitySetName + "\" "
+ "scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />"
+ "<link rel=\"edit\" title=\"Car\" href=\"" + entityURI + "\" />"
+ "<link rel=\"edit-media\" title=\"Car\" href=\"" + entityURI + "/$value\" />"
+ "<content type=\"*/*\" src=\"" + entityURI + "/$value\" />"
+ "<m:properties>"
+ "<d:" + Commons.mediaContent.get(entitySetName) + " m:type=\"Edm.Int32\">" + entityKey + "</d:VIN>"
+ "<d:Description m:null=\"true\" />"
+ "</m:properties>"
+ "</entry>";
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<String, InputStream> value =
getPropertyValues(entity, Collections.<String>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<String, InputStream> readMediaEntity(final String entitySetName, final String entityId) {
return readMediaEntity(entitySetName, entityId, null);
}
public Map.Entry<String, InputStream> readMediaEntity(
final String entitySetName, final String entityId, final String name) {
final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
return new SimpleEntry<String, InputStream>(basePath, fsManager.readFile(basePath
+ (name == null ? MEDIA_CONTENT_FILENAME : name)));
}
public Map.Entry<String, InputStream> 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<String, List<String>> extractLinkURIs(final InputStream is) throws Exception;
public abstract Map.Entry<String, List<String>> extractLinkURIs(
final String entitySetName, final String entityId, final String linkName) throws Exception;
}

View File

@ -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<String, Integer> sequence = new HashMap<String, Integer>();
protected final static Set<String> mediaContent = new HashSet<String>();
protected final static Map<String, String> mediaContent = new HashMap<String, String>();
protected final static Map<ODataVersion, MetadataLinkInfo> linkInfo =
new EnumMap<ODataVersion, MetadataLinkInfo>(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) {

View File

@ -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";

View File

@ -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);

View File

@ -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"
}

View File

@ -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(12)</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(12)" />
<title />
<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>

View File

@ -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"
}

View File

@ -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>

View File

@ -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.

View File

@ -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();

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -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>