[OLINGO-246] provided batch integration; still missing internak batch reference support
This commit is contained in:
parent
542541dd4c
commit
68f27d57a1
|
@ -18,12 +18,12 @@
|
|||
*/
|
||||
package org.apache.olingo.fit;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Container;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.apache.olingo.commons.api.data.Feed;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.core.data.AtomFeedImpl;
|
||||
import org.apache.olingo.commons.core.data.LinkImpl;
|
||||
import org.apache.olingo.fit.metadata.Metadata;
|
||||
|
@ -33,24 +33,28 @@ import org.apache.olingo.fit.utils.ConstantKey;
|
|||
import org.apache.olingo.fit.utils.Constants;
|
||||
import org.apache.olingo.fit.utils.DataBinder;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.mail.Header;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
|
@ -65,12 +69,20 @@ import javax.ws.rs.Produces;
|
|||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.cxf.jaxrs.client.WebClient;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
|
||||
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
|
||||
import org.apache.olingo.commons.api.data.Container;
|
||||
import org.apache.olingo.commons.api.data.Entry;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.core.data.AtomEntryImpl;
|
||||
import org.apache.olingo.commons.core.data.AtomPropertyImpl;
|
||||
import org.apache.olingo.commons.core.data.AtomSerializer;
|
||||
|
@ -81,13 +93,13 @@ import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
|
|||
import org.apache.olingo.fit.metadata.EntitySet;
|
||||
import org.apache.olingo.fit.metadata.EntityType;
|
||||
import org.apache.olingo.fit.metadata.NavigationProperty;
|
||||
import org.apache.olingo.fit.methods.MERGE;
|
||||
import org.apache.olingo.fit.methods.PATCH;
|
||||
import org.apache.olingo.fit.serializer.FITAtomDeserializer;
|
||||
import org.apache.olingo.fit.utils.Accept;
|
||||
import org.apache.olingo.fit.utils.FSManager;
|
||||
|
||||
import org.apache.olingo.fit.utils.Commons;
|
||||
import org.apache.olingo.fit.methods.MERGE;
|
||||
import org.apache.olingo.fit.methods.PATCH;
|
||||
import org.apache.olingo.fit.serializer.FITAtomDeserializer;
|
||||
import org.apache.olingo.fit.utils.AbstractJSONUtilities;
|
||||
import org.apache.olingo.fit.utils.AbstractUtilities;
|
||||
import org.apache.olingo.fit.utils.AbstractXMLUtilities;
|
||||
|
@ -102,6 +114,10 @@ public abstract class AbstractServices {
|
|||
*/
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(AbstractServices.class);
|
||||
|
||||
private Pattern requestPatter = Pattern.compile("(.*) (http://.*) HTTP/.*");
|
||||
|
||||
private static final String boundary = "batch_243234_25424_ef_892u748";
|
||||
|
||||
protected final ODataServiceVersion version;
|
||||
|
||||
protected final AbstractXMLUtilities xml;
|
||||
|
@ -174,6 +190,197 @@ public abstract class AbstractServices {
|
|||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/$batch")
|
||||
@Consumes("multipart/mixed")
|
||||
@Produces("application/octet-stream; boundary=" + boundary)
|
||||
public Response batch(final @Multipart MultipartBody attachment) {
|
||||
try {
|
||||
return xml.createBatchResponse(exploreMultipart(attachment.getAllAttachments(), boundary), boundary);
|
||||
} catch (IOException e) {
|
||||
return xml.createFaultResponse(Accept.XML.toString(version), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Response bodyPartRequest(final MimeBodyPart body) throws Exception {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Enumeration<Header> en = (Enumeration<Header>) body.getAllHeaders();
|
||||
|
||||
Header header = en.nextElement();
|
||||
final String request = header.getName() + ":" + header.getValue();
|
||||
final Matcher matcher = requestPatter.matcher(request);
|
||||
|
||||
if (matcher.find()) {
|
||||
final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
|
||||
|
||||
while (en.hasMoreElements()) {
|
||||
header = en.nextElement();
|
||||
headers.putSingle(header.getName(), header.getValue());
|
||||
}
|
||||
|
||||
String method = matcher.group(1);
|
||||
if ("PATCH".equals(method) || "MERGE".equals(method)) {
|
||||
headers.putSingle("X-HTTP-METHOD", method);
|
||||
method = "POST";
|
||||
}
|
||||
|
||||
final String url = matcher.group(2);
|
||||
|
||||
final WebClient client = WebClient.create(url);
|
||||
|
||||
client.headers(headers);
|
||||
|
||||
return client.invoke(method, body.getDataHandler().getInputStream());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream exploreMultipart(final List<Attachment> attachments, final String boundary) throws IOException {
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
Response res = null;
|
||||
try {
|
||||
for (Attachment obj : attachments) {
|
||||
bos.write(("--" + boundary).getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
|
||||
final Object content = obj.getDataHandler().getContent();
|
||||
if (content instanceof MimeMultipart) {
|
||||
final String cboundary = "changeset_" + UUID.randomUUID().toString();
|
||||
bos.write(("Content-Type: multipart/mixed;boundary=" + cboundary).getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
bos.write(Constants.CRLF);
|
||||
|
||||
final ByteArrayOutputStream chbos = new ByteArrayOutputStream();
|
||||
String lastContebtID = null;
|
||||
try {
|
||||
for (int i = 0; i < ((MimeMultipart) content).getCount(); i++) {
|
||||
final MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) content).getBodyPart(i);
|
||||
lastContebtID = part.getContentID();
|
||||
addChangesetItemIntro(chbos, lastContebtID, cboundary);
|
||||
|
||||
res = bodyPartRequest(new MimeBodyPart(part.getInputStream()));
|
||||
if (res.getStatus() > 400) {
|
||||
throw new Exception("Failure processing changeset");
|
||||
}
|
||||
|
||||
addSingleBatchResponse(res, lastContebtID, chbos);
|
||||
}
|
||||
bos.write(chbos.toByteArray());
|
||||
IOUtils.closeQuietly(chbos);
|
||||
|
||||
bos.write(("--" + cboundary + "--").getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("While processing changeset", e);
|
||||
IOUtils.closeQuietly(chbos);
|
||||
|
||||
addChangesetItemIntro(bos, lastContebtID, cboundary);
|
||||
if (res == null || res.getStatus() < 400) {
|
||||
addErrorBatchResponse(e, "1", bos);
|
||||
} else {
|
||||
addSingleBatchResponse(res, lastContebtID, bos);
|
||||
}
|
||||
|
||||
bos.write(("--" + cboundary + "--").getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
} else {
|
||||
addItemIntro(bos);
|
||||
|
||||
res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()));
|
||||
|
||||
if (res.getStatus() > 400) {
|
||||
throw new Exception("Failure processing changeset");
|
||||
}
|
||||
|
||||
addSingleBatchResponse(res, bos);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (res == null || res.getStatus() < 400) {
|
||||
addErrorBatchResponse(e, bos);
|
||||
} else {
|
||||
addSingleBatchResponse(res, bos);
|
||||
}
|
||||
}
|
||||
|
||||
bos.write(("--" + boundary + "--").getBytes());
|
||||
|
||||
return new ByteArrayInputStream(bos.toByteArray());
|
||||
}
|
||||
|
||||
private void addItemIntro(final ByteArrayOutputStream bos) throws IOException {
|
||||
bos.write("Content-Type: application/http".getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
bos.write("Content-Transfer-Encoding: binary".getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
|
||||
private void addChangesetItemIntro(
|
||||
final ByteArrayOutputStream bos, final String contentId, final String cboundary) throws IOException {
|
||||
bos.write(("--" + cboundary).getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
bos.write(("Content-ID: " + contentId).getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
addItemIntro(bos);
|
||||
}
|
||||
|
||||
private void addSingleBatchResponse(
|
||||
final Response response, final ByteArrayOutputStream bos) throws IOException {
|
||||
addSingleBatchResponse(response, null, bos);
|
||||
}
|
||||
|
||||
private void addSingleBatchResponse(
|
||||
final Response response, final String contentId, final ByteArrayOutputStream bos) throws IOException {
|
||||
bos.write("HTTP/1.1 ".getBytes());
|
||||
bos.write(String.valueOf(response.getStatusInfo().getStatusCode()).getBytes());
|
||||
bos.write(" ".getBytes());
|
||||
bos.write(response.getStatusInfo().getReasonPhrase().getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
|
||||
for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Object value : header.getValue()) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(value.toString());
|
||||
}
|
||||
builder.insert(0, ": ").insert(0, header.getKey());
|
||||
bos.write(builder.toString().getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(contentId)) {
|
||||
bos.write(("Content-ID: " + contentId).getBytes());
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
|
||||
bos.write(Constants.CRLF);
|
||||
|
||||
final Object entity = response.getEntity();
|
||||
if (entity != null) {
|
||||
bos.write(IOUtils.toByteArray((InputStream) entity));
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
|
||||
bos.write(Constants.CRLF);
|
||||
}
|
||||
|
||||
private void addErrorBatchResponse(final Exception e, final ByteArrayOutputStream bos)
|
||||
throws IOException {
|
||||
addErrorBatchResponse(e, null, bos);
|
||||
}
|
||||
|
||||
private void addErrorBatchResponse(final Exception e, final String contentId, final ByteArrayOutputStream bos)
|
||||
throws IOException {
|
||||
addSingleBatchResponse(xml.createFaultResponse(Accept.XML.toString(version), e), contentId, bos);
|
||||
}
|
||||
|
||||
@MERGE
|
||||
@Path("/{entitySetName}({entityId})")
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
|
||||
|
|
|
@ -60,6 +60,21 @@ public abstract class AbstractUtilities {
|
|||
|
||||
protected final static Pattern entityUriPattern = Pattern.compile(".*\\/.*\\(.*\\)");
|
||||
|
||||
/**
|
||||
* Batch/Changeset content type.
|
||||
*/
|
||||
public static final String MULTIPART_CONTENT_TYPE = "multipart/mixed";
|
||||
|
||||
/**
|
||||
* Batch item content type.
|
||||
*/
|
||||
public static final String ITEM_CONTENT_TYPE = "application/http";
|
||||
|
||||
/**
|
||||
* Boundary key.
|
||||
*/
|
||||
public static final String BOUNDARY = "boundary";
|
||||
|
||||
public AbstractUtilities(final ODataServiceVersion version) throws Exception {
|
||||
this.version = version;
|
||||
this.fsManager = FSManager.instance(version);
|
||||
|
@ -399,6 +414,13 @@ public abstract class AbstractUtilities {
|
|||
return createResponse(entity, etag, accept, null);
|
||||
}
|
||||
|
||||
public Response createBatchResponse(final InputStream stream, final String boundary) {
|
||||
|
||||
final Response.ResponseBuilder builder = Response.accepted(stream);
|
||||
builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public Response createResponse(
|
||||
final InputStream entity, final String etag, final Accept accept, final Response.Status status) {
|
||||
final Response.ResponseBuilder builder = Response.ok();
|
||||
|
|
|
@ -29,6 +29,11 @@ public class Constants {
|
|||
|
||||
private final static Map<ConstantKey, String> constants = new EnumMap<ConstantKey, String>(ConstantKey.class);
|
||||
|
||||
/**
|
||||
* CR/LF.
|
||||
*/
|
||||
public static final byte[] CRLF = {13, 10};
|
||||
|
||||
public static Charset encoding = Charset.forName("UTF-8");
|
||||
|
||||
static {
|
||||
|
|
|
@ -59,7 +59,7 @@ public enum HeaderName {
|
|||
* <li>multipart/mixed</li>
|
||||
* </ul>
|
||||
*/
|
||||
contentType("Content-Type", Arrays.asList(ODataServiceVersion.V30)),
|
||||
contentType("Content-Type", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* This header is a custom HTTP header defined for protocol versioning purposes. This header MAY be present on any
|
||||
* request or response message.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.olingo.client.api.communication.request.cud;
|
||||
|
||||
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.response.ODataEntityCreateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
|
@ -29,5 +30,5 @@ import org.apache.olingo.commons.api.format.ODataPubFormat;
|
|||
* @param <E> concrete ODataEntity implementation
|
||||
*/
|
||||
public interface ODataEntityCreateRequest<E extends CommonODataEntity>
|
||||
extends ODataBasicRequest<ODataEntityCreateResponse<E>, ODataPubFormat> {
|
||||
extends ODataBasicRequest<ODataEntityCreateResponse<E>, ODataPubFormat>, ODataBatchableRequest {
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.olingo.client.api.communication.request.cud;
|
||||
|
||||
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.response.ODataEntityUpdateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
|
@ -29,5 +30,5 @@ import org.apache.olingo.commons.api.format.ODataPubFormat;
|
|||
* @param <E> concrete ODataEntity implementation
|
||||
*/
|
||||
public interface ODataEntityUpdateRequest<E extends CommonODataEntity>
|
||||
extends ODataBasicRequest<ODataEntityUpdateResponse<E>, ODataPubFormat> {
|
||||
extends ODataBasicRequest<ODataEntityUpdateResponse<E>, ODataPubFormat>, ODataBatchableRequest {
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
package org.apache.olingo.client.api.communication.request.retrieve;
|
||||
|
||||
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.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.commons.api.format.Format;
|
||||
|
||||
/**
|
||||
* This is an abstract representation of an OData retrieve query request returning one or more result item.
|
||||
*/
|
||||
public interface ODataRetrieveRequest<V, T extends Format> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
|
||||
public interface ODataRetrieveRequest<V, T extends Format>
|
||||
extends ODataBasicRequest<ODataRetrieveResponse<V>, T>, ODataBatchableRequest {
|
||||
}
|
||||
|
|
|
@ -151,7 +151,8 @@ public class ODataBatchRequestImpl extends AbstractODataStreamedRequest<ODataBat
|
|||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public class BatchStreamManagerImpl extends AbstractODataStreamManager<ODataBatchResponse> {
|
||||
public class BatchStreamManagerImpl extends AbstractODataStreamManager<ODataBatchResponse>
|
||||
implements BatchStreamManager {
|
||||
|
||||
/**
|
||||
* Batch request current item.
|
||||
|
@ -178,6 +179,7 @@ public class ODataBatchRequestImpl extends AbstractODataStreamedRequest<ODataBat
|
|||
*
|
||||
* @return ODataChangeset instance.
|
||||
*/
|
||||
@Override
|
||||
public ODataChangeset addChangeset() {
|
||||
closeCurrentItem();
|
||||
|
||||
|
@ -197,6 +199,7 @@ public class ODataBatchRequestImpl extends AbstractODataStreamedRequest<ODataBat
|
|||
*
|
||||
* @return ODataRetrieve instance.
|
||||
*/
|
||||
@Override
|
||||
public ODataRetrieve addRetrieve() {
|
||||
closeCurrentItem();
|
||||
|
||||
|
|
|
@ -148,8 +148,7 @@ public class ODataBatchUtilities {
|
|||
}
|
||||
|
||||
} else {
|
||||
for (int i = 0;
|
||||
controller.isValidBatch() && controller.getBatchLineIterator().hasNext() && i < count; i++) {
|
||||
for (int i = 0; controller.isValidBatch() && controller.getBatchLineIterator().hasNext() && i < count; i++) {
|
||||
currentLine = controller.getBatchLineIterator().nextLine();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
|
@ -44,7 +43,7 @@ import org.apache.olingo.commons.api.data.Entry;
|
|||
*/
|
||||
public class ODataEntityCreateRequestImpl<E extends CommonODataEntity>
|
||||
extends AbstractODataBasicRequest<ODataEntityCreateResponse<E>, ODataPubFormat>
|
||||
implements ODataEntityCreateRequest<E>, ODataBatchableRequest {
|
||||
implements ODataEntityCreateRequest<E> {
|
||||
|
||||
/**
|
||||
* Entity to be created.
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
|
@ -39,11 +38,12 @@ import org.apache.olingo.commons.api.data.Entry;
|
|||
|
||||
/**
|
||||
* This class implements an OData update request.
|
||||
*
|
||||
* @param <E> concrete ODataEntity implementation
|
||||
*/
|
||||
public class ODataEntityUpdateRequestImpl<E extends CommonODataEntity>
|
||||
extends AbstractODataBasicRequest<ODataEntityUpdateResponse<E>, ODataPubFormat>
|
||||
implements ODataEntityUpdateRequest<E>, ODataBatchableRequest {
|
||||
implements ODataEntityUpdateRequest<E> {
|
||||
|
||||
/**
|
||||
* Changes to be applied.
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.net.URI;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.commons.api.format.Format;
|
||||
|
@ -36,7 +35,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
|
|||
*/
|
||||
public abstract class AbstractODataRetrieveRequest<V, T extends Format>
|
||||
extends AbstractODataBasicRequest<ODataRetrieveResponse<V>, T>
|
||||
implements ODataRetrieveRequest<V, T>, ODataBatchableRequest {
|
||||
implements ODataRetrieveRequest<V, T> {
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
|
|
|
@ -18,389 +18,429 @@
|
|||
*/
|
||||
package org.apache.olingo.client.core.it.v3;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.olingo.client.api.ODataBatchConstants;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.BatchStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataRetrieve;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
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.ODataEntityUpdateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.client.api.uri.v3.URIBuilder;
|
||||
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.batch.ODataChangesetResponseItem;
|
||||
import org.apache.olingo.client.core.communication.request.batch.ODataRetrieveResponseItem;
|
||||
import org.apache.olingo.client.core.communication.request.retrieve.ODataEntityRequestImpl;
|
||||
import org.apache.olingo.client.core.communication.request.retrieve.ODataEntityRequestImpl.ODataEntityResponseImpl;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
import org.apache.olingo.commons.api.domain.v3.ODataEntity;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BatchTestITCase extends AbstractTestITCase {
|
||||
|
||||
// private static String PREFIX = "!!PREFIX!!";
|
||||
//
|
||||
// private static String SUFFIX = "!!SUFFIX!!";
|
||||
//
|
||||
// private static int MAX = 10000;
|
||||
//
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void stringStreaming() {
|
||||
// final TestStreamManager streaming = new TestStreamManager();
|
||||
//
|
||||
// new StreamingThread(streaming).start();
|
||||
//
|
||||
// streaming.addObject((PREFIX + "\n").getBytes());
|
||||
//
|
||||
// for (int i = 0; i <= MAX; i++) {
|
||||
// streaming.addObject((i + ") send info\n").getBytes());
|
||||
// }
|
||||
//
|
||||
// streaming.addObject((SUFFIX).getBytes());
|
||||
// streaming.finalizeBody();
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void emptyBatchRequest() {
|
||||
// // create your request
|
||||
// final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
//
|
||||
// final BatchStreamManager payload = request.execute();
|
||||
// final ODataBatchResponse response = payload.getResponse();
|
||||
//
|
||||
// assertEquals(202, response.getStatusCode());
|
||||
// assertEquals("Accepted", response.getStatusMessage());
|
||||
//
|
||||
// final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
// assertFalse(iter.hasNext());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void changesetWithError() {
|
||||
// // create your request
|
||||
// final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
//
|
||||
// final BatchStreamManager payload = request.execute();
|
||||
// final ODataChangeset changeset = payload.addChangeset();
|
||||
//
|
||||
// URIBuilder<?> targetURI;
|
||||
// ODataEntityCreateRequest createReq;
|
||||
//
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
// for (int i = 1; i <= 2; i++) {
|
||||
// // Create Customer into the changeset
|
||||
// createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
// targetURI.build(),
|
||||
// getSampleCustomerProfile(100 + i, "Sample customer", false));
|
||||
// createReq.setFormat(ODataPubFormat.JSON);
|
||||
// changeset.addRequest(createReq);
|
||||
// }
|
||||
//
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("WrongEntitySet");
|
||||
// createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
// targetURI.build(),
|
||||
// getSampleCustomerProfile(105, "Sample customer", false));
|
||||
// createReq.setFormat(ODataPubFormat.JSON);
|
||||
// changeset.addRequest(createReq);
|
||||
//
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
// for (int i = 3; i <= 4; i++) {
|
||||
// // Create Customer into the changeset
|
||||
// createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
// targetURI.build(),
|
||||
// getSampleCustomerProfile(100 + i, "Sample customer", false));
|
||||
// createReq.setFormat(ODataPubFormat.ATOM);
|
||||
// changeset.addRequest(createReq);
|
||||
// }
|
||||
//
|
||||
// final ODataBatchResponse response = payload.getResponse();
|
||||
// assertEquals(202, response.getStatusCode());
|
||||
// assertEquals("Accepted", response.getStatusMessage());
|
||||
//
|
||||
// final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
// final ODataChangesetResponseItem chgResponseItem = (ODataChangesetResponseItem) iter.next();
|
||||
//
|
||||
// final ODataResponse res = chgResponseItem.next();
|
||||
// assertEquals(404, res.getStatusCode());
|
||||
// assertEquals("Not Found", res.getStatusMessage());
|
||||
// assertEquals(Integer.valueOf(3), Integer.valueOf(
|
||||
// res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next()));
|
||||
// assertFalse(chgResponseItem.hasNext());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void changesetWithReference() {
|
||||
// // create your request
|
||||
// final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
// final BatchStreamManager streamManager = request.execute();
|
||||
//
|
||||
// final ODataChangeset changeset = streamManager.addChangeset();
|
||||
// ODataEntity customer = getSampleCustomerProfile(20, "sample customer", false);
|
||||
//
|
||||
// URIBuilder<?> uriBuilder = client.getURIBuilder(testAuthServiceRootURL).appendEntitySetSegment("Customer");
|
||||
//
|
||||
// // add create request
|
||||
// final ODataEntityCreateRequest createReq =
|
||||
// client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), customer);
|
||||
//
|
||||
// changeset.addRequest(createReq);
|
||||
//
|
||||
// // retrieve request reference
|
||||
// int createRequestRef = changeset.getLastContentId();
|
||||
//
|
||||
// // add update request: link CustomerInfo(17) to the new customer
|
||||
// final ODataEntity customerChanges = client.getObjectFactory().newEntity(customer.getName());
|
||||
// customerChanges.addLink(client.getObjectFactory().newEntityNavigationLink(
|
||||
// "Info",
|
||||
// client.getURIBuilder(testAuthServiceRootURL).appendEntitySetSegment("CustomerInfo").
|
||||
// appendKeySegment(17).build()));
|
||||
//
|
||||
// final ODataEntityUpdateRequest updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||
// URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);
|
||||
//
|
||||
// changeset.addRequest(updateReq);
|
||||
//
|
||||
// final ODataBatchResponse response = streamManager.getResponse();
|
||||
// assertEquals(202, response.getStatusCode());
|
||||
// assertEquals("Accepted", response.getStatusMessage());
|
||||
//
|
||||
// // verify response payload ...
|
||||
// final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
//
|
||||
// final ODataBatchResponseItem item = iter.next();
|
||||
// assertTrue(item instanceof ODataChangesetResponseItem);
|
||||
//
|
||||
// final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item;
|
||||
//
|
||||
// ODataResponse res = chgitem.next();
|
||||
// assertEquals(201, res.getStatusCode());
|
||||
// assertTrue(res instanceof ODataEntityCreateResponse);
|
||||
//
|
||||
// customer = ((ODataEntityCreateResponse) res).getBody();
|
||||
//
|
||||
// ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(
|
||||
// URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString() + "/Info"));
|
||||
//
|
||||
// assertEquals(Integer.valueOf(17),
|
||||
// req.execute().getBody().getProperty("CustomerInfoId").getPrimitiveValue().<Integer>toCastValue());
|
||||
//
|
||||
// res = chgitem.next();
|
||||
// assertEquals(204, res.getStatusCode());
|
||||
// assertTrue(res instanceof ODataEntityUpdateResponse);
|
||||
//
|
||||
// // clean ...
|
||||
// assertEquals(204, client.getCUDRequestFactory().getDeleteRequest(
|
||||
// URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString())).execute().
|
||||
// getStatusCode());
|
||||
//
|
||||
// try {
|
||||
// client.getRetrieveRequestFactory().getEntityRequest(
|
||||
// URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString())).
|
||||
// execute().getBody();
|
||||
// fail();
|
||||
// } catch (Exception e) {
|
||||
// // ignore
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void batchRequest() {
|
||||
// // create your request
|
||||
// final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
//
|
||||
// final BatchStreamManager streamManager = request.execute();
|
||||
//
|
||||
// // -------------------------------------------
|
||||
// // Add retrieve item
|
||||
// // -------------------------------------------
|
||||
// ODataRetrieve retrieve = streamManager.addRetrieve();
|
||||
//
|
||||
// // prepare URI
|
||||
// URIBuilder<?> targetURI = client.getURIBuilder(testStaticServiceRootURL);
|
||||
// targetURI.appendEntitySetSegment("Customer").appendKeySegment(-10).
|
||||
// expand("Logins").select("CustomerId,Logins/Username");
|
||||
//
|
||||
// // create new request
|
||||
// ODataEntityRequest queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
// queryReq.setFormat(ODataPubFormat.ATOM);
|
||||
//
|
||||
// retrieve.setRequest(queryReq);
|
||||
// // -------------------------------------------
|
||||
//
|
||||
// // -------------------------------------------
|
||||
// // Add changeset item
|
||||
// // -------------------------------------------
|
||||
// final ODataChangeset changeset = streamManager.addChangeset();
|
||||
//
|
||||
// // Update Product into the changeset
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).
|
||||
// appendEntitySetSegment("Product").appendKeySegment(-10);
|
||||
// final URI editLink = targetURI.build();
|
||||
//
|
||||
// final ODataEntity merge = client.getObjectFactory().newEntity(TEST_PRODUCT_TYPE);
|
||||
// merge.setEditLink(editLink);
|
||||
//
|
||||
// merge.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
|
||||
// "Description", client.getPrimitiveValueBuilder().setText("new description from batch").build()));
|
||||
//
|
||||
// final ODataEntityUpdateRequest changeReq =
|
||||
// client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.MERGE, merge);
|
||||
// changeReq.setFormat(ODataPubFormat.JSON_FULL_METADATA);
|
||||
// changeReq.setIfMatch(getETag(editLink));
|
||||
//
|
||||
// changeset.addRequest(changeReq);
|
||||
//
|
||||
// // Create Customer into the changeset
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
// final ODataEntity original = getSampleCustomerProfile(1000, "Sample customer", false);
|
||||
// final ODataEntityCreateRequest createReq =
|
||||
// client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
||||
// createReq.setFormat(ODataPubFormat.ATOM);
|
||||
// changeset.addRequest(createReq);
|
||||
// // -------------------------------------------
|
||||
//
|
||||
// // -------------------------------------------
|
||||
// // Add retrieve item
|
||||
// // -------------------------------------------
|
||||
// retrieve = streamManager.addRetrieve();
|
||||
//
|
||||
// // prepare URI
|
||||
// targetURI = client.getURIBuilder(testStaticServiceRootURL).
|
||||
// appendEntitySetSegment("Product").appendKeySegment(-10);
|
||||
//
|
||||
// // create new request
|
||||
// queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
//
|
||||
// retrieve.setRequest(queryReq);
|
||||
// // -------------------------------------------
|
||||
//
|
||||
// final ODataBatchResponse response = streamManager.getResponse();
|
||||
// assertEquals(202, response.getStatusCode());
|
||||
// assertEquals("Accepted", response.getStatusMessage());
|
||||
//
|
||||
// final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
//
|
||||
// // retrive the first item (ODataRetrieve)
|
||||
// ODataBatchResponseItem item = iter.next();
|
||||
// assertTrue(item instanceof ODataRetrieveResponseItem);
|
||||
//
|
||||
// ODataRetrieveResponseItem retitem = (ODataRetrieveResponseItem) item;
|
||||
// ODataResponse res = retitem.next();
|
||||
// assertTrue(res instanceof ODataEntityResponseImpl);
|
||||
// assertEquals(200, res.getStatusCode());
|
||||
// assertEquals("OK", res.getStatusMessage());
|
||||
//
|
||||
// ODataEntityResponseImpl entres = (ODataEntityResponseImpl) res;
|
||||
// ODataEntity entity = entres.getBody();
|
||||
// assertEquals(new Integer(-10), entity.getProperty("CustomerId").getPrimitiveValue().<Integer>toCastValue());
|
||||
//
|
||||
// // retrieve the second item (ODataChangeset)
|
||||
// item = iter.next();
|
||||
// assertTrue(item instanceof ODataChangesetResponseItem);
|
||||
//
|
||||
// final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item;
|
||||
// res = chgitem.next();
|
||||
// assertTrue(res instanceof ODataEntityUpdateResponse);
|
||||
// assertEquals(204, res.getStatusCode());
|
||||
// assertEquals("No Content", res.getStatusMessage());
|
||||
//
|
||||
// res = chgitem.next();
|
||||
// assertTrue(res instanceof ODataEntityCreateResponse);
|
||||
// assertEquals(201, res.getStatusCode());
|
||||
// assertEquals("Created", res.getStatusMessage());
|
||||
//
|
||||
// final ODataEntityCreateResponse createres = (ODataEntityCreateResponse) res;
|
||||
// entity = createres.getBody();
|
||||
// assertEquals(new Integer(1000), entity.getProperty("CustomerId").getPrimitiveValue().<Integer>toCastValue());
|
||||
//
|
||||
// // retrive the third item (ODataRetrieve)
|
||||
// item = iter.next();
|
||||
// assertTrue(item instanceof ODataRetrieveResponseItem);
|
||||
//
|
||||
// retitem = (ODataRetrieveResponseItem) item;
|
||||
// res = retitem.next();
|
||||
// assertTrue(res instanceof ODataEntityResponseImpl);
|
||||
// assertEquals(200, res.getStatusCode());
|
||||
// assertEquals("OK", res.getStatusMessage());
|
||||
//
|
||||
// entres = (ODataEntityResponseImpl) res;
|
||||
// entity = entres.getBody();
|
||||
// assertEquals("new description from batch",
|
||||
// entity.getProperty("Description").getPrimitiveValue().<String>toCastValue());
|
||||
//
|
||||
// assertFalse(iter.hasNext());
|
||||
// }
|
||||
//
|
||||
// private static class TestStreamManager extends AbstractODataStreamManager<ODataBatchResponse> {
|
||||
//
|
||||
// public TestStreamManager() {
|
||||
// super(new Wrapper<Future<HttpResponse>>());
|
||||
// }
|
||||
//
|
||||
// public ODataStreamManager<ODataBatchResponse> addObject(byte[] src) {
|
||||
// stream(src);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected ODataBatchResponse getResponse(long timeout, TimeUnit unit) {
|
||||
// throw new UnsupportedOperationException("Not supported yet.");
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// /**
|
||||
// * To be used for debug purposes.
|
||||
// */
|
||||
// private static class StreamingThread extends Thread {
|
||||
//
|
||||
// private final TestStreamManager streaming;
|
||||
//
|
||||
// public StreamingThread(final TestStreamManager streaming) {
|
||||
// this.streaming = streaming;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// try {
|
||||
// final StringBuilder builder = new StringBuilder();
|
||||
//
|
||||
// byte[] buff = new byte[1024];
|
||||
//
|
||||
// int len;
|
||||
//
|
||||
// while ((len = streaming.getBody().read(buff)) >= 0) {
|
||||
// builder.append(new String(buff, 0, len));
|
||||
// }
|
||||
//
|
||||
// assertTrue(builder.toString().startsWith(PREFIX));
|
||||
// assertTrue(builder.toString().contains((MAX / 2) + ") send info"));
|
||||
// assertTrue(builder.toString().contains((MAX / 3) + ") send info"));
|
||||
// assertTrue(builder.toString().contains((MAX / 20) + ") send info"));
|
||||
// assertTrue(builder.toString().contains((MAX / 30) + ") send info"));
|
||||
// assertTrue(builder.toString().contains(MAX + ") send info"));
|
||||
// assertTrue(builder.toString().endsWith(SUFFIX));
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// fail();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static class BatchStreamingThread extends Thread {
|
||||
//
|
||||
// private final BatchStreamManager streaming;
|
||||
//
|
||||
// public BatchStreamingThread(final BatchStreamManager streaming) {
|
||||
// this.streaming = streaming;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// try {
|
||||
// final StringBuilder builder = new StringBuilder();
|
||||
//
|
||||
// byte[] buff = new byte[1024];
|
||||
//
|
||||
// int len;
|
||||
//
|
||||
// while ((len = streaming.getBody().read(buff)) >= 0) {
|
||||
// builder.append(new String(buff, 0, len));
|
||||
// }
|
||||
//
|
||||
// LOG.debug("Batch request {}", builder.toString());
|
||||
//
|
||||
// assertTrue(builder.toString().contains("Content-Id:2"));
|
||||
// assertTrue(builder.toString().contains("GET " + servicesODataServiceRootURL));
|
||||
// } catch (IOException e) {
|
||||
// fail();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
private static String PREFIX = "!!PREFIX!!";
|
||||
|
||||
private static String SUFFIX = "!!SUFFIX!!";
|
||||
|
||||
private static int MAX = 10000;
|
||||
|
||||
@Test
|
||||
public void stringStreaming() {
|
||||
final TestStreamManager streaming = new TestStreamManager();
|
||||
|
||||
new StreamingThread(streaming).start();
|
||||
|
||||
streaming.addObject((PREFIX + "\n").getBytes());
|
||||
|
||||
for (int i = 0; i <= MAX; i++) {
|
||||
streaming.addObject((i + ") send info\n").getBytes());
|
||||
}
|
||||
|
||||
streaming.addObject((SUFFIX).getBytes());
|
||||
streaming.finalizeBody();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyBatchRequest() {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
|
||||
final BatchStreamManager payload = request.execute();
|
||||
final ODataBatchResponse response = payload.getResponse();
|
||||
|
||||
assertEquals(202, response.getStatusCode());
|
||||
assertEquals("Accepted", response.getStatusMessage());
|
||||
|
||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changesetWithError() {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
|
||||
final BatchStreamManager payload = request.execute();
|
||||
final ODataChangeset changeset = payload.addChangeset();
|
||||
|
||||
URIBuilder targetURI;
|
||||
ODataEntityCreateRequest<ODataEntity> createReq;
|
||||
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
// Create Customer into the changeset
|
||||
createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
targetURI.build(),
|
||||
getSampleCustomerProfile(100 + i, "Sample customer", false));
|
||||
createReq.setFormat(ODataPubFormat.JSON);
|
||||
changeset.addRequest(createReq);
|
||||
}
|
||||
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("WrongEntitySet");
|
||||
createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
targetURI.build(),
|
||||
getSampleCustomerProfile(105, "Sample customer", false));
|
||||
createReq.setFormat(ODataPubFormat.JSON);
|
||||
changeset.addRequest(createReq);
|
||||
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
for (int i = 3; i <= 4; i++) {
|
||||
// Create Customer into the changeset
|
||||
createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
targetURI.build(),
|
||||
getSampleCustomerProfile(100 + i, "Sample customer", false));
|
||||
createReq.setFormat(ODataPubFormat.ATOM);
|
||||
changeset.addRequest(createReq);
|
||||
}
|
||||
|
||||
final ODataBatchResponse response = payload.getResponse();
|
||||
assertEquals(202, response.getStatusCode());
|
||||
assertEquals("Accepted", response.getStatusMessage());
|
||||
|
||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
final ODataChangesetResponseItem chgResponseItem = (ODataChangesetResponseItem) iter.next();
|
||||
|
||||
final ODataResponse res = chgResponseItem.next();
|
||||
assertEquals(404, res.getStatusCode());
|
||||
assertEquals("Not Found", res.getStatusMessage());
|
||||
assertEquals(Integer.valueOf(3), Integer.valueOf(
|
||||
res.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next()));
|
||||
assertFalse(chgResponseItem.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
@SuppressWarnings("unchecked")
|
||||
public void changesetWithReference() throws EdmPrimitiveTypeException {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
final BatchStreamManager streamManager = request.execute();
|
||||
|
||||
final ODataChangeset changeset = streamManager.addChangeset();
|
||||
ODataEntity customer = getSampleCustomerProfile(20, "sample customer", false);
|
||||
|
||||
URIBuilder uriBuilder = client.getURIBuilder(testAuthServiceRootURL).appendEntitySetSegment("Customer");
|
||||
|
||||
// add create request
|
||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||
client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), customer);
|
||||
|
||||
changeset.addRequest(createReq);
|
||||
|
||||
// retrieve request reference
|
||||
int createRequestRef = changeset.getLastContentId();
|
||||
|
||||
// add update request: link CustomerInfo(17) to the new customer
|
||||
final ODataEntity customerChanges = client.getObjectFactory().newEntity(customer.getTypeName());
|
||||
customerChanges.addLink(client.getObjectFactory().newEntityNavigationLink(
|
||||
"Info",
|
||||
client.getURIBuilder(testAuthServiceRootURL).appendEntitySetSegment("CustomerInfo").
|
||||
appendKeySegment(17).build()));
|
||||
|
||||
final ODataEntityUpdateRequest updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||
URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);
|
||||
|
||||
changeset.addRequest(updateReq);
|
||||
|
||||
final ODataBatchResponse response = streamManager.getResponse();
|
||||
assertEquals(202, response.getStatusCode());
|
||||
assertEquals("Accepted", response.getStatusMessage());
|
||||
|
||||
// verify response payload ...
|
||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
|
||||
final ODataBatchResponseItem item = iter.next();
|
||||
assertTrue(item instanceof ODataChangesetResponseItem);
|
||||
|
||||
final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item;
|
||||
|
||||
ODataResponse res = chgitem.next();
|
||||
assertEquals(201, res.getStatusCode());
|
||||
assertTrue(res instanceof ODataEntityCreateResponse);
|
||||
|
||||
customer = ((ODataEntityCreateResponse<ODataEntity>) res).getBody();
|
||||
|
||||
ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(
|
||||
URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString() + "/Info"));
|
||||
|
||||
assertEquals(Integer.valueOf(17),
|
||||
req.execute().getBody().getProperty("CustomerInfoId").getPrimitiveValue().toCastValue(Integer.class));
|
||||
|
||||
res = chgitem.next();
|
||||
assertEquals(204, res.getStatusCode());
|
||||
assertTrue(res instanceof ODataEntityUpdateResponse);
|
||||
|
||||
// clean ...
|
||||
assertEquals(204, client.getCUDRequestFactory().getDeleteRequest(
|
||||
URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString())).execute().
|
||||
getStatusCode());
|
||||
|
||||
try {
|
||||
client.getRetrieveRequestFactory().getEntityRequest(
|
||||
URIUtils.getURI(testStaticServiceRootURL, customer.getEditLink().toASCIIString())).
|
||||
execute().getBody();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void batchRequest() throws EdmPrimitiveTypeException {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
|
||||
final BatchStreamManager streamManager = request.execute();
|
||||
|
||||
// -------------------------------------------
|
||||
// Add retrieve item
|
||||
// -------------------------------------------
|
||||
ODataRetrieve retrieve = streamManager.addRetrieve();
|
||||
|
||||
// prepare URI
|
||||
URIBuilder targetURI = client.getURIBuilder(testStaticServiceRootURL);
|
||||
targetURI.appendEntitySetSegment("Customer").appendKeySegment(-10).
|
||||
expand("Logins").select("CustomerId,Logins/Username");
|
||||
|
||||
// create new request
|
||||
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
queryReq.setFormat(ODataPubFormat.ATOM);
|
||||
|
||||
retrieve.setRequest(queryReq);
|
||||
// -------------------------------------------
|
||||
|
||||
// -------------------------------------------
|
||||
// Add changeset item
|
||||
// -------------------------------------------
|
||||
final ODataChangeset changeset = streamManager.addChangeset();
|
||||
|
||||
// Update Product into the changeset
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("Product").appendKeySegment(-10);
|
||||
final URI editLink = targetURI.build();
|
||||
|
||||
final ODataEntity merge = client.getObjectFactory().newEntity(TEST_PRODUCT_TYPE);
|
||||
merge.setEditLink(editLink);
|
||||
|
||||
merge.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
|
||||
"Description",
|
||||
client.getObjectFactory().newPrimitiveValueBuilder().buildString("new description from batch")));
|
||||
|
||||
final ODataEntityUpdateRequest changeReq =
|
||||
client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.MERGE, merge);
|
||||
changeReq.setFormat(ODataPubFormat.JSON_FULL_METADATA);
|
||||
changeReq.setIfMatch(getETag(editLink));
|
||||
|
||||
changeset.addRequest(changeReq);
|
||||
|
||||
// Create Customer into the changeset
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customer");
|
||||
final ODataEntity original = getSampleCustomerProfile(1000, "Sample customer", false);
|
||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
||||
createReq.setFormat(ODataPubFormat.ATOM);
|
||||
changeset.addRequest(createReq);
|
||||
// -------------------------------------------
|
||||
|
||||
// -------------------------------------------
|
||||
// Add retrieve item
|
||||
// -------------------------------------------
|
||||
retrieve = streamManager.addRetrieve();
|
||||
|
||||
// prepare URI
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("Product").appendKeySegment(-10);
|
||||
|
||||
// create new request
|
||||
queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
|
||||
retrieve.setRequest(queryReq);
|
||||
// -------------------------------------------
|
||||
|
||||
final ODataBatchResponse response = streamManager.getResponse();
|
||||
assertEquals(202, response.getStatusCode());
|
||||
assertEquals("Accepted", response.getStatusMessage());
|
||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
|
||||
// retrive the first item (ODataRetrieve)
|
||||
ODataBatchResponseItem item = iter.next();
|
||||
assertTrue(item instanceof ODataRetrieveResponseItem);
|
||||
|
||||
ODataRetrieveResponseItem retitem = (ODataRetrieveResponseItem) item;
|
||||
ODataResponse res = retitem.next();
|
||||
assertTrue(res instanceof ODataEntityResponseImpl);
|
||||
assertEquals(200, res.getStatusCode());
|
||||
assertEquals("OK", res.getStatusMessage());
|
||||
|
||||
ODataEntityRequestImpl<ODataEntity>.ODataEntityResponseImpl entres =
|
||||
(ODataEntityRequestImpl<ODataEntity>.ODataEntityResponseImpl) res;
|
||||
|
||||
ODataEntity entity = entres.getBody();
|
||||
assertEquals(new Integer(-10), entity.getProperty("CustomerId").getPrimitiveValue().toCastValue(Integer.class));
|
||||
|
||||
// retrieve the second item (ODataChangeset)
|
||||
item = iter.next();
|
||||
assertTrue(item instanceof ODataChangesetResponseItem);
|
||||
|
||||
final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item;
|
||||
res = chgitem.next();
|
||||
assertTrue(res instanceof ODataEntityUpdateResponse);
|
||||
assertEquals(204, res.getStatusCode());
|
||||
assertEquals("No Content", res.getStatusMessage());
|
||||
|
||||
res = chgitem.next();
|
||||
assertTrue(res instanceof ODataEntityCreateResponse);
|
||||
assertEquals(201, res.getStatusCode());
|
||||
assertEquals("Created", res.getStatusMessage());
|
||||
|
||||
final ODataEntityCreateResponse<ODataEntity> createres = (ODataEntityCreateResponse<ODataEntity>) res;
|
||||
entity = createres.getBody();
|
||||
assertEquals(new Integer(1000), entity.getProperty("CustomerId").getPrimitiveValue().toCastValue(Integer.class));
|
||||
|
||||
// retrive the third item (ODataRetrieve)
|
||||
item = iter.next();
|
||||
assertTrue(item instanceof ODataRetrieveResponseItem);
|
||||
|
||||
retitem = (ODataRetrieveResponseItem) item;
|
||||
res = retitem.next();
|
||||
assertTrue(res instanceof ODataEntityResponseImpl);
|
||||
assertEquals(200, res.getStatusCode());
|
||||
assertEquals("OK", res.getStatusMessage());
|
||||
|
||||
entres = (ODataEntityRequestImpl<ODataEntity>.ODataEntityResponseImpl) res;
|
||||
entity = entres.getBody();
|
||||
assertEquals("new description from batch",
|
||||
entity.getProperty("Description").getPrimitiveValue().toCastValue(String.class));
|
||||
|
||||
assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
private static class TestStreamManager extends AbstractODataStreamManager<ODataBatchResponse> {
|
||||
|
||||
public TestStreamManager() {
|
||||
super(new Wrapper<Future<HttpResponse>>());
|
||||
}
|
||||
|
||||
public ODataStreamManager<ODataBatchResponse> addObject(byte[] src) {
|
||||
stream(src);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataBatchResponse getResponse(long timeout, TimeUnit unit) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* To be used for debug purposes.
|
||||
*/
|
||||
private static class StreamingThread extends Thread {
|
||||
|
||||
private final TestStreamManager streaming;
|
||||
|
||||
public StreamingThread(final TestStreamManager streaming) {
|
||||
this.streaming = streaming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
byte[] buff = new byte[1024];
|
||||
|
||||
int len;
|
||||
|
||||
while ((len = streaming.getBody().read(buff)) >= 0) {
|
||||
builder.append(new String(buff, 0, len));
|
||||
}
|
||||
|
||||
assertTrue(builder.toString().startsWith(PREFIX));
|
||||
assertTrue(builder.toString().contains((MAX / 2) + ") send info"));
|
||||
assertTrue(builder.toString().contains((MAX / 3) + ") send info"));
|
||||
assertTrue(builder.toString().contains((MAX / 20) + ") send info"));
|
||||
assertTrue(builder.toString().contains((MAX / 30) + ") send info"));
|
||||
assertTrue(builder.toString().contains(MAX + ") send info"));
|
||||
assertTrue(builder.toString().endsWith(SUFFIX));
|
||||
|
||||
} catch (IOException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BatchStreamingThread extends Thread {
|
||||
|
||||
private final BatchStreamManager streaming;
|
||||
|
||||
public BatchStreamingThread(final BatchStreamManager streaming) {
|
||||
this.streaming = streaming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
byte[] buff = new byte[1024];
|
||||
|
||||
int len;
|
||||
|
||||
while ((len = streaming.getBody().read(buff)) >= 0) {
|
||||
builder.append(new String(buff, 0, len));
|
||||
}
|
||||
|
||||
LOG.debug("Batch request {}", builder.toString());
|
||||
|
||||
assertTrue(builder.toString().contains("Content-Id:2"));
|
||||
assertTrue(builder.toString().contains("GET " + testStaticServiceRootURL));
|
||||
} catch (IOException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue