blob: c51c6dec5e284c046111777adb02f5b38f4b51b0 [file] [log] [blame]
/*******************************************************************************
* 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.odata2.core.ep;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.olingo.odata2.api.commons.HttpContentType;
import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
import org.apache.olingo.odata2.api.ep.entry.DeletedEntryMetadata;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
import org.apache.olingo.odata2.api.processor.ODataErrorContext;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.core.commons.ContentType;
import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
import org.apache.olingo.odata2.core.ep.consumer.AbstractConsumerTest;
import org.apache.olingo.odata2.testutil.helper.StringHelper;
import org.apache.olingo.odata2.testutil.mock.MockFacade;
import org.junit.Test;
import junit.framework.Assert;
/**
*
*/
public class ProviderFacadeImplTest extends AbstractConsumerTest {
private static final String EMPLOYEE_1_XML =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<entry xmlns=\"" + Edm.NAMESPACE_ATOM_2005 + "\"" +
" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\"" +
" xmlns:d=\"" + Edm.NAMESPACE_D_2007_08 + "\"" +
" xml:base=\"https://some.host.com/some.service.root.segment/ReferenceScenario.svc/\">" +
"<id>https://some.host.com/some.service.root.segment/ReferenceScenario.svc/Employees('1')</id>" +
"<title type=\"text\">Walter Winter</title>" +
"<updated>1999-01-01T00:00:00Z</updated>" +
"<category term=\"RefScenario.Employee\" scheme=\"" + Edm.NAMESPACE_SCHEME_2007_08 + "\"/>" +
"<link href=\"Employees('1')\" rel=\"edit\" title=\"Employee\"/>" +
"<link href=\"Employees('1')/$value\" rel=\"edit-media\" type=\"application/octet-stream\"/>" +
"<link href=\"Employees('1')/ne_Room\" rel=\"" + Edm.NAMESPACE_REL_2007_08
+ "ne_Room\" type=\"application/atom+xml; type=entry\" title=\"ne_Room\"/>" +
"<link href=\"Employees('1')/ne_Manager\" rel=\"" + Edm.NAMESPACE_REL_2007_08
+ "ne_Manager\" type=\"application/atom+xml; type=entry\" title=\"ne_Manager\"/>" +
"<link href=\"Employees('1')/ne_Team\" rel=\"" + Edm.NAMESPACE_REL_2007_08
+ "ne_Team\" type=\"application/atom+xml; type=entry\" title=\"ne_Team\"/>" +
"<content type=\"application/octet-stream\" src=\"Employees('1')/$value\"/>" +
"<m:properties>" +
"<d:EmployeeId>1</d:EmployeeId>" +
"<d:EmployeeName>Walter Winter</d:EmployeeName>" +
"<d:ManagerId>1</d:ManagerId>" +
"<d:RoomId>1</d:RoomId>" +
"<d:TeamId>1</d:TeamId>" +
"<d:Location m:type=\"RefScenario.c_Location\">" +
"<d:Country>Germany</d:Country>" +
"<d:City m:type=\"RefScenario.c_City\">" +
"<d:PostalCode>69124</d:PostalCode>" +
"<d:CityName>Heidelberg</d:CityName>" +
"</d:City>" +
"</d:Location>" +
"<d:Age>52</d:Age>" +
"<d:EntryDate>1999-01-01T00:00:00</d:EntryDate>" +
"<d:ImageUrl>Employee_1.png</d:ImageUrl>" +
"</m:properties>" +
"</entry>";
@Test
public void readDeltaFeed() throws Exception {
final String contentType = ContentType.APPLICATION_ATOM_XML_FEED.toContentTypeString();
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
InputStream content = getFileAsStream("feed_with_deleted_entries.xml");
EntityProviderReadProperties properties = EntityProviderReadProperties.init().build();
ODataDeltaFeed deltaFeed = new ProviderFacadeImpl().readDeltaFeed(contentType, entitySet, content, properties);
assertNotNull(deltaFeed);
assertNotNull(deltaFeed.getEntries());
assertNotNull(deltaFeed.getFeedMetadata());
assertEquals(1, deltaFeed.getEntries().size());
assertEquals(1, deltaFeed.getDeletedEntries().size());
assertEquals("http://host:123/odata/Rooms?$skiptoken=97", deltaFeed.getFeedMetadata().getDeltaLink());
assertEquals("http://host:123/odata/Rooms('2')", deltaFeed.getDeletedEntries().get(0).getUri());
Date when =
EdmDateTimeOffset.getInstance().valueOfString("2014-01-14T18:11:06.682+01:00", EdmLiteralKind.DEFAULT, null,
Date.class);
assertEquals(when, deltaFeed.getDeletedEntries().get(0).getWhen());
}
@Test
public void readFeed() throws Exception {
final String contentType = ContentType.APPLICATION_ATOM_XML_FEED.toContentTypeString();
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
InputStream content = getFileAsStream("feed_employees.xml");
EntityProviderReadProperties properties = EntityProviderReadProperties.init().build();
ODataFeed feed = new ProviderFacadeImpl().readFeed(contentType, entitySet, content, properties);
assertNotNull(feed);
assertNotNull(feed.getEntries());
assertNotNull(feed.getFeedMetadata());
assertEquals(6, feed.getEntries().size());
}
@Test
public void readEntry() throws Exception {
final String contentType = ContentType.APPLICATION_ATOM_XML_ENTRY.toContentTypeString();
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
InputStream content = new ByteArrayInputStream(EMPLOYEE_1_XML.getBytes("UTF-8"));
final ODataEntry result =
new ProviderFacadeImpl().readEntry(contentType, entitySet, content, EntityProviderReadProperties.init()
.mergeSemantic(true).build());
assertNotNull(result);
assertFalse(result.containsInlineEntry());
assertNotNull(result.getExpandSelectTree());
assertTrue(result.getExpandSelectTree().isAll());
assertNotNull(result.getMetadata());
assertNull(result.getMetadata().getEtag());
assertNotNull(result.getMediaMetadata());
assertEquals(HttpContentType.APPLICATION_OCTET_STREAM, result.getMediaMetadata().getContentType());
assertNotNull(result.getProperties());
assertEquals(52, result.getProperties().get("Age"));
}
@Test
public void readDeltaFeedJson() throws Exception {
final String contentType = ContentType.APPLICATION_JSON.toContentTypeString();
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
InputStream content = getFileAsStream("JsonWithDeletedEntries.json");
EntityProviderReadProperties properties = EntityProviderReadProperties.init().build();
ODataDeltaFeed deltaFeed = new ProviderFacadeImpl().readDeltaFeed(contentType, entitySet, content, properties);
assertNotNull(deltaFeed);
assertNotNull(deltaFeed.getEntries());
assertNotNull(deltaFeed.getFeedMetadata());
assertEquals(1, deltaFeed.getEntries().size());
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms?!deltatoken=4711",
deltaFeed.getFeedMetadata().getDeltaLink());
assertEquals(2, deltaFeed.getDeletedEntries().size());
List<DeletedEntryMetadata> deletedEntries = deltaFeed.getDeletedEntries();
assertEquals(2, deletedEntries.size());
for (DeletedEntryMetadata deletedEntry : deletedEntries) {
String uri = deletedEntry.getUri();
if (uri.contains("Rooms('4')")) {
assertEquals("http://host:80/service/Rooms('4')", deletedEntry.getUri());
assertEquals(new Date(3509636760000l), deletedEntry.getWhen());
} else if (uri.contains("Rooms('3')")) {
assertEquals("http://host:80/service/Rooms('3')", deletedEntry.getUri());
assertEquals(new Date(1300561560000l), deletedEntry.getWhen());
} else {
Assert.fail("Found unknown DeletedEntry with value: " + deletedEntry);
}
}
}
@Test
public void readPropertyValue() throws Exception {
final EdmProperty property =
(EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
InputStream content = new ByteArrayInputStream("2012-02-29T01:02:03".getBytes("UTF-8"));
final Object result = new ProviderFacadeImpl().readPropertyValue(property, content, Long.class);
assertEquals(1330477323000L, result);
}
@Test
public void readProperty() throws Exception {
final EdmProperty property =
(EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
final String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">42</Age>";
InputStream content = new ByteArrayInputStream(xml.getBytes("UTF-8"));
final Map<String, Object> result =
new ProviderFacadeImpl().readProperty(HttpContentType.APPLICATION_XML, property, content,
EntityProviderReadProperties.init().build());
assertFalse(result.isEmpty());
assertEquals(42, result.get("Age"));
}
@Test
public void readFunctionImport() throws Exception {
final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer()
.getFunctionImport("MaximalAge");
InputStream content = new ByteArrayInputStream("{\"d\":{\"MaximalAge\":42}}".getBytes("UTF-8"));
final Object result = new ProviderFacadeImpl().readFunctionImport(HttpContentType.APPLICATION_JSON,
functionImport, content, EntityProviderReadProperties.init().build());
assertEquals((short) 42, result);
}
@Test
public void readMultipleEntityFunctionImport() throws Exception {
final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer()
.getFunctionImport("EmployeeSearch");
InputStream content = new ByteArrayInputStream(
("{\"d\": {"
+ "\"results\": [{"
+ "\"__metadata\": {"
+ "\"type\": \"RefScenario.Employee\","
+ "\"content_type\": \"image/jpeg\","
+ "\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\","
+ "\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\""
+ "},"
+ "\"EmployeeId\": \"3\","
+ "\"EmployeeName\": \"Jonathan Smith\","
+ "\"ManagerId\": \"1\","
+ "\"RoomId\": \"2\","
+ "\"TeamId\": \"1\","
+ "\"Location\": {"
+ "\"__metadata\": {"
+ "\"type\": \"RefScenario.c_Location\""
+ "},"
+ "\"City\": {"
+ "\"__metadata\": {"
+ "\"type\": \"RefScenario.c_City\""
+ "},"
+ "\"PostalCode\": \"69190\","
+ "\"CityName\": \"Walldorf\""
+ "},"
+ "\"Country\": \"Germany\""
+ "},"
+ "\"Age\": 56,"
+ "\"EntryDate\": null,"
+ "\"ImageUrl\": \"Employees('3')/$value\","
+ "\"ne_Manager\": {"
+ "\"__deferred\": {"
+ "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\""
+ "}"
+ "},"
+ "\"ne_Team\": {"
+ "\"__deferred\": {"
+ "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\""
+ "}"
+ "},"
+ "\"ne_Room\": {"
+ "\"__deferred\": {"
+ "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\""
+ "}"
+ "}"
+ "}]"
+ "}"
+ "}").getBytes("UTF-8"));
final Object result = new ProviderFacadeImpl().readFunctionImport(HttpContentType.APPLICATION_JSON,
functionImport, content, EntityProviderReadProperties.init().build());
ODataDeltaFeed feed = (ODataDeltaFeed) result;
List<ODataEntry> entries = feed.getEntries();
int size = entries.size();
assertEquals(1, size);
String id = (String) entries.get(0).getProperties().get("EmployeeId");
assertEquals("3", id);
}
@Test
public void readLink() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
InputStream content = new ByteArrayInputStream("{\"d\":{\"uri\":\"http://somelink\"}}".getBytes("UTF-8"));
final String result = new ProviderFacadeImpl().readLink(HttpContentType.APPLICATION_JSON, entitySet, content);
assertEquals("http://somelink", result);
}
@Test
public void readLinks() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
InputStream content =
new ByteArrayInputStream("{\"d\":{\"__count\":\"42\",\"results\":[{\"uri\":\"http://somelink\"}]}}"
.getBytes("UTF-8"));
final List<String> result =
new ProviderFacadeImpl().readLinks(HttpContentType.APPLICATION_JSON, entitySet, content);
assertEquals(Arrays.asList("http://somelink"), result);
}
@Test
public void readErrorDocumentJson() throws EntityProviderException {
ProviderFacadeImpl providerFacade = new ProviderFacadeImpl();
String errorDoc = "{\"error\":{\"code\":\"ErrorCode\",\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}";
ODataErrorContext errorContext = providerFacade.readErrorDocument(StringHelper.encapsulate(errorDoc),
ContentType.APPLICATION_JSON.toContentTypeString());
//
assertEquals("Wrong content type", "application/json", errorContext.getContentType());
assertEquals("Wrong message", "Message", errorContext.getMessage());
assertEquals("Wrong error code", "ErrorCode", errorContext.getErrorCode());
assertEquals("Wrong locale for lang", Locale.US, errorContext.getLocale());
}
@Test
public void readErrorDocumentXml() throws EntityProviderException {
ProviderFacadeImpl providerFacade = new ProviderFacadeImpl();
String errorDoc =
"<?xml version='1.0' encoding='UTF-8'?>\n" +
"<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" +
"\t<code>ErrorCode</code>\n" +
"\t<message xml:lang=\"en-US\">Message</message>\n" +
"</error>";
ODataErrorContext errorContext = providerFacade.readErrorDocument(StringHelper.encapsulate(errorDoc),
ContentType.APPLICATION_XML.toContentTypeString());
//
assertEquals("Wrong content type", "application/xml", errorContext.getContentType());
assertEquals("Wrong message", "Message", errorContext.getMessage());
assertEquals("Wrong error code", "ErrorCode", errorContext.getErrorCode());
assertEquals("Wrong locale for lang", Locale.US, errorContext.getLocale());
}
@Test
public void writeFeed() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
List<Map<String, Object>> propertiesList = new ArrayList<Map<String, Object>>();
final ODataResponse result =
new ProviderFacadeImpl().writeFeed(HttpContentType.APPLICATION_JSON, entitySet, propertiesList,
EntityProviderWriteProperties.serviceRoot(URI.create("http://root/")).build());
assertEquals("{\"d\":{\"results\":[]}}", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeEntry() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("Id", "42");
final ODataResponse result =
new ProviderFacadeImpl().writeEntry(HttpContentType.APPLICATION_JSON, entitySet, properties,
EntityProviderWriteProperties.serviceRoot(URI.create("http://root/")).build());
assertEquals("{\"d\":{\"__metadata\":{\"id\":\"http://root/Teams('42')\","
+ "\"uri\":\"http://root/Teams('42')\",\"type\":\"RefScenario.Team\"},"
+ "\"Id\":\"42\",\"Name\":null,\"isScrumTeam\":null,"
+ "\"nt_Employees\":{\"__deferred\":{\"uri\":\"http://root/Teams('42')/nt_Employees\"}}}}",
StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeProperty() throws Exception {
final EdmProperty property =
(EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
final ODataResponse result =
new ProviderFacadeImpl().writeProperty(HttpContentType.APPLICATION_XML, property, 987654321000L);
assertNull("EntityProvider should not set content header", result.getContentHeader());
assertTrue(StringHelper.inputStreamToString((InputStream) result.getEntity())
.endsWith("\">2001-04-19T04:25:21</EntryDate>"));
}
@Test
public void writeLink() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("Id", "42");
final ODataResponse result =
new ProviderFacadeImpl().writeLink(HttpContentType.APPLICATION_JSON, entitySet, properties,
EntityProviderWriteProperties.serviceRoot(URI.create("http://root/")).build());
assertEquals("{\"d\":{\"uri\":\"http://root/Rooms('42')\"}}",
StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeLinks() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("Id", "42");
List<Map<String, Object>> propertiesList = new ArrayList<Map<String, Object>>();
propertiesList.add(properties);
propertiesList.add(properties);
final ODataResponse result =
new ProviderFacadeImpl().writeLinks(HttpContentType.APPLICATION_JSON, entitySet, propertiesList,
EntityProviderWriteProperties.serviceRoot(URI.create("http://root/")).build());
assertEquals("{\"d\":[{\"uri\":\"http://root/Rooms('42')\"},{\"uri\":\"http://root/Rooms('42')\"}]}",
StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeServiceDocument() throws Exception {
final ODataResponse result =
new ProviderFacadeImpl()
.writeServiceDocument(HttpContentType.APPLICATION_JSON, MockFacade.getMockEdm(), "root");
assertEquals("{\"d\":{\"EntitySets\":[]}}", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writePropertyValue() throws Exception {
final EdmProperty property =
(EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
final ODataResponse result = new ProviderFacadeImpl().writePropertyValue(property, 987654321000L);
assertNull("BasicProvider should not set content header", result.getContentHeader());
assertEquals("2001-04-19T04:25:21", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeText() throws Exception {
final ODataResponse result = new ProviderFacadeImpl().writeText("test");
assertNull("BasicProvider should not set content header", result.getContentHeader());
assertEquals("test", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeBinary() throws Exception {
final ODataResponse result =
new ProviderFacadeImpl().writeBinary(HttpContentType.APPLICATION_OCTET_STREAM, new byte[] { 102, 111, 111 });
assertEquals(HttpContentType.APPLICATION_OCTET_STREAM, result.getContentHeader());
assertEquals("foo", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
@Test
public void writeBinaryNoContent() throws Exception {
final ODataResponse result = new ProviderFacadeImpl().writeBinary(HttpContentType.APPLICATION_OCTET_STREAM, null);
assertNull(result.getEntity());
assertNull(result.getContentHeader());
assertEquals(HttpStatusCodes.NO_CONTENT, result.getStatus());
}
@Test
public void writeFunctionImport() throws Exception {
final EdmFunctionImport function =
MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("MaximalAge");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("MaximalAge", 99);
final ODataResponse result =
new ProviderFacadeImpl().writeFunctionImport(HttpContentType.APPLICATION_JSON, function, properties, null);
assertEquals("{\"d\":{\"MaximalAge\":99}}", StringHelper.inputStreamToString((InputStream) result.getEntity()));
}
}