[OLINGO-366,OLINGO-367,OLINGO-370] merge
This commit is contained in:
commit
cdc98eacd8
ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy
api
commons
fit/src
main/java/org/apache/olingo/fit
test/java/org/apache/olingo/fit
lib
client-api/src/main/java/org/apache/olingo/client/api
Configuration.java
communication
client-core/src/main/java/org/apache/olingo/client/core
ConfigurationImpl.java
communication
commons-api/src/main/java/org/apache/olingo/commons/api
server-api/src/test/java/org/apache/olingo/server/api
server-core/src/main/java/org/apache/olingo/server/core/serializer/json
server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data
server-test/src/test/java/org/apache/olingo/server/core/serializer/json
|
@ -19,6 +19,8 @@
|
||||||
package org.apache.olingo.ext.proxy.api;
|
package org.apache.olingo.ext.proxy.api;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for container operations.
|
* Interface for container operations.
|
||||||
|
@ -27,6 +29,9 @@ public interface PersistenceManager extends Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes all pending changes to the OData service.
|
* Flushes all pending changes to the OData service.
|
||||||
|
*
|
||||||
|
* @return a list where n-th item is either null (if corresponding request went out successfully) or the exception
|
||||||
|
* bearing the error returned from the service.
|
||||||
*/
|
*/
|
||||||
void flush();
|
List<ODataRuntimeException> flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateR
|
||||||
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
|
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
|
import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
|
||||||
import org.apache.olingo.client.core.uri.URIUtils;
|
import org.apache.olingo.client.core.uri.URIUtils;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||||
import org.apache.olingo.commons.api.domain.ODataLink;
|
import org.apache.olingo.commons.api.domain.ODataLink;
|
||||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||||
|
@ -67,10 +68,10 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
||||||
this.service = factory;
|
this.service = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void doFlush(final PersistenceChanges changes, final TransactionItems items);
|
protected abstract List<ODataRuntimeException> doFlush(PersistenceChanges changes, TransactionItems items);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public List<ODataRuntimeException> flush() {
|
||||||
final PersistenceChanges changes = new PersistenceChanges();
|
final PersistenceChanges changes = new PersistenceChanges();
|
||||||
final TransactionItems items = new TransactionItems();
|
final TransactionItems items = new TransactionItems();
|
||||||
|
|
||||||
|
@ -89,9 +90,10 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
|
||||||
|
|
||||||
processDelayedUpdates(delayedUpdates, pos, items, changes);
|
processDelayedUpdates(delayedUpdates, pos, items, changes);
|
||||||
|
|
||||||
doFlush(changes, items);
|
final List<ODataRuntimeException> result = doFlush(changes, items);
|
||||||
|
|
||||||
service.getContext().detachAll();
|
service.getContext().detachAll();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ODataLink buildNavigationLink(final String name, final URI uri, final ODataLinkType type) {
|
private ODataLink buildNavigationLink(final String name, final URI uri, final ODataLinkType type) {
|
||||||
|
|
|
@ -23,8 +23,6 @@ import org.apache.olingo.ext.proxy.Service;
|
||||||
import org.apache.olingo.ext.proxy.api.annotations.EntityContainer;
|
import org.apache.olingo.ext.proxy.api.annotations.EntityContainer;
|
||||||
import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
|
import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
|
||||||
import org.apache.olingo.ext.proxy.api.annotations.Singleton;
|
import org.apache.olingo.ext.proxy.api.annotations.Singleton;
|
||||||
import org.apache.olingo.ext.proxy.utils.ClassUtils;
|
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
@ -80,8 +78,7 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
|
||||||
if (isSelfMethod(method, args)) {
|
if (isSelfMethod(method, args)) {
|
||||||
return invokeSelfMethod(method, args);
|
return invokeSelfMethod(method, args);
|
||||||
} else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
|
} else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
|
||||||
service.getPersistenceManager().flush();
|
return service.getPersistenceManager().flush();
|
||||||
return ClassUtils.returnVoid();
|
|
||||||
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
|
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
|
||||||
final Class<?> returnType = method.getReturnType();
|
final Class<?> returnType = method.getReturnType();
|
||||||
|
|
||||||
|
|
|
@ -19,22 +19,23 @@
|
||||||
package org.apache.olingo.ext.proxy.commons;
|
package org.apache.olingo.ext.proxy.commons;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
|
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataRequest;
|
import org.apache.olingo.client.api.communication.request.ODataRequest;
|
||||||
|
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.ext.proxy.Service;
|
import org.apache.olingo.ext.proxy.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.apache.olingo.ext.proxy.api.PersistenceManager} implementation not using OData batch requests: any
|
* {@link org.apache.olingo.ext.proxy.api.PersistenceManager} implementation not using OData batch requests: any
|
||||||
* read-write operation will be sent separately to the OData service when calling <tt>flush()</tt>; any intermediate
|
* read-write operation will be sent separately to the OData service when calling <tt>flush()</tt>.
|
||||||
* error will be logged and ignored.
|
|
||||||
*/
|
*/
|
||||||
public class NonTransactionalPersistenceManagerImpl extends AbstractPersistenceManager {
|
public class NonTransactionalPersistenceManagerImpl extends AbstractPersistenceManager {
|
||||||
|
|
||||||
|
@ -45,7 +46,9 @@ public class NonTransactionalPersistenceManagerImpl extends AbstractPersistenceM
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFlush(final PersistenceChanges changes, final TransactionItems items) {
|
protected List<ODataRuntimeException> doFlush(final PersistenceChanges changes, final TransactionItems items) {
|
||||||
|
final List<ODataRuntimeException> result = new ArrayList<ODataRuntimeException>();
|
||||||
|
|
||||||
final Map<Integer, URI> responses = new HashMap<Integer, URI>();
|
final Map<Integer, URI> responses = new HashMap<Integer, URI>();
|
||||||
int virtualContentID = 0;
|
int virtualContentID = 0;
|
||||||
|
|
||||||
|
@ -82,9 +85,19 @@ public class NonTransactionalPersistenceManagerImpl extends AbstractPersistenceM
|
||||||
} else {
|
} else {
|
||||||
responses.put(virtualContentID, null);
|
responses.put(virtualContentID, null);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
|
result.add(null);
|
||||||
|
} catch (ODataRuntimeException e) {
|
||||||
LOG.error("While performing {}", entry.getKey().getURI(), e);
|
LOG.error("While performing {}", entry.getKey().getURI(), e);
|
||||||
|
|
||||||
|
if (service.getClient().getConfiguration().isContinueOnError()) {
|
||||||
|
result.add(e);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.ext.proxy.commons;
|
package org.apache.olingo.ext.proxy.commons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.http.ProtocolVersion;
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataRequest;
|
import org.apache.olingo.client.api.communication.request.ODataRequest;
|
||||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||||
|
@ -29,12 +35,11 @@ import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||||
|
import org.apache.olingo.client.core.communication.header.ODataErrorResponseChecker;
|
||||||
import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
|
import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.ext.proxy.Service;
|
import org.apache.olingo.ext.proxy.Service;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.apache.olingo.ext.proxy.api.PersistenceManager} implementation using OData batch requests to implement
|
* {@link org.apache.olingo.ext.proxy.api.PersistenceManager} implementation using OData batch requests to implement
|
||||||
* high-level user transactions: all read-write operations will be packed in a batch request to the OData service when
|
* high-level user transactions: all read-write operations will be packed in a batch request to the OData service when
|
||||||
|
@ -52,20 +57,20 @@ public class TransactionalPersistenceManagerImpl extends AbstractPersistenceMana
|
||||||
* Transactional changes commit.
|
* Transactional changes commit.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doFlush(final PersistenceChanges changes, final TransactionItems items) {
|
protected List<ODataRuntimeException> doFlush(final PersistenceChanges changes, final TransactionItems items) {
|
||||||
final CommonODataBatchRequest request =
|
final CommonODataBatchRequest request =
|
||||||
service.getClient().getBatchRequestFactory().getBatchRequest(service.getClient().getServiceRoot());
|
service.getClient().getBatchRequestFactory().getBatchRequest(service.getClient().getServiceRoot());
|
||||||
((ODataRequest) request).setAccept(
|
((ODataRequest) request).setAccept(
|
||||||
service.getClient().getConfiguration().getDefaultBatchAcceptFormat().toContentTypeString());
|
service.getClient().getConfiguration().getDefaultBatchAcceptFormat().toContentTypeString());
|
||||||
|
|
||||||
final BatchManager streamManager = (BatchManager) ((ODataStreamedRequest) request).payloadManager();
|
final BatchManager batchManager = (BatchManager) ((ODataStreamedRequest) request).payloadManager();
|
||||||
|
|
||||||
final ODataChangeset changeset = streamManager.addChangeset();
|
final ODataChangeset changeset = batchManager.addChangeset();
|
||||||
for (Map.Entry<ODataBatchableRequest, EntityInvocationHandler> entry : changes.getChanges().entrySet()) {
|
for (Map.Entry<ODataBatchableRequest, EntityInvocationHandler> entry : changes.getChanges().entrySet()) {
|
||||||
changeset.addRequest(entry.getKey());
|
changeset.addRequest(entry.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
final ODataBatchResponse response = streamManager.getResponse();
|
final ODataBatchResponse response = batchManager.getResponse();
|
||||||
|
|
||||||
// This should be 202 for service version <= 3.0 and 200 for service version >= 4.0 but it seems that
|
// This should be 202 for service version <= 3.0 and 200 for service version >= 4.0 but it seems that
|
||||||
// many service implementations are not fully compliant in this respect.
|
// many service implementations are not fully compliant in this respect.
|
||||||
|
@ -73,24 +78,54 @@ public class TransactionalPersistenceManagerImpl extends AbstractPersistenceMana
|
||||||
throw new IllegalStateException("Operation failed");
|
throw new IllegalStateException("Operation failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<ODataRuntimeException> result = new ArrayList<ODataRuntimeException>();
|
||||||
|
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
final Iterator<ODataBatchResponseItem> batchResItor = response.getBody();
|
||||||
if (!iter.hasNext()) {
|
if (!batchResItor.hasNext()) {
|
||||||
throw new IllegalStateException("Unexpected operation result");
|
throw new IllegalStateException("Unexpected operation result");
|
||||||
}
|
}
|
||||||
|
|
||||||
final ODataBatchResponseItem item = iter.next();
|
final ODataBatchResponseItem item = batchResItor.next();
|
||||||
if (!(item instanceof ODataChangesetResponseItem)) {
|
if (!(item instanceof ODataChangesetResponseItem)) {
|
||||||
throw new IllegalStateException("Unexpected batch response item " + item.getClass().getSimpleName());
|
throw new IllegalStateException("Unexpected batch response item " + item.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
final ODataChangesetResponseItem chgres = (ODataChangesetResponseItem) item;
|
final ODataChangesetResponseItem chgres = (ODataChangesetResponseItem) item;
|
||||||
|
|
||||||
for (Integer changesetItemId : items.sortedValues()) {
|
for (final Iterator<Integer> itor = items.sortedValues().iterator(); itor.hasNext();) {
|
||||||
|
final Integer changesetItemId = itor.next();
|
||||||
LOG.debug("Expected changeset item {}", changesetItemId);
|
LOG.debug("Expected changeset item {}", changesetItemId);
|
||||||
|
|
||||||
final ODataResponse res = chgres.next();
|
final ODataResponse res = chgres.next();
|
||||||
if (res.getStatusCode() >= 400) {
|
if (res.getStatusCode() >= 400) {
|
||||||
throw new IllegalStateException("Transaction failed: " + res.getStatusMessage());
|
if (service.getClient().getConfiguration().isContinueOnError()) {
|
||||||
|
result.add(ODataErrorResponseChecker.checkResponse(
|
||||||
|
service.getClient(),
|
||||||
|
new StatusLine() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProtocolVersion getProtocolVersion() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStatusCode() {
|
||||||
|
return res.getStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReasonPhrase() {
|
||||||
|
return res.getStatusMessage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
res.getRawResponse(),
|
||||||
|
((ODataRequest) request).getAccept()));
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Transaction failed: " + res.getStatusMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.add(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final EntityInvocationHandler handler = items.get(changesetItemId);
|
final EntityInvocationHandler handler = items.get(changesetItemId);
|
||||||
|
@ -107,5 +142,7 @@ public class TransactionalPersistenceManagerImpl extends AbstractPersistenceMana
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import javax.ws.rs.BadRequestException;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Path("/V40/Static.svc")
|
@Path("/V40/Static.svc")
|
||||||
|
@ -301,7 +302,7 @@ public class V4Services extends AbstractServices {
|
||||||
addChangesetItemIntro(chbos, lastContebtID, cboundary);
|
addChangesetItemIntro(chbos, lastContebtID, cboundary);
|
||||||
|
|
||||||
res = bodyPartRequest(new MimeBodyPart(part.getInputStream()), references);
|
res = bodyPartRequest(new MimeBodyPart(part.getInputStream()), references);
|
||||||
if (res == null || res.getStatus() >= 400) {
|
if (!continueOnError && (res == null || res.getStatus() >= 400)) {
|
||||||
throw new Exception("Failure processing changeset");
|
throw new Exception("Failure processing changeset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +373,7 @@ public class V4Services extends AbstractServices {
|
||||||
return StringUtils.isBlank(filter) && StringUtils.isBlank(search)
|
return StringUtils.isBlank(filter) && StringUtils.isBlank(search)
|
||||||
? NumberUtils.isNumber(type)
|
? NumberUtils.isNumber(type)
|
||||||
? super.getEntityInternal(
|
? super.getEntityInternal(
|
||||||
uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null)
|
uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null)
|
||||||
: super.getEntitySet(accept, "People", type)
|
: super.getEntitySet(accept, "People", type)
|
||||||
: super.getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken);
|
: super.getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken);
|
||||||
}
|
}
|
||||||
|
@ -753,7 +754,7 @@ public class V4Services extends AbstractServices {
|
||||||
|
|
||||||
return utils.getValue().createResponse(
|
return utils.getValue().createResponse(
|
||||||
FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
|
FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
|
||||||
+ File.separatorChar + filename, utils.getKey()),
|
+ File.separatorChar + filename, utils.getKey()),
|
||||||
null,
|
null,
|
||||||
utils.getKey());
|
utils.getKey());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -762,6 +763,24 @@ public class V4Services extends AbstractServices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/People")
|
||||||
|
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
|
||||||
|
@Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM})
|
||||||
|
public Response postPeople(
|
||||||
|
@Context final UriInfo uriInfo,
|
||||||
|
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
|
||||||
|
@HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
|
||||||
|
@HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
|
||||||
|
final String entity) {
|
||||||
|
|
||||||
|
if ("{\"@odata.type\":\"#Microsoft.Test.OData.Services.ODataWCFService.Person\"}".equals(entity)) {
|
||||||
|
return xml.createFaultResponse(accept, new BadRequestException());
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.postNewEntity(uriInfo, accept, contentType, prefer, "People", entity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response patchEntity(
|
public Response patchEntity(
|
||||||
final UriInfo uriInfo,
|
final UriInfo uriInfo,
|
||||||
|
@ -775,9 +794,9 @@ public class V4Services extends AbstractServices {
|
||||||
|
|
||||||
final Response response =
|
final Response response =
|
||||||
getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
|
getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
|
||||||
accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
|
accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
return response.getStatus() >= 400
|
return response.getStatus() >= 400
|
||||||
? postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes)
|
? super.postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes)
|
||||||
: super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
|
: super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1020,7 @@ public class V4Services extends AbstractServices {
|
||||||
// 1. Fetch the contained entity to be removed
|
// 1. Fetch the contained entity to be removed
|
||||||
final InputStream entry = FSManager.instance(version).
|
final InputStream entry = FSManager.instance(version).
|
||||||
readFile(containedPath(entityId, containedEntitySetName).
|
readFile(containedPath(entityId, containedEntitySetName).
|
||||||
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
||||||
final ResWrap<Entity> container = atomDeserializer.toEntity(entry);
|
final ResWrap<Entity> container = atomDeserializer.toEntity(entry);
|
||||||
|
|
||||||
// 2. Remove the contained entity
|
// 2. Remove the contained entity
|
||||||
|
@ -1275,7 +1294,7 @@ public class V4Services extends AbstractServices {
|
||||||
|
|
||||||
final ResWrap<Property> result = new ResWrap<Property>(
|
final ResWrap<Property> result = new ResWrap<Property>(
|
||||||
URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
|
URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
|
||||||
+ "Microsoft.Test.OData.Services.ODataWCFService.Address"),
|
+ "Microsoft.Test.OData.Services.ODataWCFService.Address"),
|
||||||
null,
|
null,
|
||||||
entity.getProperty("address"));
|
entity.getProperty("address"));
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.olingo.fit.proxy.v3;
|
package org.apache.olingo.fit.proxy.v3;
|
||||||
|
|
||||||
//CHECKSTYLE:OFF (Maven checkstyle)
|
//CHECKSTYLE:OFF (Maven checkstyle)
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.olingo.fit.proxy.v4;
|
package org.apache.olingo.fit.proxy.v4;
|
||||||
|
|
||||||
//CHECKSTYLE:OFF (Maven checkstyle)
|
//CHECKSTYLE:OFF (Maven checkstyle)
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.olingo.fit.proxy.v4;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
|
import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
import org.apache.olingo.commons.api.format.ContentType;
|
||||||
|
import org.apache.olingo.ext.proxy.Service;
|
||||||
|
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.InMemoryEntities;
|
||||||
|
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Address;
|
||||||
|
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Employee;
|
||||||
|
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Person;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ContextTestITCase extends AbstractTestITCase {
|
||||||
|
|
||||||
|
private void continueOnError(final Service<EdmEnabledODataClient> service, final InMemoryEntities container) {
|
||||||
|
final Person person = service.newEntity(Person.class);
|
||||||
|
container.getPeople().add(person);
|
||||||
|
|
||||||
|
final Employee employee = service.newEntity(Employee.class);
|
||||||
|
employee.setPersonID(199);
|
||||||
|
employee.setFirstName("Fabio");
|
||||||
|
employee.setLastName("Martelli");
|
||||||
|
employee.setEmails(Collections.<String>singleton("fabio.martelli@tirasa.net"));
|
||||||
|
final Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
date.clear();
|
||||||
|
date.set(2011, 3, 4, 9, 0, 0);
|
||||||
|
employee.setDateHired(new Timestamp(date.getTimeInMillis()));
|
||||||
|
final Address homeAddress = service.newComplex(Address.class);
|
||||||
|
homeAddress.setCity("Pescara");
|
||||||
|
homeAddress.setPostalCode("65100");
|
||||||
|
homeAddress.setStreet("viale Gabriele D'Annunzio 256");
|
||||||
|
employee.setHomeAddress(homeAddress);
|
||||||
|
employee.setNumbers(Arrays.asList(new String[] {"3204725072", "08569930"}));
|
||||||
|
|
||||||
|
container.getPeople().add(employee);
|
||||||
|
|
||||||
|
final List<ODataRuntimeException> result = container.flush();
|
||||||
|
assertEquals(2, result.size());
|
||||||
|
assertTrue(result.get(0) instanceof ODataClientErrorException);
|
||||||
|
assertNull(result.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transactionalContinueOnError() {
|
||||||
|
service.getClient().getConfiguration().setContinueOnError(true);
|
||||||
|
continueOnError(service, container);
|
||||||
|
service.getClient().getConfiguration().setContinueOnError(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nonTransactionalContinueOnError() {
|
||||||
|
final Service<EdmEnabledODataClient> _service = Service.getV4(testStaticServiceRootURL, false);
|
||||||
|
_service.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
|
||||||
|
_service.getClient().getConfiguration().setContinueOnError(true);
|
||||||
|
|
||||||
|
final InMemoryEntities _container = _service.getEntityContainer(InMemoryEntities.class);
|
||||||
|
|
||||||
|
continueOnError(_service, _container);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.olingo.fit.proxy.v4;
|
package org.apache.olingo.fit.proxy.v4;
|
||||||
|
|
||||||
//CHECKSTYLE:OFF (Maven checkstyle)
|
//CHECKSTYLE:OFF (Maven checkstyle)
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
assertEquals(404, res.getStatusCode());
|
assertEquals(404, res.getStatusCode());
|
||||||
assertEquals("Not Found", res.getStatusMessage());
|
assertEquals("Not Found", res.getStatusMessage());
|
||||||
assertEquals(Integer.valueOf(3), Integer.valueOf(
|
assertEquals(Integer.valueOf(3), Integer.valueOf(
|
||||||
res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next()));
|
res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next()));
|
||||||
|
|
||||||
assertFalse(retitem.hasNext());
|
assertFalse(retitem.hasNext());
|
||||||
assertFalse(iter.hasNext());
|
assertFalse(iter.hasNext());
|
||||||
|
@ -175,10 +175,12 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void continueOnError(final boolean continueOnError) {
|
private void continueOnError(final boolean continueOnError) {
|
||||||
|
final boolean preContinueOnError = client.getConfiguration().isContinueOnError();
|
||||||
|
client.getConfiguration().setContinueOnError(continueOnError);
|
||||||
|
|
||||||
// create your request
|
// create your request
|
||||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||||
request.setAccept(ACCEPT);
|
request.setAccept(ACCEPT);
|
||||||
request.continueOnError();
|
|
||||||
|
|
||||||
final BatchManager streamManager = request.payloadManager();
|
final BatchManager streamManager = request.payloadManager();
|
||||||
|
|
||||||
|
@ -187,7 +189,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
// prepare URI
|
// prepare URI
|
||||||
URIBuilder targetURI = client.newURIBuilder(testStaticServiceRootURL);
|
URIBuilder targetURI = client.newURIBuilder(testStaticServiceRootURL);
|
||||||
targetURI.appendEntitySetSegment("UnexistinfEntitySet").appendKeySegment(1);
|
targetURI.appendEntitySetSegment("UnexistingEntitySet").appendKeySegment(1);
|
||||||
|
|
||||||
// create new request
|
// create new request
|
||||||
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||||
|
@ -232,6 +234,8 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
assertEquals(200, res.getStatusCode());
|
assertEquals(200, res.getStatusCode());
|
||||||
assertEquals("OK", res.getStatusMessage());
|
assertEquals("OK", res.getStatusMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.getConfiguration().setContinueOnError(preContinueOnError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -249,7 +253,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
|
|
||||||
// add create request
|
// add create request
|
||||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||||
client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), order);
|
client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), order);
|
||||||
|
|
||||||
changeset.addRequest(createReq);
|
changeset.addRequest(createReq);
|
||||||
|
|
||||||
|
@ -259,8 +263,8 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
// add update request: link CustomerInfo(17) to the new customer
|
// add update request: link CustomerInfo(17) to the new customer
|
||||||
final ODataEntity customerChanges = client.getObjectFactory().newEntity(order.getTypeName());
|
final ODataEntity customerChanges = client.getObjectFactory().newEntity(order.getTypeName());
|
||||||
customerChanges.addLink(client.getObjectFactory().newEntitySetNavigationLink(
|
customerChanges.addLink(client.getObjectFactory().newEntitySetNavigationLink(
|
||||||
"OrderDetails",
|
"OrderDetails",
|
||||||
client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("OrderDetails").
|
client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("OrderDetails").
|
||||||
appendKeySegment(new HashMap<String, Object>() {
|
appendKeySegment(new HashMap<String, Object>() {
|
||||||
private static final long serialVersionUID = 3109256773218160485L;
|
private static final long serialVersionUID = 3109256773218160485L;
|
||||||
|
|
||||||
|
@ -271,7 +275,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
}).build()));
|
}).build()));
|
||||||
|
|
||||||
final ODataEntityUpdateRequest<ODataEntity> updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(
|
final ODataEntityUpdateRequest<ODataEntity> updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||||
URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);
|
URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);
|
||||||
|
|
||||||
changeset.addRequest(updateReq);
|
changeset.addRequest(updateReq);
|
||||||
|
|
||||||
|
@ -293,10 +297,10 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
|
|
||||||
order = ((ODataEntityCreateResponse<ODataEntity>) res).getBody();
|
order = ((ODataEntityCreateResponse<ODataEntity>) res).getBody();
|
||||||
final ODataEntitySetRequest<ODataEntitySet> req = client.getRetrieveRequestFactory().getEntitySetRequest(
|
final ODataEntitySetRequest<ODataEntitySet> req = client.getRetrieveRequestFactory().getEntitySetRequest(
|
||||||
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString() + "/OrderDetails"));
|
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString() + "/OrderDetails"));
|
||||||
|
|
||||||
assertEquals(Integer.valueOf(7),
|
assertEquals(Integer.valueOf(7),
|
||||||
req.execute().getBody().getEntities().get(0).getProperty("OrderID").getPrimitiveValue().
|
req.execute().getBody().getEntities().get(0).getProperty("OrderID").getPrimitiveValue().
|
||||||
toCastValue(Integer.class));
|
toCastValue(Integer.class));
|
||||||
|
|
||||||
res = chgitem.next();
|
res = chgitem.next();
|
||||||
|
@ -305,13 +309,13 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
|
|
||||||
// clean ...
|
// clean ...
|
||||||
assertEquals(204, client.getCUDRequestFactory().getDeleteRequest(
|
assertEquals(204, client.getCUDRequestFactory().getDeleteRequest(
|
||||||
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString())).execute().
|
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString())).execute().
|
||||||
getStatusCode());
|
getStatusCode());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getRetrieveRequestFactory().getEntityRequest(
|
client.getRetrieveRequestFactory().getEntityRequest(
|
||||||
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString())).
|
URIUtils.getURI(testStaticServiceRootURL, order.getEditLink().toASCIIString())).
|
||||||
execute().getBody();
|
execute().getBody();
|
||||||
fail();
|
fail();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -332,7 +336,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
// prepare URI
|
// prepare URI
|
||||||
URIBuilder targetURI = client.newURIBuilder(testStaticServiceRootURL);
|
URIBuilder targetURI = client.newURIBuilder(testStaticServiceRootURL);
|
||||||
targetURI.appendEntitySetSegment("Customers").appendKeySegment(1).
|
targetURI.appendEntitySetSegment("Customers").appendKeySegment(1).
|
||||||
expand("Orders").select("PersonID,Orders/OrderID");
|
expand("Orders").select("PersonID,Orders/OrderID");
|
||||||
|
|
||||||
// create new request
|
// create new request
|
||||||
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||||
|
@ -348,7 +352,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
targetURI = client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders");
|
targetURI = client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders");
|
||||||
final ODataEntity original = newOrder(2000);
|
final ODataEntity original = newOrder(2000);
|
||||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||||
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
||||||
createReq.setFormat(ODataFormat.JSON);
|
createReq.setFormat(ODataFormat.JSON);
|
||||||
streamManager.addRequest(createReq);
|
streamManager.addRequest(createReq);
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
|
@ -386,7 +390,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({"unchecked"})
|
||||||
public void batchRequest() throws EdmPrimitiveTypeException {
|
public void batchRequest() throws EdmPrimitiveTypeException {
|
||||||
// create your request
|
// create your request
|
||||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||||
|
@ -418,15 +422,15 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
final URI editLink = targetURI.build();
|
final URI editLink = targetURI.build();
|
||||||
|
|
||||||
final ODataEntity patch = client.getObjectFactory().newEntity(
|
final ODataEntity patch = client.getObjectFactory().newEntity(
|
||||||
new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Customer"));
|
new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Customer"));
|
||||||
patch.setEditLink(editLink);
|
patch.setEditLink(editLink);
|
||||||
|
|
||||||
patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
|
patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
|
||||||
"LastName",
|
"LastName",
|
||||||
client.getObjectFactory().newPrimitiveValueBuilder().buildString("new last name")));
|
client.getObjectFactory().newPrimitiveValueBuilder().buildString("new last name")));
|
||||||
|
|
||||||
final ODataEntityUpdateRequest<ODataEntity> changeReq =
|
final ODataEntityUpdateRequest<ODataEntity> changeReq =
|
||||||
client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch);
|
client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch);
|
||||||
changeReq.setFormat(ODataFormat.JSON_FULL_METADATA);
|
changeReq.setFormat(ODataFormat.JSON_FULL_METADATA);
|
||||||
|
|
||||||
changeset.addRequest(changeReq);
|
changeset.addRequest(changeReq);
|
||||||
|
@ -435,7 +439,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
targetURI = client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders");
|
targetURI = client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders");
|
||||||
final ODataEntity original = newOrder(1000);
|
final ODataEntity original = newOrder(1000);
|
||||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||||
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
||||||
createReq.setFormat(ODataFormat.JSON);
|
createReq.setFormat(ODataFormat.JSON);
|
||||||
changeset.addRequest(createReq);
|
changeset.addRequest(createReq);
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
|
@ -468,7 +472,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
assertEquals("OK", res.getStatusMessage());
|
assertEquals("OK", res.getStatusMessage());
|
||||||
|
|
||||||
ODataEntityRequestImpl<ODataEntity>.ODataEntityResponseImpl entres =
|
ODataEntityRequestImpl<ODataEntity>.ODataEntityResponseImpl entres =
|
||||||
(ODataEntityRequestImpl.ODataEntityResponseImpl) res;
|
(ODataEntityRequestImpl.ODataEntityResponseImpl) res;
|
||||||
|
|
||||||
ODataEntity entity = entres.getBody();
|
ODataEntity entity = entres.getBody();
|
||||||
assertEquals(1, entity.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class), 0);
|
assertEquals(1, entity.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class), 0);
|
||||||
|
@ -513,7 +517,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
public void async() {
|
public void async() {
|
||||||
// create your request
|
// create your request
|
||||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(
|
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(
|
||||||
URI.create(testStaticServiceRootURL + "/async/").normalize().toASCIIString());
|
URI.create(testStaticServiceRootURL + "/async/").normalize().toASCIIString());
|
||||||
request.setAccept(ACCEPT);
|
request.setAccept(ACCEPT);
|
||||||
|
|
||||||
final AsyncBatchRequestWrapper async = client.getAsyncRequestFactory().getAsyncBatchRequestWrapper(request);
|
final AsyncBatchRequestWrapper async = client.getAsyncRequestFactory().getAsyncBatchRequestWrapper(request);
|
||||||
|
@ -556,17 +560,17 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||||
|
|
||||||
// retrieve the first item (ODataRetrieve)
|
// retrieve the first item (ODataRetrieve)
|
||||||
ODataBatchResponseItem item = iter.next();
|
final ODataBatchResponseItem item = iter.next();
|
||||||
assertTrue(item instanceof ODataSingleResponseItem);
|
assertTrue(item instanceof ODataSingleResponseItem);
|
||||||
|
|
||||||
// The service return interim results to an asynchronously executing batch.
|
// The service return interim results to an asynchronously executing batch.
|
||||||
ODataSingleResponseItem retitem = (ODataSingleResponseItem) item;
|
final ODataSingleResponseItem retitem = (ODataSingleResponseItem) item;
|
||||||
ODataResponse res = retitem.next();
|
final ODataResponse res = retitem.next();
|
||||||
assertTrue(res instanceof AsyncResponse);
|
assertTrue(res instanceof AsyncResponse);
|
||||||
assertEquals(202, res.getStatusCode());
|
assertEquals(202, res.getStatusCode());
|
||||||
assertEquals("Accepted", res.getStatusMessage());
|
assertEquals("Accepted", res.getStatusMessage());
|
||||||
|
|
||||||
Collection<String> newMonitorLocation = res.getHeader(HeaderName.location);
|
final Collection<String> newMonitorLocation = res.getHeader(HeaderName.location);
|
||||||
if (newMonitorLocation != null && !newMonitorLocation.isEmpty()) {
|
if (newMonitorLocation != null && !newMonitorLocation.isEmpty()) {
|
||||||
responseWrapper.forceNextMonitorCheck(URI.create(newMonitorLocation.iterator().next()));
|
responseWrapper.forceNextMonitorCheck(URI.create(newMonitorLocation.iterator().next()));
|
||||||
// .... now you can start again with isDone() and getODataResponse().
|
// .... now you can start again with isDone() and getODataResponse().
|
||||||
|
@ -634,20 +638,20 @@ public class BatchTestITCase extends AbstractTestITCase {
|
||||||
|
|
||||||
private ODataEntity newOrder(final int id) {
|
private ODataEntity newOrder(final int id) {
|
||||||
final ODataEntity order = getClient().getObjectFactory().
|
final ODataEntity order = getClient().getObjectFactory().
|
||||||
newEntity(new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Order"));
|
newEntity(new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Order"));
|
||||||
|
|
||||||
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("OrderID",
|
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("OrderID",
|
||||||
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(id)));
|
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(id)));
|
||||||
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("OrderDate",
|
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("OrderDate",
|
||||||
getClient().getObjectFactory().newPrimitiveValueBuilder().
|
getClient().getObjectFactory().newPrimitiveValueBuilder().
|
||||||
setType(EdmPrimitiveTypeKind.DateTimeOffset).setValue(Calendar.getInstance()).build()));
|
setType(EdmPrimitiveTypeKind.DateTimeOffset).setValue(Calendar.getInstance()).build()));
|
||||||
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("ShelfLife",
|
order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("ShelfLife",
|
||||||
getClient().getObjectFactory().newPrimitiveValueBuilder().
|
getClient().getObjectFactory().newPrimitiveValueBuilder().
|
||||||
setType(EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal("0.0000002")).build()));
|
setType(EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal("0.0000002")).build()));
|
||||||
order.getProperties().add(getClient().getObjectFactory().newCollectionProperty("OrderShelfLifes",
|
order.getProperties().add(getClient().getObjectFactory().newCollectionProperty("OrderShelfLifes",
|
||||||
getClient().getObjectFactory().newCollectionValue(EdmPrimitiveTypeKind.Duration.name()).add(
|
getClient().getObjectFactory().newCollectionValue(EdmPrimitiveTypeKind.Duration.name()).add(
|
||||||
getClient().getObjectFactory().newPrimitiveValueBuilder().setType(EdmPrimitiveTypeKind.Duration).
|
getClient().getObjectFactory().newPrimitiveValueBuilder().setType(EdmPrimitiveTypeKind.Duration).
|
||||||
setValue(new BigDecimal("0.0000002")).build())));
|
setValue(new BigDecimal("0.0000002")).build())));
|
||||||
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,14 @@ public interface Configuration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the configured default <tt>Accept</tt> header value format for a batch request.
|
* Gets the configured default <tt>Accept</tt> header value format for a batch request.
|
||||||
|
*
|
||||||
* @return configured default <tt>Accept</tt> header value for a batch request.
|
* @return configured default <tt>Accept</tt> header value for a batch request.
|
||||||
*/
|
*/
|
||||||
ContentType getDefaultBatchAcceptFormat();
|
ContentType getDefaultBatchAcceptFormat();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the default <tt>Accept</tt> header value format for a batch request.
|
* Set the default <tt>Accept</tt> header value format for a batch request.
|
||||||
|
*
|
||||||
* @param contentType default <tt>Accept</tt> header value.
|
* @param contentType default <tt>Accept</tt> header value.
|
||||||
*/
|
*/
|
||||||
void setDefaultBatchAcceptFormat(ContentType contentType);
|
void setDefaultBatchAcceptFormat(ContentType contentType);
|
||||||
|
@ -197,17 +199,35 @@ public interface Configuration {
|
||||||
void setKeyAsSegment(boolean value);
|
void setKeyAsSegment(boolean value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether query URIs in request should contain fully qualified type name.
|
* Gets whether query URIs in request should contain fully qualified type name. - OData Intermediate Conformance
|
||||||
* - OData Intermediate Conformance Level:
|
* Level: MUST support casting to a derived type according to [OData-URL] if derived types are present in the model.
|
||||||
* MUST support casting to a derived type according to [OData-URL] if derived types are present in the model.
|
|
||||||
* <br/>
|
* <br/>
|
||||||
* Example: http://host/service/Customers/Model.VipCustomer(102) or
|
* Example: http://host/service/Customers/Model.VipCustomer(102) or http://host/service/Customers/Model.VipCustomer
|
||||||
* http://host/service/Customers/Model.VipCustomer
|
|
||||||
*
|
*
|
||||||
* @return whether query URIs in request should contain fully qualified type name.
|
* @return whether query URIs in request should contain fully qualified type name. segment.
|
||||||
* segment.
|
|
||||||
*/
|
*/
|
||||||
boolean isAddressingDerivedTypes() ;
|
boolean isAddressingDerivedTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether query URIs in request should contain fully qualified type name. - OData Intermediate Conformance
|
||||||
|
* Level: MUST support casting to a derived type according to [OData-URL] if derived types are present in the model.
|
||||||
|
* <br/>
|
||||||
|
* Example: http://host/service/Customers/Model.VipCustomer(102) or http://host/service/Customers/Model.VipCustomer
|
||||||
|
*
|
||||||
|
* @param value 'TRUE' to use this feature.
|
||||||
|
*/
|
||||||
|
void setAddressingDerivedTypes(boolean value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether operation name in request URI should be fully qualified name, which is required by OData V4
|
||||||
|
* protocol, but some service may still choose to support shorter name.
|
||||||
|
* <br/>
|
||||||
|
* Example: http://host/service/Customers(2)/NS1.Model.IncreaseSalary VS
|
||||||
|
* http://host/service/Customers(2)/IncreaseSalary
|
||||||
|
*
|
||||||
|
* @return wheter operation name in request URI should be fully qualified name. segment.
|
||||||
|
*/
|
||||||
|
boolean isUseUrlOperationFQN();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether operation name in request URI should be fully qualified name, which is required by OData V4 protocol,
|
* Sets whether operation name in request URI should be fully qualified name, which is required by OData V4 protocol,
|
||||||
|
@ -218,31 +238,23 @@ public interface Configuration {
|
||||||
*
|
*
|
||||||
* @param value 'TRUE' to use this feature.
|
* @param value 'TRUE' to use this feature.
|
||||||
*/
|
*/
|
||||||
void setUseUrlOperationFQN(final boolean value);
|
void setUseUrlOperationFQN(boolean value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether operation name in request URI should be fully qualified name, which is required by OData V4 protocol,
|
* When processing a set of requests (in batch requests, for example), checks if the execution will be aborted after
|
||||||
* but some service may still choose to support shorter name.
|
* first error encountered or not.
|
||||||
* <br/>
|
|
||||||
* Example: http://host/service/Customers(2)/NS1.Model.IncreaseSalary VS
|
|
||||||
* http://host/service/Customers(2)/IncreaseSalary
|
|
||||||
*
|
*
|
||||||
* @return whether whether operation name in request URI should be fully qualified name.
|
* @return whether execution of a set of requests will be aborted after first error
|
||||||
* segment.
|
|
||||||
*/
|
*/
|
||||||
boolean isUseUrlOperationFQN() ;
|
boolean isContinueOnError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether query URIs in request should contain fully qualified type name.
|
* When processing a set of requests (in batch requests, for example), sets if the execution will be aborted after
|
||||||
* - OData Intermediate Conformance Level:
|
* first error encountered or not.
|
||||||
* MUST support casting to a derived type according to [OData-URL] if derived types are present in the model.
|
|
||||||
* <br/>
|
|
||||||
* Example: http://host/service/Customers/Model.VipCustomer(102) or
|
|
||||||
* http://host/service/Customers/Model.VipCustomer
|
|
||||||
*
|
*
|
||||||
* @param value 'TRUE' to use this feature.
|
* @param value 'TRUE' to use this feature.
|
||||||
*/
|
*/
|
||||||
void setAddressingDerivedTypes(final boolean value);
|
void setContinueOnError(boolean value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves request executor service.
|
* Retrieves request executor service.
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.client.api.communication;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.domain.ODataError;
|
import org.apache.olingo.commons.api.domain.ODataError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +28,7 @@ import org.apache.olingo.commons.api.domain.ODataError;
|
||||||
*
|
*
|
||||||
* @see ODataError
|
* @see ODataError
|
||||||
*/
|
*/
|
||||||
public class ODataClientErrorException extends RuntimeException {
|
public class ODataClientErrorException extends ODataRuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2551523202755268162L;
|
private static final long serialVersionUID = -2551523202755268162L;
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
package org.apache.olingo.client.api.communication;
|
package org.apache.olingo.client.api.communication;
|
||||||
|
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a server error in OData.
|
* Represents a server error in OData.
|
||||||
*/
|
*/
|
||||||
public class ODataServerErrorException extends RuntimeException {
|
public class ODataServerErrorException extends ODataRuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = -6423014532618680135L;
|
private static final long serialVersionUID = -6423014532618680135L;
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,7 @@ import org.apache.olingo.client.api.communication.request.batch.BatchManager;
|
||||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a batch request.
|
|
||||||
*/
|
|
||||||
public interface ODataBatchRequest
|
public interface ODataBatchRequest
|
||||||
extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchManager> {
|
extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchManager> {
|
||||||
|
|
||||||
ODataBatchRequest continueOnError();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ public class ConfigurationImpl implements Configuration {
|
||||||
|
|
||||||
private static final String CHUNKING = "chunking";
|
private static final String CHUNKING = "chunking";
|
||||||
|
|
||||||
|
private static final String CONTINUE_ON_ERROR = "continueOnError";
|
||||||
|
|
||||||
private final Map<String, Object> CONF = new HashMap<String, Object>();
|
private final Map<String, Object> CONF = new HashMap<String, Object>();
|
||||||
|
|
||||||
private transient ExecutorService executor = Executors.newFixedThreadPool(10);
|
private transient ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||||
|
@ -105,7 +107,7 @@ public class ConfigurationImpl implements Configuration {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ODataFormat getDefaultFormat() {
|
public ODataFormat getDefaultFormat() {
|
||||||
ODataFormat format = getDefaultPubFormat();
|
final ODataFormat format = getDefaultPubFormat();
|
||||||
return format == ODataFormat.ATOM ? ODataFormat.XML : format;
|
return format == ODataFormat.ATOM ? ODataFormat.XML : format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +211,16 @@ public class ConfigurationImpl implements Configuration {
|
||||||
setProperty(USE_OPERATION_FQN_IN_URL, value);
|
setProperty(USE_OPERATION_FQN_IN_URL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isContinueOnError() {
|
||||||
|
return (Boolean) getProperty(CONTINUE_ON_ERROR, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContinueOnError(final boolean value) {
|
||||||
|
setProperty(CONTINUE_ON_ERROR, value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutorService getExecutor() {
|
public ExecutorService getExecutor() {
|
||||||
return executor;
|
return executor;
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.client.core.communication.header;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.olingo.client.api.CommonODataClient;
|
||||||
|
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||||
|
import org.apache.olingo.client.api.communication.ODataServerErrorException;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
import org.apache.olingo.commons.api.domain.ODataError;
|
||||||
|
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||||
|
import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public final class ODataErrorResponseChecker {
|
||||||
|
|
||||||
|
protected static final Logger LOG = LoggerFactory.getLogger(ODataErrorResponseChecker.class);
|
||||||
|
|
||||||
|
private static ODataError getGenericError(final int code, final String errorMsg) {
|
||||||
|
final ODataError error = new ODataError();
|
||||||
|
error.setCode(String.valueOf(code));
|
||||||
|
error.setMessage(errorMsg);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ODataRuntimeException checkResponse(
|
||||||
|
final CommonODataClient<?> odataClient, final StatusLine statusLine, final InputStream entity,
|
||||||
|
final String accept) {
|
||||||
|
|
||||||
|
ODataRuntimeException result = null;
|
||||||
|
|
||||||
|
if (statusLine.getStatusCode() >= 400) {
|
||||||
|
if (entity == null) {
|
||||||
|
result = new ODataClientErrorException(statusLine);
|
||||||
|
} else {
|
||||||
|
final ODataFormat format = accept.contains("xml") ? ODataFormat.XML : ODataFormat.JSON;
|
||||||
|
|
||||||
|
ODataError error;
|
||||||
|
try {
|
||||||
|
error = odataClient.getReader().readError(entity, format);
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
LOG.warn("Error deserializing error response", e);
|
||||||
|
error = getGenericError(
|
||||||
|
statusLine.getStatusCode(),
|
||||||
|
statusLine.getReasonPhrase());
|
||||||
|
} catch (final ODataDeserializerException e) {
|
||||||
|
LOG.warn("Error deserializing error response", e);
|
||||||
|
error = getGenericError(
|
||||||
|
statusLine.getStatusCode(),
|
||||||
|
statusLine.getReasonPhrase());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusLine.getStatusCode() >= 500) {
|
||||||
|
result = new ODataServerErrorException(statusLine);
|
||||||
|
} else {
|
||||||
|
result = new ODataClientErrorException(statusLine, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ODataErrorResponseChecker() {
|
||||||
|
// private constructor for static utility class
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,20 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.client.core.communication.request;
|
package org.apache.olingo.client.core.communication.request;
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
|
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
|
||||||
import org.apache.olingo.client.api.CommonODataClient;
|
import org.apache.olingo.client.api.CommonODataClient;
|
||||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
import org.apache.olingo.client.core.communication.header.ODataErrorResponseChecker;
|
||||||
import org.apache.olingo.client.api.communication.ODataServerErrorException;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.client.api.http.HttpClientException;
|
|
||||||
import org.apache.olingo.commons.api.domain.ODataError;
|
|
||||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
|
||||||
import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class AbstractRequest {
|
public abstract class AbstractRequest {
|
||||||
|
@ -38,13 +32,6 @@ public abstract class AbstractRequest {
|
||||||
*/
|
*/
|
||||||
protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class);
|
protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class);
|
||||||
|
|
||||||
private ODataError getGenericError(final int code, final String errorMsg) {
|
|
||||||
final ODataError error = new ODataError();
|
|
||||||
error.setCode(String.valueOf(code));
|
|
||||||
error.setMessage(errorMsg);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkRequest(final CommonODataClient<?> odataClient, final HttpUriRequest request) {
|
protected void checkRequest(final CommonODataClient<?> odataClient, final HttpUriRequest request) {
|
||||||
// If using and Edm enabled client, checks that the cached service root matches the request URI
|
// If using and Edm enabled client, checks that the cached service root matches the request URI
|
||||||
if (odataClient instanceof CommonEdmEnabledODataClient
|
if (odataClient instanceof CommonEdmEnabledODataClient
|
||||||
|
@ -61,39 +48,18 @@ public abstract class AbstractRequest {
|
||||||
protected void checkResponse(
|
protected void checkResponse(
|
||||||
final CommonODataClient<?> odataClient, final HttpResponse response, final String accept) {
|
final CommonODataClient<?> odataClient, final HttpResponse response, final String accept) {
|
||||||
|
|
||||||
if (response.getStatusLine().getStatusCode() >= 400) {
|
try {
|
||||||
try {
|
final ODataRuntimeException exception = ODataErrorResponseChecker.
|
||||||
final HttpEntity httpEntity = response.getEntity();
|
checkResponse(odataClient,
|
||||||
if (httpEntity == null) {
|
response.getStatusLine(),
|
||||||
throw new ODataClientErrorException(response.getStatusLine());
|
response.getEntity() == null ? null : response.getEntity().getContent(),
|
||||||
} else {
|
accept);
|
||||||
final ODataFormat format = accept.contains("xml") ? ODataFormat.XML : ODataFormat.JSON;
|
if (exception != null) {
|
||||||
|
throw exception;
|
||||||
ODataError error;
|
|
||||||
try {
|
|
||||||
error = odataClient.getReader().readError(httpEntity.getContent(), format);
|
|
||||||
} catch (final RuntimeException e) {
|
|
||||||
LOG.warn("Error deserializing error response", e);
|
|
||||||
error = getGenericError(
|
|
||||||
response.getStatusLine().getStatusCode(),
|
|
||||||
response.getStatusLine().getReasonPhrase());
|
|
||||||
} catch (final ODataDeserializerException e) {
|
|
||||||
LOG.warn("Error deserializing error response", e);
|
|
||||||
error = getGenericError(
|
|
||||||
response.getStatusLine().getStatusCode(),
|
|
||||||
response.getStatusLine().getReasonPhrase());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.getStatusLine().getStatusCode() >= 500) {
|
|
||||||
throw new ODataServerErrorException(response.getStatusLine());
|
|
||||||
} else {
|
|
||||||
throw new ODataClientErrorException(response.getStatusLine(), error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new HttpClientException(
|
|
||||||
"Received '" + response.getStatusLine() + "' but could not extract error body", e);
|
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ODataRuntimeException(
|
||||||
|
"Received '" + response.getStatusLine() + "' but could not extract error body", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import org.apache.olingo.client.api.communication.request.batch.ODataSingleReque
|
||||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||||
import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
|
import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
|
||||||
import org.apache.olingo.client.core.communication.request.Wrapper;
|
import org.apache.olingo.client.core.communication.request.Wrapper;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -36,6 +35,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractBatchManager extends AbstractODataStreamManager<ODataBatchResponse> {
|
public abstract class AbstractBatchManager extends AbstractODataStreamManager<ODataBatchResponse> {
|
||||||
|
|
||||||
|
protected final boolean continueOnError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batch request current item.
|
* Batch request current item.
|
||||||
*/
|
*/
|
||||||
|
@ -46,15 +47,12 @@ public abstract class AbstractBatchManager extends AbstractODataStreamManager<OD
|
||||||
*/
|
*/
|
||||||
protected final CommonODataBatchRequest req;
|
protected final CommonODataBatchRequest req;
|
||||||
|
|
||||||
/**
|
protected AbstractBatchManager(final CommonODataBatchRequest req,
|
||||||
* Private constructor.
|
final Wrapper<Future<HttpResponse>> futureWrap, final boolean continueOnError) {
|
||||||
*
|
|
||||||
* @param req batch request reference.
|
|
||||||
*/
|
|
||||||
protected AbstractBatchManager(
|
|
||||||
final CommonODataBatchRequest req, final Wrapper<Future<HttpResponse>> futureWrap) {
|
|
||||||
super(futureWrap);
|
super(futureWrap);
|
||||||
this.req = req;
|
this.req = req;
|
||||||
|
this.continueOnError = continueOnError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +66,7 @@ public abstract class AbstractBatchManager extends AbstractODataStreamManager<OD
|
||||||
// stream dash boundary
|
// stream dash boundary
|
||||||
streamDashBoundary();
|
streamDashBoundary();
|
||||||
|
|
||||||
final ODataChangesetResponseItem expectedResItem = new ODataChangesetResponseItem();
|
final ODataChangesetResponseItem expectedResItem = new ODataChangesetResponseItem(continueOnError);
|
||||||
((AbstractODataBatchRequest) req).addExpectedResItem(expectedResItem);
|
((AbstractODataBatchRequest) req).addExpectedResItem(expectedResItem);
|
||||||
|
|
||||||
currentItem = new ODataChangesetImpl(req, expectedResItem);
|
currentItem = new ODataChangesetImpl(req, expectedResItem);
|
||||||
|
@ -106,9 +104,6 @@ public abstract class AbstractBatchManager extends AbstractODataStreamManager<OD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected ODataBatchResponse getResponse(final long timeout, final TimeUnit unit) {
|
protected ODataBatchResponse getResponse(final long timeout, final TimeUnit unit) {
|
||||||
closeCurrentItem();
|
closeCurrentItem();
|
||||||
|
@ -140,5 +135,5 @@ public abstract class AbstractBatchManager extends AbstractODataStreamManager<OD
|
||||||
stream(("--" + ((AbstractODataBatchRequest) req).boundary + "--").getBytes());
|
stream(("--" + ((AbstractODataBatchRequest) req).boundary + "--").getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void validateSingleRequest(final ODataBatchableRequest request);
|
protected abstract void validateSingleRequest(ODataBatchableRequest request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.olingo.client.api.ODataBatchConstants;
|
||||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchErrorResponse;
|
import org.apache.olingo.client.core.communication.response.batch.ODataBatchErrorResponse;
|
||||||
import org.apache.olingo.client.core.communication.response.v4.AsyncResponseImpl;
|
import org.apache.olingo.client.core.communication.response.v4.AsyncResponseImpl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
@ -32,22 +31,19 @@ import java.util.NoSuchElementException;
|
||||||
*/
|
*/
|
||||||
public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
|
public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
|
||||||
|
|
||||||
|
private final boolean continueOnError;
|
||||||
|
|
||||||
private boolean unexpected = false;
|
private boolean unexpected = false;
|
||||||
|
|
||||||
/**
|
public ODataChangesetResponseItem(final boolean continueOnError) {
|
||||||
* Constructor.
|
|
||||||
*/
|
|
||||||
public ODataChangesetResponseItem() {
|
|
||||||
super(true);
|
super(true);
|
||||||
|
this.continueOnError = continueOnError;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnexpected() {
|
public void setUnexpected() {
|
||||||
this.unexpected = true;
|
this.unexpected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ODataResponse next() {
|
public ODataResponse next() {
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
|
@ -105,7 +101,7 @@ public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
|
||||||
|
|
||||||
current.initFromBatch(responseLine, headers, batchLineIterator, boundary);
|
current.initFromBatch(responseLine, headers, batchLineIterator, boundary);
|
||||||
|
|
||||||
if (current.getStatusCode() >= 400) {
|
if (current.getStatusCode() >= 400 && !continueOnError) {
|
||||||
// found error ....
|
// found error ....
|
||||||
breaking = true;
|
breaking = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,15 +34,11 @@ import org.apache.olingo.client.core.communication.request.batch.AbstractBatchMa
|
||||||
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest;
|
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest;
|
||||||
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
||||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a batch request.
|
|
||||||
*/
|
|
||||||
public class ODataBatchRequestImpl
|
public class ODataBatchRequestImpl
|
||||||
extends AbstractODataBatchRequest<ODataBatchResponse, BatchManager>
|
extends AbstractODataBatchRequest<ODataBatchResponse, BatchManager>
|
||||||
implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchManager> {
|
implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchManager> {
|
||||||
|
@ -60,20 +56,14 @@ public class ODataBatchRequestImpl
|
||||||
return (BatchManager) payloadManager;
|
return (BatchManager) payloadManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
||||||
getPayloadManager().getBodyStreamWriter().write(toBeStreamed);
|
getPayloadManager().getBodyStreamWriter().write(toBeStreamed);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, final int off, final int len) throws IOException {
|
||||||
getPayloadManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
getPayloadManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +74,7 @@ public class ODataBatchRequestImpl
|
||||||
public class BatchManagerImpl extends AbstractBatchManager implements BatchManager {
|
public class BatchManagerImpl extends AbstractBatchManager implements BatchManager {
|
||||||
|
|
||||||
public BatchManagerImpl(final ODataBatchRequest req) {
|
public BatchManagerImpl(final ODataBatchRequest req) {
|
||||||
super(req, ODataBatchRequestImpl.this.futureWrapper);
|
super(req, ODataBatchRequestImpl.this.futureWrapper, odataClient.getConfiguration().isContinueOnError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,11 +90,6 @@ public class ODataBatchRequestImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a response to a batch request.
|
|
||||||
*
|
|
||||||
* @see org.apache.olingo.client.core.communication.request.ODataBatchRequest
|
|
||||||
*/
|
|
||||||
protected class ODataBatchResponseImpl extends AbstractODataResponse implements ODataBatchResponse {
|
protected class ODataBatchResponseImpl extends AbstractODataResponse implements ODataBatchResponse {
|
||||||
|
|
||||||
protected ODataBatchResponseImpl(final CommonODataClient<?> odataClient, final HttpClient httpClient,
|
protected ODataBatchResponseImpl(final CommonODataClient<?> odataClient, final HttpClient httpClient,
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.client.core.communication.request.batch.v4;
|
package org.apache.olingo.client.core.communication.request.batch.v4;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.olingo.client.api.CommonODataClient;
|
import org.apache.olingo.client.api.CommonODataClient;
|
||||||
|
@ -34,20 +38,10 @@ import org.apache.olingo.client.core.communication.request.batch.AbstractODataBa
|
||||||
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
||||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a batch request.
|
|
||||||
*/
|
|
||||||
public class ODataBatchRequestImpl
|
public class ODataBatchRequestImpl
|
||||||
extends AbstractODataBatchRequest<ODataBatchResponse, BatchManager>
|
extends AbstractODataBatchRequest<ODataBatchResponse, BatchManager>
|
||||||
implements ODataBatchRequest {
|
implements ODataBatchRequest {
|
||||||
|
|
||||||
private boolean continueOnError = false;
|
|
||||||
|
|
||||||
public ODataBatchRequestImpl(final ODataClient odataClient, final URI uri) {
|
public ODataBatchRequestImpl(final ODataClient odataClient, final URI uri) {
|
||||||
super(odataClient, uri);
|
super(odataClient, uri);
|
||||||
setAccept(odataClient.getConfiguration().getDefaultBatchAcceptFormat().toContentTypeString());
|
setAccept(odataClient.getConfiguration().getDefaultBatchAcceptFormat().toContentTypeString());
|
||||||
|
@ -61,18 +55,12 @@ public class ODataBatchRequestImpl
|
||||||
return (BatchManager) payloadManager;
|
return (BatchManager) payloadManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
||||||
getPayloadManager().getBodyStreamWriter().write(toBeStreamed);
|
getPayloadManager().getBodyStreamWriter().write(toBeStreamed);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
||||||
getPayloadManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
getPayloadManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
||||||
|
@ -80,10 +68,12 @@ public class ODataBatchRequestImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ODataBatchRequest continueOnError() {
|
protected HttpResponse doExecute() {
|
||||||
addCustomHeader(HeaderName.prefer, new ODataPreferences(odataClient.getServiceVersion()).continueOnError());
|
if (odataClient.getConfiguration().isContinueOnError()) {
|
||||||
continueOnError = true;
|
addCustomHeader(HeaderName.prefer, new ODataPreferences(odataClient.getServiceVersion()).continueOnError());
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
return super.doExecute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +82,8 @@ public class ODataBatchRequestImpl
|
||||||
public class BatchManagerImpl extends AbstractBatchManager implements BatchManager {
|
public class BatchManagerImpl extends AbstractBatchManager implements BatchManager {
|
||||||
|
|
||||||
public BatchManagerImpl(final ODataBatchRequest req) {
|
public BatchManagerImpl(final ODataBatchRequest req) {
|
||||||
super(req, ODataBatchRequestImpl.this.futureWrapper);
|
super(req, ODataBatchRequestImpl.this.futureWrapper,
|
||||||
|
ODataBatchRequestImpl.this.odataClient.getConfiguration().isContinueOnError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,11 +96,6 @@ public class ODataBatchRequestImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a response to a batch request.
|
|
||||||
*
|
|
||||||
* @see org.apache.olingo.client.core.communication.request.ODataBatchRequest
|
|
||||||
*/
|
|
||||||
protected class ODataBatchResponseImpl extends AbstractODataResponse implements ODataBatchResponse {
|
protected class ODataBatchResponseImpl extends AbstractODataResponse implements ODataBatchResponse {
|
||||||
|
|
||||||
protected ODataBatchResponseImpl(
|
protected ODataBatchResponseImpl(
|
||||||
|
@ -118,12 +104,9 @@ public class ODataBatchRequestImpl
|
||||||
super(odataClient, httpClient, res);
|
super(odataClient, httpClient, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<ODataBatchResponseItem> getBody() {
|
public Iterator<ODataBatchResponseItem> getBody() {
|
||||||
return new ODataBatchResponseManager(this, expectedResItems, continueOnError);
|
return new ODataBatchResponseManager(this, expectedResItems, odataClient.getConfiguration().isContinueOnError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,18 +20,18 @@ package org.apache.olingo.commons.api;
|
||||||
|
|
||||||
public class ODataRuntimeException extends RuntimeException {
|
public class ODataRuntimeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 5492375572049190883L;
|
||||||
|
|
||||||
public ODataRuntimeException(final String msg) {
|
public ODataRuntimeException(final String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ODataRuntimeException(final String msg, final Exception e) {
|
public ODataRuntimeException(final String msg, final Exception cause) {
|
||||||
super(msg, e);
|
super(msg, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ODataRuntimeException(final Exception e) {
|
public ODataRuntimeException(final Exception cause) {
|
||||||
super(e);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ public class TranslatedExceptionsTest {
|
||||||
private static final String ONEPARAM = "ONEPARAM";
|
private static final String ONEPARAM = "ONEPARAM";
|
||||||
private static final String TWOPARAM = "TWOPARAM";
|
private static final String TWOPARAM = "TWOPARAM";
|
||||||
|
|
||||||
|
public TranslatedExceptionsTest() {
|
||||||
|
// for test reason we assume a system with a default Locale.ENGLISH
|
||||||
|
Locale.setDefault(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void basic() {
|
public void basic() {
|
||||||
ODataTranslatedException exp = new ODataTranslatedException(DEV, BASIC);
|
ODataTranslatedException exp = new ODataTranslatedException(DEV, BASIC);
|
||||||
|
|
|
@ -18,34 +18,29 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.serializer.json;
|
package org.apache.olingo.server.core.serializer.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
import java.io.IOException;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
|
import org.apache.olingo.commons.api.Constants;
|
||||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.domain.ODataError;
|
import org.apache.olingo.commons.api.domain.ODataError;
|
||||||
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
|
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
|
||||||
public class ODataErrorSerializer {
|
public class ODataErrorSerializer {
|
||||||
|
|
||||||
private static final String ERROR = "error";
|
|
||||||
private static final String CODE = "code";
|
|
||||||
private static final String MESSAGE = "message";
|
|
||||||
private static final String TARGET = "target";
|
|
||||||
private static final String DETAILS = "details";
|
|
||||||
|
|
||||||
public void writeErrorDocument(JsonGenerator json, ODataError error) throws IOException {
|
public void writeErrorDocument(JsonGenerator json, ODataError error) throws IOException {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
throw new ODataRuntimeException("ODataError object MUST NOT be null!");
|
throw new ODataRuntimeException("ODataError object MUST NOT be null!");
|
||||||
}
|
}
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
json.writeFieldName(ERROR);
|
json.writeFieldName(Constants.JSON_ERROR);
|
||||||
|
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
writeODataError(json, error.getCode(), error.getMessage(), error.getTarget());
|
writeODataError(json, error.getCode(), error.getMessage(), error.getTarget());
|
||||||
|
|
||||||
if (error.getDetails() != null) {
|
if (error.getDetails() != null) {
|
||||||
json.writeArrayFieldStart(DETAILS);
|
json.writeArrayFieldStart(Constants.ERROR_DETAILS);
|
||||||
for (ODataErrorDetail detail : error.getDetails()) {
|
for (ODataErrorDetail detail : error.getDetails()) {
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
writeODataError(json, detail.getCode(), detail.getMessage(), detail.getTarget());
|
writeODataError(json, detail.getCode(), detail.getMessage(), detail.getTarget());
|
||||||
|
@ -58,21 +53,23 @@ public class ODataErrorSerializer {
|
||||||
json.writeEndObject();
|
json.writeEndObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException,
|
private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException {
|
||||||
JsonGenerationException {
|
json.writeFieldName(Constants.ERROR_CODE);
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
json.writeNullField(CODE);
|
json.writeNull();
|
||||||
} else {
|
} else {
|
||||||
json.writeStringField(CODE, code);
|
json.writeString(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json.writeFieldName(Constants.ERROR_MESSAGE);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
json.writeNullField(MESSAGE);
|
json.writeNull();
|
||||||
} else {
|
} else {
|
||||||
json.writeStringField(MESSAGE, message);
|
json.writeString(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
json.writeStringField(TARGET, target);
|
json.writeStringField(Constants.ERROR_TARGET, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.serializer.json;
|
package org.apache.olingo.server.core.serializer.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
import java.io.IOException;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import java.io.InputStream;
|
||||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.Constants;
|
import org.apache.olingo.commons.api.Constants;
|
||||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.data.ContextURL;
|
import org.apache.olingo.commons.api.data.ContextURL;
|
||||||
|
@ -45,11 +46,9 @@ import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
import java.io.IOException;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import java.io.InputStream;
|
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ODataJsonSerializer implements ODataSerializer {
|
public class ODataJsonSerializer implements ODataSerializer {
|
||||||
|
|
||||||
|
@ -64,21 +63,15 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
@Override
|
@Override
|
||||||
public InputStream serviceDocument(final Edm edm, final String serviceRoot) {
|
public InputStream serviceDocument(final Edm edm, final String serviceRoot) {
|
||||||
CircleStreamBuffer buffer;
|
CircleStreamBuffer buffer;
|
||||||
BufferedWriter writer;
|
|
||||||
JsonFactory factory;
|
|
||||||
JsonGenerator gen = null;
|
JsonGenerator gen = null;
|
||||||
|
|
||||||
// TODO: move stream initialization into separate method
|
// TODO: move stream initialization into separate method
|
||||||
try {
|
try {
|
||||||
buffer = new CircleStreamBuffer();
|
buffer = new CircleStreamBuffer();
|
||||||
writer = new BufferedWriter(new OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
|
gen = new JsonFactory().createGenerator(buffer.getOutputStream())
|
||||||
factory = new JsonFactory();
|
.setPrettyPrinter(new DefaultPrettyPrinter());
|
||||||
|
|
||||||
gen = factory.createGenerator(writer);
|
new ServiceDocumentJsonSerializer(edm, serviceRoot).writeServiceDocument(gen);
|
||||||
gen.setPrettyPrinter(new DefaultPrettyPrinter());
|
|
||||||
|
|
||||||
ServiceDocumentJsonSerializer serializer = new ServiceDocumentJsonSerializer(edm, serviceRoot);
|
|
||||||
serializer.writeServiceDocument(gen);
|
|
||||||
|
|
||||||
gen.close();
|
gen.close();
|
||||||
|
|
||||||
|
@ -130,7 +123,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
try {
|
try {
|
||||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
if (entitySetContextURL != null && format != ODataFormat.JSON_NO_METADATA) {
|
if (format != ODataFormat.JSON_NO_METADATA) {
|
||||||
json.writeStringField(Constants.JSON_CONTEXT, entitySetContextURL.getURI().toASCIIString());
|
json.writeStringField(Constants.JSON_CONTEXT, entitySetContextURL.getURI().toASCIIString());
|
||||||
}
|
}
|
||||||
if (entitySet.getCount() != null) {
|
if (entitySet.getCount() != null) {
|
||||||
|
@ -174,6 +167,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
|
|
||||||
protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
|
protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
|
||||||
final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||||
|
final EdmEntityType entityType = entitySet.getEntityType();
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
if (format != ODataFormat.JSON_NO_METADATA) {
|
if (format != ODataFormat.JSON_NO_METADATA) {
|
||||||
if (contextURL != null) {
|
if (contextURL != null) {
|
||||||
|
@ -182,14 +176,15 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
if (entity.getETag() != null) {
|
if (entity.getETag() != null) {
|
||||||
json.writeStringField(Constants.JSON_ETAG, entity.getETag());
|
json.writeStringField(Constants.JSON_ETAG, entity.getETag());
|
||||||
}
|
}
|
||||||
if (entity.getMediaETag() != null) {
|
if (entityType.hasStream()) {
|
||||||
json.writeStringField(Constants.JSON_MEDIA_ETAG, entity.getMediaETag());
|
if (entity.getMediaETag() != null) {
|
||||||
}
|
json.writeStringField(Constants.JSON_MEDIA_ETAG, entity.getMediaETag());
|
||||||
if (entity.getMediaContentType() != null) {
|
}
|
||||||
json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
|
if (entity.getMediaContentType() != null) {
|
||||||
|
json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final EdmEntityType entityType = entitySet.getEntityType();
|
|
||||||
for (final String propertyName : entityType.getPropertyNames()) {
|
for (final String propertyName : entityType.getPropertyNames()) {
|
||||||
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
|
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
|
||||||
final Property property = entity.getProperty(propertyName);
|
final Property property = entity.getProperty(propertyName);
|
||||||
|
@ -214,7 +209,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
writePrimitive(edmProperty, property, json);
|
writePrimitive(edmProperty, property, json);
|
||||||
} else if (property.isLinkedComplex()) {
|
} else if (property.isLinkedComplex()) {
|
||||||
writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json);
|
writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json);
|
||||||
} else if(property.isComplex()) {
|
} else if (property.isComplex()) {
|
||||||
writeComplexValue(edmProperty, property.asComplex(), json);
|
writeComplexValue(edmProperty, property.asComplex(), json);
|
||||||
} else {
|
} else {
|
||||||
throw new ODataRuntimeException("Property type not yet supported!");
|
throw new ODataRuntimeException("Property type not yet supported!");
|
||||||
|
@ -285,7 +280,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
|
private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
|
||||||
JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||||
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
|
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
|
||||||
json.writeStartObject();
|
json.writeStartObject();
|
||||||
for (final String propertyName : type.getPropertyNames()) {
|
for (final String propertyName : type.getPropertyNames()) {
|
||||||
|
|
|
@ -18,22 +18,18 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.serializer.json;
|
package org.apache.olingo.server.core.serializer.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
import java.io.IOException;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
|
import org.apache.olingo.commons.api.Constants;
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
|
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
|
||||||
import org.apache.olingo.commons.api.edm.EdmSingleton;
|
import org.apache.olingo.commons.api.edm.EdmSingleton;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
|
||||||
public class ServiceDocumentJsonSerializer {
|
public class ServiceDocumentJsonSerializer {
|
||||||
public static final String ODATA_CONTEXT = "@odata.context";
|
|
||||||
public static final String METADATA = "$metadata";
|
|
||||||
public static final String VALUE = "value";
|
|
||||||
public static final String NAME = "name";
|
|
||||||
public static final String URL = "url";
|
|
||||||
public static final String KIND = "kind";
|
public static final String KIND = "kind";
|
||||||
|
|
||||||
public static final String FUNCTION_IMPORT = "FunctionImport";
|
public static final String FUNCTION_IMPORT = "FunctionImport";
|
||||||
|
@ -48,64 +44,63 @@ public class ServiceDocumentJsonSerializer {
|
||||||
this.serviceRoot = serviceRoot;
|
this.serviceRoot = serviceRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeServiceDocument(final JsonGenerator gen) throws JsonGenerationException, IOException {
|
public void writeServiceDocument(final JsonGenerator gen) throws IOException {
|
||||||
gen.writeStartObject();
|
gen.writeStartObject();
|
||||||
|
|
||||||
Object metadataUri;
|
Object metadataUri;
|
||||||
|
|
||||||
if (serviceRoot == null) {
|
if (serviceRoot == null) {
|
||||||
metadataUri = METADATA;
|
metadataUri = Constants.METADATA;
|
||||||
} else {
|
} else {
|
||||||
if (serviceRoot.endsWith("/")) {
|
if (serviceRoot.endsWith("/")) {
|
||||||
metadataUri = serviceRoot + METADATA;
|
metadataUri = serviceRoot + Constants.METADATA;
|
||||||
} else {
|
} else {
|
||||||
metadataUri = serviceRoot + "/" + METADATA;
|
metadataUri = serviceRoot + "/" + Constants.METADATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gen.writeObjectField(ODATA_CONTEXT, metadataUri);
|
gen.writeObjectField(Constants.JSON_CONTEXT, metadataUri);
|
||||||
gen.writeArrayFieldStart(VALUE);
|
gen.writeArrayFieldStart(Constants.VALUE);
|
||||||
|
|
||||||
writeEntitySets(gen, edm);
|
writeEntitySets(gen, edm);
|
||||||
writeFunctionImports(gen, edm);
|
writeFunctionImports(gen, edm);
|
||||||
writeSingletons(gen, edm);
|
writeSingletons(gen, edm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeEntitySets(final JsonGenerator gen, final Edm edm) throws JsonGenerationException, IOException {
|
private void writeEntitySets(final JsonGenerator gen, final Edm edm) throws IOException {
|
||||||
EdmEntityContainer container = edm.getEntityContainer(null);
|
EdmEntityContainer container = edm.getEntityContainer(null);
|
||||||
|
|
||||||
for (EdmEntitySet edmEntitySet : container.getEntitySets()) {
|
for (EdmEntitySet edmEntitySet : container.getEntitySets()) {
|
||||||
if (edmEntitySet.isIncludeInServiceDocument()) {
|
if (edmEntitySet.isIncludeInServiceDocument()) {
|
||||||
gen.writeStartObject();
|
gen.writeStartObject();
|
||||||
gen.writeObjectField(NAME, edmEntitySet.getName());
|
gen.writeObjectField(Constants.JSON_NAME, edmEntitySet.getName());
|
||||||
gen.writeObjectField(URL, edmEntitySet.getName());
|
gen.writeObjectField(Constants.JSON_URL, edmEntitySet.getName());
|
||||||
gen.writeEndObject();
|
gen.writeEndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeFunctionImports(final JsonGenerator gen, final Edm edm) throws JsonGenerationException,
|
private void writeFunctionImports(final JsonGenerator gen, final Edm edm) throws IOException {
|
||||||
IOException {
|
|
||||||
EdmEntityContainer container = edm.getEntityContainer(null);
|
EdmEntityContainer container = edm.getEntityContainer(null);
|
||||||
|
|
||||||
for (EdmFunctionImport edmFunctionImport : container.getFunctionImports()) {
|
for (EdmFunctionImport edmFunctionImport : container.getFunctionImports()) {
|
||||||
if (edmFunctionImport.isIncludeInServiceDocument()) {
|
if (edmFunctionImport.isIncludeInServiceDocument()) {
|
||||||
gen.writeStartObject();
|
gen.writeStartObject();
|
||||||
gen.writeObjectField(NAME, edmFunctionImport.getName());
|
gen.writeObjectField(Constants.JSON_NAME, edmFunctionImport.getName());
|
||||||
gen.writeObjectField(URL, edmFunctionImport.getName());
|
gen.writeObjectField(Constants.JSON_URL, edmFunctionImport.getName());
|
||||||
gen.writeObjectField(KIND, FUNCTION_IMPORT);
|
gen.writeObjectField(KIND, FUNCTION_IMPORT);
|
||||||
gen.writeEndObject();
|
gen.writeEndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSingletons(final JsonGenerator gen, final Edm edm) throws JsonGenerationException, IOException {
|
private void writeSingletons(final JsonGenerator gen, final Edm edm) throws IOException {
|
||||||
EdmEntityContainer container = edm.getEntityContainer(null);
|
EdmEntityContainer container = edm.getEntityContainer(null);
|
||||||
|
|
||||||
for (EdmSingleton edmSingleton : container.getSingletons()) {
|
for (EdmSingleton edmSingleton : container.getSingletons()) {
|
||||||
gen.writeStartObject();
|
gen.writeStartObject();
|
||||||
gen.writeObjectField(NAME, edmSingleton.getName());
|
gen.writeObjectField(Constants.JSON_NAME, edmSingleton.getName());
|
||||||
gen.writeObjectField(URL, edmSingleton.getName());
|
gen.writeObjectField(Constants.JSON_URL, edmSingleton.getName());
|
||||||
gen.writeObjectField(KIND, SINGLETON);
|
gen.writeObjectField(KIND, SINGLETON);
|
||||||
gen.writeEndObject();
|
gen.writeEndObject();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.tecsvc.data;
|
package org.apache.olingo.server.tecsvc.data;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntitySet;
|
import org.apache.olingo.commons.api.data.EntitySet;
|
||||||
import org.apache.olingo.commons.api.data.LinkedComplexValue;
|
import org.apache.olingo.commons.api.data.LinkedComplexValue;
|
||||||
|
@ -35,16 +45,6 @@ import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
|
||||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||||
import org.apache.olingo.server.api.uri.UriParameter;
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class DataProvider {
|
public class DataProvider {
|
||||||
|
|
||||||
private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
|
private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
|
||||||
|
@ -61,6 +61,7 @@ public class DataProvider {
|
||||||
data.put("ESCollAllPrim", createESCollAllPrim());
|
data.put("ESCollAllPrim", createESCollAllPrim());
|
||||||
data.put("ESMixPrimCollComp", createESMixPrimCollComp());
|
data.put("ESMixPrimCollComp", createESMixPrimCollComp());
|
||||||
data.put("ESAllKey", createESAllKey());
|
data.put("ESAllKey", createESAllKey());
|
||||||
|
data.put("ESMedia", createESMedia());
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntitySet readAll(final EdmEntitySet edmEntitySet) throws DataProviderException {
|
public EntitySet readAll(final EdmEntitySet edmEntitySet) throws DataProviderException {
|
||||||
|
@ -419,6 +420,32 @@ public class DataProvider {
|
||||||
return entitySet;
|
return entitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EntitySet createESMedia() {
|
||||||
|
EntitySet entitySet = new EntitySetImpl();
|
||||||
|
|
||||||
|
Entity entity = new EntityImpl();
|
||||||
|
entity.addProperty(createPrimitive("PropertyInt16", 1));
|
||||||
|
entity.setMediaContentType("image/png");
|
||||||
|
entitySet.getEntities().add(entity);
|
||||||
|
|
||||||
|
entity = new EntityImpl();
|
||||||
|
entity.addProperty(createPrimitive("PropertyInt16", 2));
|
||||||
|
entity.setMediaContentType("image/bmp");
|
||||||
|
entitySet.getEntities().add(entity);
|
||||||
|
|
||||||
|
entity = new EntityImpl();
|
||||||
|
entity.addProperty(createPrimitive("PropertyInt16", 3));
|
||||||
|
entity.setMediaContentType("image/jpeg");
|
||||||
|
entitySet.getEntities().add(entity);
|
||||||
|
|
||||||
|
entity = new EntityImpl();
|
||||||
|
entity.addProperty(createPrimitive("PropertyInt16", 4));
|
||||||
|
entity.setMediaContentType("foo");
|
||||||
|
entitySet.getEntities().add(entity);
|
||||||
|
|
||||||
|
return entitySet;
|
||||||
|
}
|
||||||
|
|
||||||
private Property createPrimitive(final String name, final Object value) {
|
private Property createPrimitive(final String name, final Object value) {
|
||||||
return new PropertyImpl(null, name, ValueType.PRIMITIVE, value);
|
return new PropertyImpl(null, name, ValueType.PRIMITIVE, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.serializer.json;
|
package org.apache.olingo.server.core.serializer.json;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.data.ContextURL;
|
import org.apache.olingo.commons.api.data.ContextURL;
|
||||||
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntitySet;
|
import org.apache.olingo.commons.api.data.EntitySet;
|
||||||
|
import org.apache.olingo.commons.api.data.ValueType;
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
|
@ -35,9 +41,6 @@ import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
public class ODataJsonSerializerTest {
|
public class ODataJsonSerializerTest {
|
||||||
|
|
||||||
private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
|
private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
|
||||||
|
@ -75,6 +78,40 @@ public class ODataJsonSerializerTest {
|
||||||
Assert.assertEquals(expectedResult, resultString);
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityAllPrimAllNull() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||||
|
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||||
|
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
|
||||||
|
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
|
||||||
|
final String expectedResult = "{\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
|
||||||
|
+ "\"PropertyInt16\":32767,"
|
||||||
|
+ "\"PropertyString\":null,\"PropertyBoolean\":null,"
|
||||||
|
+ "\"PropertyByte\":null,\"PropertySByte\":null,"
|
||||||
|
+ "\"PropertyInt32\":null,\"PropertyInt64\":null,"
|
||||||
|
+ "\"PropertySingle\":null,\"PropertyDouble\":null,\"PropertyDecimal\":null,"
|
||||||
|
+ "\"PropertyBinary\":null,"
|
||||||
|
+ "\"PropertyDate\":null,\"PropertyDateTimeOffset\":null,\"PropertyDuration\":null,"
|
||||||
|
+ "\"PropertyGuid\":null,\"PropertyTimeOfDay\":null}";
|
||||||
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ODataRuntimeException.class)
|
||||||
|
public void entityAllPrimKeyNull() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||||
|
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||||
|
entity.getProperties().clear();
|
||||||
|
serializer.entity(edmEntitySet, entity, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ODataRuntimeException.class)
|
||||||
|
public void entityWrongData() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||||
|
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||||
|
entity.getProperties().get(0).setValue(ValueType.PRIMITIVE, false);
|
||||||
|
serializer.entity(edmEntitySet, entity, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void entitySetAllPrim() throws Exception {
|
public void entitySetAllPrim() throws Exception {
|
||||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||||
|
@ -180,6 +217,18 @@ public class ODataJsonSerializerTest {
|
||||||
Assert.assertEquals(expectedResult, resultString);
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityMixPrimCollCompAllNull() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
|
||||||
|
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||||
|
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
|
||||||
|
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
|
||||||
|
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
|
||||||
|
+ "\"PropertyInt16\":32767,"
|
||||||
|
+ "\"CollPropertyString\":null,\"PropertyComp\":null,\"CollPropertyComp\":null}";
|
||||||
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void entityTwoPrimNoMetadata() throws Exception {
|
public void entityTwoPrimNoMetadata() throws Exception {
|
||||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||||
|
@ -205,4 +254,29 @@ public class ODataJsonSerializerTest {
|
||||||
+ "{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"}]}";
|
+ "{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"}]}";
|
||||||
Assert.assertEquals(expectedResult, resultString);
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityMedia() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
|
||||||
|
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||||
|
entity.setMediaETag("theMediaETag");
|
||||||
|
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
|
||||||
|
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
|
||||||
|
+ "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/png\","
|
||||||
|
+ "\"PropertyInt16\":1}";
|
||||||
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entitySetMedia() throws Exception {
|
||||||
|
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
|
||||||
|
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||||
|
final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet, null));
|
||||||
|
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
|
||||||
|
+ "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
|
||||||
|
+ "{\"@odata.mediaContentType\":\"image/bmp\",\"PropertyInt16\":2},"
|
||||||
|
+ "{\"@odata.mediaContentType\":\"image/jpeg\",\"PropertyInt16\":3},"
|
||||||
|
+ "{\"@odata.mediaContentType\":\"foo\",\"PropertyInt16\":4}]}";
|
||||||
|
Assert.assertEquals(expectedResult, resultString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue