[OLINGO-175, OLINGO-205, OLINGO-246] provided v4 batch test including outside update; still missing asyncronous execution
This commit is contained in:
parent
6dfdee2ef2
commit
9fa8fbc31f
|
@ -38,12 +38,10 @@ 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;
|
||||
|
@ -118,7 +116,7 @@ public abstract class AbstractServices {
|
|||
|
||||
private static final Pattern BATCH_REQUEST_REF_PATTERN = Pattern.compile("(.*) ([$].*) HTTP/.*");
|
||||
|
||||
private static final String BOUNDARY = "batch_243234_25424_ef_892u748";
|
||||
protected static final String BOUNDARY = "batch_243234_25424_ef_892u748";
|
||||
|
||||
protected final ODataServiceVersion version;
|
||||
|
||||
|
@ -205,16 +203,16 @@ public abstract class AbstractServices {
|
|||
|
||||
@POST
|
||||
@Path("/$batch")
|
||||
@Consumes("multipart/mixed")
|
||||
@Produces("application/octet-stream; boundary=" + BOUNDARY)
|
||||
@Consumes(ContentType.MULTIPART_MIXED)
|
||||
@Produces(ContentType.APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY)
|
||||
public Response batch(
|
||||
@HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
|
||||
final @Multipart MultipartBody attachment) {
|
||||
try {
|
||||
final boolean continueOnError = prefer.contains("odata.continue-on-error");
|
||||
|
||||
|
||||
return xml.createBatchResponse(
|
||||
exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError),
|
||||
exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError),
|
||||
BOUNDARY);
|
||||
} catch (IOException e) {
|
||||
return xml.createFaultResponse(Accept.XML.toString(version), e);
|
||||
|
@ -244,6 +242,8 @@ public abstract class AbstractServices {
|
|||
headers.putSingle(header.getName(), header.getValue());
|
||||
}
|
||||
|
||||
final Response res;
|
||||
|
||||
if (matcher.find()) {
|
||||
String method = matcher.group(1);
|
||||
if ("PATCH".equals(method) || "MERGE".equals(method)) {
|
||||
|
@ -255,8 +255,8 @@ public abstract class AbstractServices {
|
|||
|
||||
final WebClient client = WebClient.create(url);
|
||||
client.headers(headers);
|
||||
|
||||
return client.invoke(method, body.getDataHandler().getInputStream());
|
||||
res = client.invoke(method, body.getDataHandler().getInputStream());
|
||||
client.close();
|
||||
} else if (matcherRef.find()) {
|
||||
String method = matcherRef.group(1);
|
||||
if ("PATCH".equals(method) || "MERGE".equals(method)) {
|
||||
|
@ -269,14 +269,17 @@ public abstract class AbstractServices {
|
|||
final WebClient client = WebClient.create(references.get(url));
|
||||
client.headers(headers);
|
||||
|
||||
return client.invoke(method, body.getDataHandler().getInputStream());
|
||||
res = client.invoke(method, body.getDataHandler().getInputStream());
|
||||
client.close();
|
||||
} else {
|
||||
return null;
|
||||
res = null;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
protected abstract InputStream exploreMultipart(
|
||||
final List<Attachment> attachments, final String boundary, final boolean continueOnError)
|
||||
final List<Attachment> attachments, final String boundary, final boolean continueOnError)
|
||||
throws IOException;
|
||||
|
||||
protected void addItemIntro(final ByteArrayOutputStream bos) throws IOException {
|
||||
|
@ -417,7 +420,7 @@ public abstract class AbstractServices {
|
|||
} else {
|
||||
final Container<JSONEntryImpl> jcont =
|
||||
mapper.readValue(IOUtils.toInputStream(changes), new TypeReference<JSONEntryImpl>() {
|
||||
});
|
||||
});
|
||||
|
||||
entryChanges = dataBinder.getAtomEntry(jcont.getObject());
|
||||
}
|
||||
|
@ -555,7 +558,6 @@ public abstract class AbstractServices {
|
|||
@HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
|
||||
@PathParam("entitySetName") String entitySetName,
|
||||
final String entity) {
|
||||
|
||||
// default
|
||||
AbstractUtilities utils = xml;
|
||||
try {
|
||||
|
@ -608,7 +610,7 @@ public abstract class AbstractServices {
|
|||
} else {
|
||||
final Container<JSONEntryImpl> jcontainer =
|
||||
mapper.readValue(IOUtils.toInputStream(entity), new TypeReference<JSONEntryImpl>() {
|
||||
});
|
||||
});
|
||||
|
||||
entry = dataBinder.getAtomEntry(jcontainer.getObject());
|
||||
|
||||
|
@ -635,7 +637,7 @@ public abstract class AbstractServices {
|
|||
Container<AtomEntryImpl> result = atomDeserializer.read(serialization, AtomEntryImpl.class);
|
||||
result = new Container<AtomEntryImpl>(
|
||||
URI.create(Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL)
|
||||
+ "$metadata#" + entitySetName + "/$entity"), null, result.getObject());
|
||||
+ "$metadata#" + entitySetName + "/$entity"), null, result.getObject());
|
||||
|
||||
final String path = Commons.getEntityBasePath(entitySetName, entityKey);
|
||||
FSManager.instance(version).putInMemory(
|
||||
|
@ -697,13 +699,13 @@ public abstract class AbstractServices {
|
|||
replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,").
|
||||
replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\"").
|
||||
replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>.*\\</d:Salary\\>",
|
||||
"<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
|
||||
"<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
|
||||
replaceAll("\\<d:Title\\>.*\\</d:Title\\>", "<d:Title>[Sacked]</d:Title>");
|
||||
|
||||
final FSManager fsManager = FSManager.instance(version);
|
||||
fsManager.putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
|
||||
fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
|
||||
ConstantKey.ENTITY), utils.getKey()));
|
||||
ConstantKey.ENTITY), utils.getKey()));
|
||||
|
||||
return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
|
||||
} catch (Exception e) {
|
||||
|
@ -755,9 +757,9 @@ public abstract class AbstractServices {
|
|||
final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
|
||||
newContent = newContent.
|
||||
replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
|
||||
"\"Salary\":" + newSalary + ",").
|
||||
"\"Salary\":" + newSalary + ",").
|
||||
replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
|
||||
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
|
||||
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
|
||||
}
|
||||
|
||||
FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
|
||||
|
@ -887,7 +889,7 @@ public abstract class AbstractServices {
|
|||
} else {
|
||||
mapper.writeValue(
|
||||
writer, new JsonFeedContainer<JSONFeedImpl>(container.getContextURL(), container.getMetadataETag(),
|
||||
dataBinder.getJsonFeed(container.getObject())));
|
||||
dataBinder.getJsonFeed(container.getObject())));
|
||||
}
|
||||
|
||||
return xml.createResponse(
|
||||
|
@ -1502,8 +1504,8 @@ public abstract class AbstractServices {
|
|||
mapper.writeValue(
|
||||
writer,
|
||||
new JsonFeedContainer<JSONFeedImpl>(container.getContextURL(),
|
||||
container.getMetadataETag(),
|
||||
dataBinder.getJsonFeed((AtomFeedImpl) container.getObject())));
|
||||
container.getMetadataETag(),
|
||||
dataBinder.getJsonFeed((AtomFeedImpl) container.getObject())));
|
||||
}
|
||||
} else {
|
||||
final Container<Entry> container = atomDeserializer.<Entry, AtomEntryImpl>read(stream, AtomEntryImpl.class);
|
||||
|
@ -1515,8 +1517,8 @@ public abstract class AbstractServices {
|
|||
mapper.writeValue(
|
||||
writer,
|
||||
new JsonEntryContainer<JSONEntryImpl>(container.getContextURL(),
|
||||
container.getMetadataETag(),
|
||||
dataBinder.getJsonEntry((AtomEntryImpl) container.getObject())));
|
||||
container.getMetadataETag(),
|
||||
dataBinder.getJsonEntry((AtomEntryImpl) container.getObject())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ public class V4Services extends AbstractServices {
|
|||
|
||||
return utils.getValue().createResponse(
|
||||
FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
|
||||
+ File.separatorChar + filename, utils.getKey()),
|
||||
+ File.separatorChar + filename, utils.getKey()),
|
||||
null,
|
||||
utils.getKey());
|
||||
} catch (Exception e) {
|
||||
|
@ -218,7 +218,7 @@ public class V4Services extends AbstractServices {
|
|||
|
||||
final Response response =
|
||||
getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
|
||||
accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false);
|
||||
accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false);
|
||||
return response.getStatus() >= 400
|
||||
? postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes)
|
||||
: super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
|
||||
|
@ -242,7 +242,7 @@ public class V4Services extends AbstractServices {
|
|||
return postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, entityId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private StringBuilder containedPath(final String entityId, final String containedEntitySetName) {
|
||||
return new StringBuilder("Accounts").append(File.separatorChar).
|
||||
append(entityId).append(File.separatorChar).
|
||||
|
@ -272,7 +272,7 @@ public class V4Services extends AbstractServices {
|
|||
|
||||
final InputStream entry = FSManager.instance(version).
|
||||
readFile(containedPath(entityId, containedEntitySetName).
|
||||
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
||||
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
||||
|
||||
final Container<AtomEntryImpl> container = atomDeserializer.read(entry, AtomEntryImpl.class);
|
||||
|
||||
|
@ -315,7 +315,7 @@ public class V4Services extends AbstractServices {
|
|||
} else {
|
||||
final Container<JSONEntryImpl> jcontainer =
|
||||
mapper.readValue(IOUtils.toInputStream(entity), new TypeReference<JSONEntryImpl>() {
|
||||
});
|
||||
});
|
||||
|
||||
entry = dataBinder.getAtomEntry(jcontainer.getObject());
|
||||
|
||||
|
@ -413,7 +413,7 @@ public class V4Services extends AbstractServices {
|
|||
|
||||
final Container<JSONEntryImpl> jsonContainer = mapper.readValue(IOUtils.toInputStream(changes),
|
||||
new TypeReference<JSONEntryImpl>() {
|
||||
});
|
||||
});
|
||||
jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString());
|
||||
entryChanges = dataBinder.getAtomEntry(jsonContainer.getObject());
|
||||
}
|
||||
|
@ -446,9 +446,9 @@ public class V4Services extends AbstractServices {
|
|||
// 1. Fetch the contained entity to be removed
|
||||
final InputStream entry = FSManager.instance(version).
|
||||
readFile(containedPath(entityId, containedEntitySetName).
|
||||
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
||||
append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
|
||||
final Container<AtomEntryImpl> container = atomDeserializer.read(entry, AtomEntryImpl.class);
|
||||
|
||||
|
||||
// 2. Remove the contained entity
|
||||
final String atomEntryRelativePath = containedPath(entityId, containedEntitySetName).
|
||||
append('(').append(containedEntityId).append(')').toString();
|
||||
|
@ -457,7 +457,7 @@ public class V4Services extends AbstractServices {
|
|||
// 3. Update the contained entity set
|
||||
final String atomFeedRelativePath = containedPath(entityId, containedEntitySetName).toString();
|
||||
final InputStream feedIS = FSManager.instance(version).readFile(atomFeedRelativePath, Accept.ATOM);
|
||||
final Container<AtomFeedImpl> feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class);
|
||||
final Container<AtomFeedImpl> feedContainer = atomDeserializer.read(feedIS, AtomFeedImpl.class);
|
||||
feedContainer.getObject().getEntries().remove(container.getObject());
|
||||
|
||||
final ByteArrayOutputStream content = new ByteArrayOutputStream();
|
||||
|
@ -510,7 +510,7 @@ public class V4Services extends AbstractServices {
|
|||
} else {
|
||||
mapper.writeValue(
|
||||
writer, new JsonFeedContainer<JSONFeedImpl>(container.getContextURL(), container.getMetadataETag(),
|
||||
dataBinder.getJsonFeed(container.getObject())));
|
||||
dataBinder.getJsonFeed(container.getObject())));
|
||||
}
|
||||
|
||||
return xml.createResponse(
|
||||
|
@ -522,5 +522,4 @@ public class V4Services extends AbstractServices {
|
|||
return xml.createFaultResponse(accept, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,6 @@ package org.apache.olingo.client.api;
|
|||
*/
|
||||
public class ODataBatchConstants {
|
||||
|
||||
/**
|
||||
* Batch/Changeset content type.
|
||||
*/
|
||||
public static final String MULTIPART_CONTENT_TYPE = "multipart/mixed";
|
||||
|
||||
/**
|
||||
* Batch item content type.
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.client.api.communication.request;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
|
||||
/**
|
||||
* Object request that can be sent embedded into a batch request.
|
||||
|
@ -32,7 +32,7 @@ public interface ODataBatchableRequest extends ODataRequest {
|
|||
*
|
||||
* @param req destination batch request.
|
||||
*/
|
||||
void batch(final ODataBatchRequest req);
|
||||
void batch(final CommonODataBatchRequest req);
|
||||
|
||||
/**
|
||||
* Writes (and consume) the request onto the given batch stream.
|
||||
|
@ -42,5 +42,5 @@ public interface ODataBatchableRequest extends ODataRequest {
|
|||
* @param req destination batch request.
|
||||
* @param contentId ContentId header value to be added to the serialization. Use this in case of changeset items.
|
||||
*/
|
||||
void batch(final ODataBatchRequest req, final String contentId);
|
||||
void batch(final CommonODataBatchRequest req, final String contentId);
|
||||
}
|
||||
|
|
|
@ -24,12 +24,4 @@ import java.io.Serializable;
|
|||
* OData batch request factory class.
|
||||
*/
|
||||
public interface CommonBatchRequestFactory extends Serializable {
|
||||
|
||||
/**
|
||||
* Gets a batch request object instance.
|
||||
*
|
||||
* @param serviceRoot service root.
|
||||
* @return new ODataBatchRequest instance.
|
||||
*/
|
||||
ODataBatchRequest getBatchRequest(String serviceRoot);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,11 @@ package org.apache.olingo.client.api.communication.request.batch;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.PipedOutputStream;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public interface ODataBatchRequest extends ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
|
||||
public interface CommonODataBatchRequest {
|
||||
|
||||
/**
|
||||
* Gets piped stream to be used to stream batch items.
|
||||
|
@ -42,7 +40,7 @@ public interface ODataBatchRequest extends ODataStreamedRequest<ODataBatchRespon
|
|||
* @return the current batch request.
|
||||
* @throws IOException in case of write errors.
|
||||
*/
|
||||
ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException;
|
||||
CommonODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException;
|
||||
|
||||
/**
|
||||
* Appends the given byte array to the payload.
|
||||
|
@ -53,5 +51,5 @@ public interface ODataBatchRequest extends ODataStreamedRequest<ODataBatchRespon
|
|||
* @return the current batch request.
|
||||
* @throws IOException in case of write errors.
|
||||
*/
|
||||
ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException;
|
||||
CommonODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException;
|
||||
}
|
|
@ -21,4 +21,12 @@ package org.apache.olingo.client.api.communication.request.batch.v3;
|
|||
import org.apache.olingo.client.api.communication.request.batch.CommonBatchRequestFactory;
|
||||
|
||||
public interface BatchRequestFactory extends CommonBatchRequestFactory {
|
||||
|
||||
/**
|
||||
* Gets a batch request object instance.
|
||||
*
|
||||
* @param serviceRoot service root.
|
||||
* @return new ODataBatchRequest instance.
|
||||
*/
|
||||
ODataBatchRequest getBatchRequest(String serviceRoot);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.api.communication.request.batch.v3;
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public interface BatchStreamManager
|
||||
extends org.apache.olingo.client.api.communication.request.batch.BatchStreamManager {
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.api.communication.request.batch.v3;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public interface ODataBatchRequest
|
||||
extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
|
||||
}
|
|
@ -21,4 +21,12 @@ package org.apache.olingo.client.api.communication.request.batch.v4;
|
|||
import org.apache.olingo.client.api.communication.request.batch.CommonBatchRequestFactory;
|
||||
|
||||
public interface BatchRequestFactory extends CommonBatchRequestFactory {
|
||||
|
||||
/**
|
||||
* Gets a batch request object instance.
|
||||
*
|
||||
* @param serviceRoot service root.
|
||||
* @return new ODataBatchRequest instance.
|
||||
*/
|
||||
ODataBatchRequest getBatchRequest(String serviceRoot);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.api.communication.request.batch.v4;
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public interface BatchStreamManager
|
||||
extends org.apache.olingo.client.api.communication.request.batch.BatchStreamManager {
|
||||
|
||||
/**
|
||||
* Gets an outside update batch item instance. An outside update item can be submitted embedded into a batch request
|
||||
* only.
|
||||
*
|
||||
* @return ODataOutsideUpdate instance.
|
||||
*/
|
||||
ODataOutsideUpdate addOutsideUpdate();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.api.communication.request.batch.v4;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public interface ODataBatchRequest
|
||||
extends CommonODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.api.communication.request.batch.v4;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequestItem;
|
||||
|
||||
/**
|
||||
* Retrieve request wrapper for the corresponding batch item.
|
||||
*/
|
||||
public interface ODataOutsideUpdate extends ODataBatchRequestItem {
|
||||
|
||||
/**
|
||||
* Serialize and send the given request.
|
||||
* <p>
|
||||
* An IllegalArgumentException is thrown in case of no GET request.
|
||||
*
|
||||
* @param request request to be serialized.
|
||||
* @return current item instance.
|
||||
*/
|
||||
ODataOutsideUpdate setRequest(final ODataBatchableRequest request);
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.client.api.communication.request.streamed;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataMediaEntityCreateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
|
||||
|
@ -27,5 +28,6 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
|||
* @param <E> concrete ODataEntity implementation
|
||||
*/
|
||||
public interface ODataMediaEntityCreateRequest<E extends CommonODataEntity>
|
||||
extends ODataStreamedEntityRequest<ODataMediaEntityCreateResponse<E>, MediaEntityCreateStreamManager<E>> {
|
||||
extends ODataStreamedEntityRequest<ODataMediaEntityCreateResponse<E>, MediaEntityCreateStreamManager<E>>,
|
||||
ODataBatchableRequest{
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.client.api.communication.request.streamed;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
|
||||
import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
||||
|
||||
|
@ -27,5 +28,6 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity;
|
|||
* @param <E> concrete ODataEntity implementation
|
||||
*/
|
||||
public interface ODataMediaEntityUpdateRequest<E extends CommonODataEntity>
|
||||
extends ODataStreamedEntityRequest<ODataMediaEntityUpdateResponse<E>, MediaEntityUpdateStreamManager<E>> {
|
||||
extends ODataStreamedEntityRequest<ODataMediaEntityUpdateResponse<E>, MediaEntityUpdateStreamManager<E>>,
|
||||
ODataBatchableRequest {
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.apache.olingo.client.api.ODataBatchConstants;
|
|||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamer;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.commons.api.format.Format;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
|
@ -94,7 +94,7 @@ public abstract class AbstractODataBasicRequest<V extends ODataResponse, T exten
|
|||
*
|
||||
* @param req destination batch request.
|
||||
*/
|
||||
public void batch(final ODataBatchRequest req) {
|
||||
public void batch(final CommonODataBatchRequest req) {
|
||||
batch(req, null);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public abstract class AbstractODataBasicRequest<V extends ODataResponse, T exten
|
|||
* @param req destination batch request.
|
||||
* @param contentId contentId of the changeset item.
|
||||
*/
|
||||
public void batch(final ODataBatchRequest req, final String contentId) {
|
||||
public void batch(final CommonODataBatchRequest req, final String contentId) {
|
||||
try {
|
||||
req.rawAppend(toByteArray());
|
||||
if (StringUtils.isNotBlank(contentId)) {
|
||||
|
|
|
@ -14,7 +14,6 @@ package org.apache.olingo.client.core.communication.request.batch;
|
|||
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonBatchRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
|
||||
/**
|
||||
* OData batch request factory class.
|
||||
|
@ -28,9 +27,4 @@ public abstract class AbstractBatchRequestFactory implements CommonBatchRequestF
|
|||
protected AbstractBatchRequestFactory(final CommonODataClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataBatchRequest getBatchRequest(final String serviceRoot) {
|
||||
return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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.request.batch;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequestItem;
|
||||
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.response.ODataBatchResponse;
|
||||
import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
|
||||
import org.apache.olingo.client.core.communication.request.Wrapper;
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public abstract class AbstractBatchStreamManager extends AbstractODataStreamManager<ODataBatchResponse> {
|
||||
|
||||
/**
|
||||
* Batch request current item.
|
||||
*/
|
||||
protected ODataBatchRequestItem currentItem = null;
|
||||
|
||||
/**
|
||||
* batch request reference.
|
||||
*/
|
||||
protected final CommonODataBatchRequest req;
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*
|
||||
* @param req batch request reference.
|
||||
*/
|
||||
protected AbstractBatchStreamManager(
|
||||
final CommonODataBatchRequest req, final Wrapper<Future<HttpResponse>> futureWrap) {
|
||||
super(futureWrap);
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a changeset batch item instance. A changeset can be submitted embedded into a batch request only.
|
||||
*
|
||||
* @return ODataChangeset instance.
|
||||
*/
|
||||
public ODataChangeset addChangeset() {
|
||||
closeCurrentItem();
|
||||
|
||||
// stream dash boundary
|
||||
streamDashBoundary();
|
||||
|
||||
final ODataChangesetResponseItem expectedResItem = new ODataChangesetResponseItem();
|
||||
((AbstractODataBatchRequest) req).expectedResItems.add(expectedResItem);
|
||||
|
||||
currentItem = new ODataChangesetImpl(req, expectedResItem);
|
||||
|
||||
return (ODataChangeset) currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a retrieve batch item instance. A retrieve item can be submitted embedded into a batch request only.
|
||||
*
|
||||
* @return ODataRetrieve instance.
|
||||
*/
|
||||
public ODataRetrieve addRetrieve() {
|
||||
closeCurrentItem();
|
||||
|
||||
// stream dash boundary
|
||||
streamDashBoundary();
|
||||
|
||||
final ODataRetrieveResponseItem expectedResItem = new ODataRetrieveResponseItem();
|
||||
currentItem = new ODataRetrieveImpl(req, expectedResItem);
|
||||
|
||||
((AbstractODataBatchRequest) req).expectedResItems.add(expectedResItem);
|
||||
|
||||
return (ODataRetrieve) currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current streamed item.
|
||||
*/
|
||||
protected void closeCurrentItem() {
|
||||
if (currentItem != null) {
|
||||
currentItem.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
protected ODataBatchResponse getResponse(final long timeout, final TimeUnit unit) {
|
||||
closeCurrentItem();
|
||||
streamCloseDelimiter();
|
||||
finalizeBody();
|
||||
return getResponseInstance(timeout, unit);
|
||||
}
|
||||
|
||||
protected abstract ODataBatchResponse getResponseInstance(final long timeout, final TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Streams dash boundary.
|
||||
*/
|
||||
protected void streamDashBoundary() {
|
||||
// preamble
|
||||
newLine();
|
||||
|
||||
// stream batch-boundary
|
||||
stream(("--" + ((AbstractODataBatchRequest) req).boundary).getBytes());
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams close delimiter.
|
||||
*/
|
||||
protected void streamCloseDelimiter() {
|
||||
// stream close-delimiter
|
||||
newLine();
|
||||
stream(("--" + ((AbstractODataBatchRequest) req).boundary + "--").getBytes());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.request.batch;
|
||||
|
||||
import java.io.PipedOutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.apache.olingo.client.api.ODataBatchConstants;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.streamed.AbstractODataStreamedRequest;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public abstract class AbstractODataBatchRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
|
||||
extends AbstractODataStreamedRequest<V, T> {
|
||||
|
||||
/**
|
||||
* Batch request boundary.
|
||||
*/
|
||||
protected final String boundary;
|
||||
|
||||
/**
|
||||
* Expected batch response items.
|
||||
*/
|
||||
protected final List<ODataBatchResponseItem> expectedResItems = new ArrayList<ODataBatchResponseItem>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param odataClient client instance getting this request
|
||||
* @param uri batch request URI (http://serviceRoot/$batch)
|
||||
*/
|
||||
protected AbstractODataBatchRequest(final CommonODataClient odataClient, final URI uri) {
|
||||
super(odataClient, HttpMethod.POST, uri);
|
||||
|
||||
// create a random UUID value for boundary
|
||||
boundary = "batch_" + UUID.randomUUID().toString();
|
||||
|
||||
// specify the contentType header
|
||||
setContentType(ContentType.MULTIPART_MIXED + ";" + ODataBatchConstants.BOUNDARY + "=" + boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
public PipedOutputStream getOutputStream() {
|
||||
return getStreamManager().getBodyStreamWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This operation is unsupported by a batch request.
|
||||
*/
|
||||
@Override
|
||||
public void batch(CommonODataBatchRequest req) {
|
||||
throw new UnsupportedOperationException("A batch request is not batchable");
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ package org.apache.olingo.client.core.communication.request.batch;
|
|||
|
||||
import org.apache.olingo.client.api.ODataBatchConstants;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequestItem;
|
||||
import org.apache.olingo.client.core.communication.request.AbstractODataStreamer;
|
||||
|
||||
|
@ -43,14 +43,14 @@ public abstract class AbstractODataBatchRequestItem extends AbstractODataStreame
|
|||
/**
|
||||
* OData batch request.
|
||||
*/
|
||||
protected ODataBatchRequest req;
|
||||
protected CommonODataBatchRequest req;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param req OData batch request.
|
||||
*/
|
||||
public AbstractODataBatchRequestItem(final ODataBatchRequest req) {
|
||||
public AbstractODataBatchRequestItem(final CommonODataBatchRequest req) {
|
||||
super(req.getOutputStream());
|
||||
this.open = true;
|
||||
this.req = req;
|
||||
|
@ -81,7 +81,7 @@ public abstract class AbstractODataBatchRequestItem extends AbstractODataStreame
|
|||
* @param request request to be batched.
|
||||
* @param contentId changeset item id.
|
||||
*/
|
||||
protected void streamRequestHeader(final ODataBatchableRequest request, final int contentId) {
|
||||
protected void streamRequestHeader(final ODataBatchableRequest request, final String contentId) {
|
||||
//stream batch content type
|
||||
stream(ODataBatchConstants.ITEM_CONTENT_TYPE_LINE.getBytes());
|
||||
newLine();
|
||||
|
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
* 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.request.batch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.olingo.client.api.ODataBatchConstants;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
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.ODataBatchRequestItem;
|
||||
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.response.ODataBatchResponse;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
|
||||
import org.apache.olingo.client.core.communication.request.streamed.AbstractODataStreamedRequest;
|
||||
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public class ODataBatchRequestImpl extends AbstractODataStreamedRequest<ODataBatchResponse, BatchStreamManager>
|
||||
implements ODataBatchRequest {
|
||||
|
||||
/**
|
||||
* Batch request boundary.
|
||||
*/
|
||||
private final String boundary;
|
||||
|
||||
/**
|
||||
* Expected batch response items.
|
||||
*/
|
||||
private final List<ODataBatchResponseItem> expectedResItems = new ArrayList<ODataBatchResponseItem>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param odataClient client instance getting this request
|
||||
* @param uri batch request URI (http://serviceRoot/$batch)
|
||||
*/
|
||||
ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) {
|
||||
super(odataClient, HttpMethod.POST, uri);
|
||||
|
||||
// create a random UUID value for boundary
|
||||
boundary = "batch_" + UUID.randomUUID().toString();
|
||||
|
||||
// specify the contentType header
|
||||
setContentType(ODataBatchConstants.MULTIPART_CONTENT_TYPE + ";" + ODataBatchConstants.BOUNDARY + "=" + boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
protected BatchStreamManager getStreamManager() {
|
||||
if (streamManager == null) {
|
||||
streamManager = new BatchStreamManagerImpl(this);
|
||||
}
|
||||
return (BatchStreamManager) streamManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public PipedOutputStream getOutputStream() {
|
||||
return getStreamManager().getBodyStreamWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequestImpl rawAppend(final byte[] toBeStreamed) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequestImpl rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This operation is unsupported by a batch request.
|
||||
*/
|
||||
@Override
|
||||
public void batch(ODataBatchRequest req) {
|
||||
throw new UnsupportedOperationException("A batch request is not batchable");
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements a response to a batch request.
|
||||
*
|
||||
* @see org.apache.olingo.client.core.communication.request.ODataBatchRequest
|
||||
*/
|
||||
private class ODataBatchResponseImpl extends AbstractODataResponse implements ODataBatchResponse {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param client HTTP client.
|
||||
* @param res HTTP response.
|
||||
*/
|
||||
private ODataBatchResponseImpl(final HttpClient client, final HttpResponse res) {
|
||||
super(client, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Iterator<ODataBatchResponseItem> getBody() {
|
||||
return new ODataBatchResponseManager(this, expectedResItems);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public class BatchStreamManagerImpl extends AbstractODataStreamManager<ODataBatchResponse>
|
||||
implements BatchStreamManager {
|
||||
|
||||
/**
|
||||
* Batch request current item.
|
||||
*/
|
||||
private ODataBatchRequestItem currentItem = null;
|
||||
|
||||
/**
|
||||
* batch request reference.
|
||||
*/
|
||||
private final ODataBatchRequest req;
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*
|
||||
* @param req batch request reference.
|
||||
*/
|
||||
private BatchStreamManagerImpl(final ODataBatchRequest req) {
|
||||
super(ODataBatchRequestImpl.this.futureWrapper);
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a changeset batch item instance. A changeset can be submitted embedded into a batch request only.
|
||||
*
|
||||
* @return ODataChangeset instance.
|
||||
*/
|
||||
@Override
|
||||
public ODataChangeset addChangeset() {
|
||||
closeCurrentItem();
|
||||
|
||||
// stream dash boundary
|
||||
streamDashBoundary();
|
||||
|
||||
final ODataChangesetResponseItem expectedResItem = new ODataChangesetResponseItem();
|
||||
expectedResItems.add(expectedResItem);
|
||||
|
||||
currentItem = new ODataChangesetImpl(req, expectedResItem);
|
||||
|
||||
return (ODataChangeset) currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a retrieve batch item instance. A retrieve item can be submitted embedded into a batch request only.
|
||||
*
|
||||
* @return ODataRetrieve instance.
|
||||
*/
|
||||
@Override
|
||||
public ODataRetrieve addRetrieve() {
|
||||
closeCurrentItem();
|
||||
|
||||
// stream dash boundary
|
||||
streamDashBoundary();
|
||||
|
||||
final ODataRetrieveResponseItem expectedResItem = new ODataRetrieveResponseItem();
|
||||
currentItem = new ODataRetrieveImpl(req, expectedResItem);
|
||||
|
||||
expectedResItems.add(expectedResItem);
|
||||
|
||||
return (ODataRetrieve) currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current streamed item.
|
||||
*/
|
||||
private void closeCurrentItem() {
|
||||
if (currentItem != null) {
|
||||
currentItem.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
protected ODataBatchResponse getResponse(final long timeout, final TimeUnit unit) {
|
||||
closeCurrentItem();
|
||||
streamCloseDelimiter();
|
||||
finalizeBody();
|
||||
return new ODataBatchResponseImpl(httpClient, getHttpResponse(timeout, unit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams dash boundary.
|
||||
*/
|
||||
private void streamDashBoundary() {
|
||||
// preamble
|
||||
newLine();
|
||||
|
||||
// stream batch-boundary
|
||||
stream(("--" + boundary).getBytes());
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams close delimiter.
|
||||
*/
|
||||
private void streamCloseDelimiter() {
|
||||
// stream close-delimiter
|
||||
newLine();
|
||||
stream(("--" + boundary + "--").getBytes());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import org.apache.olingo.client.api.ODataBatchConstants;
|
|||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamer;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -301,7 +302,7 @@ public class ODataBatchUtilities {
|
|||
final String contentType = headers.containsKey(HeaderName.contentType.toString())
|
||||
? headers.get(HeaderName.contentType.toString()).toString() : StringUtils.EMPTY;
|
||||
|
||||
if (contentType.contains(ODataBatchConstants.MULTIPART_CONTENT_TYPE)) {
|
||||
if (contentType.contains(ContentType.MULTIPART_MIXED)) {
|
||||
nextItemType = BatchItemType.CHANGESET;
|
||||
} else if (contentType.contains(ODataBatchConstants.ITEM_CONTENT_TYPE)) {
|
||||
nextItemType = BatchItemType.RETRIEVE;
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
package org.apache.olingo.client.core.communication.request.batch;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.apache.olingo.client.api.ODataBatchConstants;
|
||||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
|
||||
/**
|
||||
* Changeset wrapper for the corresponding batch item.
|
||||
|
@ -54,7 +54,7 @@ public class ODataChangesetImpl extends AbstractODataBatchRequestItem
|
|||
* @param req batch request.
|
||||
* @param expectedResItem expected OData response items.
|
||||
*/
|
||||
ODataChangesetImpl(final ODataBatchRequest req, final ODataChangesetResponseItem expectedResItem) {
|
||||
ODataChangesetImpl(final CommonODataBatchRequest req, final ODataChangesetResponseItem expectedResItem) {
|
||||
super(req);
|
||||
this.expectedResItem = expectedResItem;
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class ODataChangesetImpl extends AbstractODataBatchRequestItem
|
|||
|
||||
if (!hasStreamedSomething) {
|
||||
stream((HeaderName.contentType.toString() + ": "
|
||||
+ ODataBatchConstants.MULTIPART_CONTENT_TYPE + ";boundary=" + boundary).getBytes());
|
||||
+ ContentType.MULTIPART_MIXED + ";boundary=" + boundary).getBytes());
|
||||
|
||||
newLine();
|
||||
newLine();
|
||||
|
@ -117,7 +117,7 @@ public class ODataChangesetImpl extends AbstractODataBatchRequestItem
|
|||
newLine();
|
||||
|
||||
// stream the request
|
||||
streamRequestHeader(request, contentId);
|
||||
streamRequestHeader(request, String.valueOf(contentId));
|
||||
|
||||
request.batch(req, String.valueOf(contentId));
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.apache.olingo.client.core.communication.request.batch;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataRetrieve;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
|
||||
|
@ -38,7 +38,7 @@ public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
|
|||
* @param req batch request.
|
||||
* @param expectedResItem expected batch response item.
|
||||
*/
|
||||
ODataRetrieveImpl(final ODataBatchRequest req, final ODataRetrieveResponseItem expectedResItem) {
|
||||
ODataRetrieveImpl(final CommonODataBatchRequest req, final ODataRetrieveResponseItem expectedResItem) {
|
||||
super(req);
|
||||
this.expectedResItem = expectedResItem;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.client.core.communication.request.batch.v3;
|
|||
|
||||
import org.apache.olingo.client.api.v3.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v3.ODataBatchRequest;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchRequestFactory;
|
||||
|
||||
public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
|
||||
|
@ -30,4 +31,9 @@ public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
|
|||
public BatchRequestFactoryImpl(final ODataClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataBatchRequest getBatchRequest(final String serviceRoot) {
|
||||
return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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.request.batch.v3;
|
||||
|
||||
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.client.HttpClient;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v3.BatchStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v3.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequest;
|
||||
import org.apache.olingo.client.core.communication.request.batch.v3.ODataBatchRequestImpl.BatchStreamManagerImpl;
|
||||
import org.apache.olingo.client.core.communication.request.batch.v3.ODataBatchRequestImpl.ODataBatchResponseImpl;
|
||||
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
|
||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public class ODataBatchRequestImpl
|
||||
extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
|
||||
implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
|
||||
|
||||
public ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) {
|
||||
super(odataClient, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BatchStreamManager getStreamManager() {
|
||||
if (streamManager == null) {
|
||||
streamManager = new BatchStreamManagerImpl(this);
|
||||
}
|
||||
return (BatchStreamManager) streamManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public class BatchStreamManagerImpl extends AbstractBatchStreamManager implements BatchStreamManager {
|
||||
|
||||
public BatchStreamManagerImpl(final ODataBatchRequest req) {
|
||||
super(req, ODataBatchRequestImpl.this.futureWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataBatchResponse getResponseInstance(final long timeout, final TimeUnit unit) {
|
||||
return new ODataBatchResponseImpl(httpClient, getHttpResponse(timeout, unit));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param client HTTP client.
|
||||
* @param res HTTP response.
|
||||
*/
|
||||
protected ODataBatchResponseImpl(final HttpClient client, final HttpResponse res) {
|
||||
super(client, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Iterator<ODataBatchResponseItem> getBody() {
|
||||
return new ODataBatchResponseManager(this, expectedResItems);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.client.core.communication.request.batch.v4;
|
|||
|
||||
import org.apache.olingo.client.api.v4.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataBatchRequest;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchRequestFactory;
|
||||
|
||||
public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
|
||||
|
@ -30,4 +31,9 @@ public class BatchRequestFactoryImpl extends AbstractBatchRequestFactory
|
|||
public BatchRequestFactoryImpl(final ODataClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataBatchRequest getBatchRequest(final String serviceRoot) {
|
||||
return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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.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.client.HttpClient;
|
||||
import org.apache.olingo.client.api.CommonODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.BatchStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
|
||||
import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractBatchStreamManager;
|
||||
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.batch.ODataBatchResponseManager;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
|
||||
/**
|
||||
* This class implements a batch request.
|
||||
*/
|
||||
public class ODataBatchRequestImpl
|
||||
extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
|
||||
implements ODataBatchRequest {
|
||||
|
||||
public ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) {
|
||||
super(odataClient, uri);
|
||||
setAccept(ContentType.MULTIPART_MIXED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BatchStreamManager getStreamManager() {
|
||||
if (streamManager == null) {
|
||||
streamManager = new BatchStreamManagerImpl(this);
|
||||
}
|
||||
return (BatchStreamManager) streamManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
|
||||
getStreamManager().getBodyStreamWriter().write(toBeStreamed, off, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch request payload management.
|
||||
*/
|
||||
public class BatchStreamManagerImpl extends AbstractBatchStreamManager implements BatchStreamManager {
|
||||
|
||||
public BatchStreamManagerImpl(final ODataBatchRequest req) {
|
||||
super(req, ODataBatchRequestImpl.this.futureWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataBatchResponse getResponseInstance(final long timeout, final TimeUnit unit) {
|
||||
return new ODataBatchResponseImpl(httpClient, getHttpResponse(timeout, unit));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataOutsideUpdate addOutsideUpdate() {
|
||||
closeCurrentItem();
|
||||
|
||||
// stream dash boundary
|
||||
streamDashBoundary();
|
||||
|
||||
final ODataOutsideUpdateResponseItem expectedResItem = new ODataOutsideUpdateResponseItem();
|
||||
currentItem = new ODataOutsideUpdateImpl(req, expectedResItem);
|
||||
|
||||
((ODataBatchRequestImpl) req).expectedResItems.add(expectedResItem);
|
||||
|
||||
return (ODataOutsideUpdate) currentItem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param client HTTP client.
|
||||
* @param res HTTP response.
|
||||
*/
|
||||
protected ODataBatchResponseImpl(final HttpClient client, final HttpResponse res) {
|
||||
super(client, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Iterator<ODataBatchResponseItem> getBody() {
|
||||
return new ODataBatchResponseManager(this, expectedResItems);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.request.batch.v4;
|
||||
|
||||
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequestItem;
|
||||
|
||||
/**
|
||||
* Retrieve request wrapper for the corresponding batch item.
|
||||
*/
|
||||
public class ODataOutsideUpdateImpl extends AbstractODataBatchRequestItem
|
||||
implements ODataOutsideUpdate {
|
||||
|
||||
private final ODataOutsideUpdateResponseItem expectedResItem;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param req batch request.
|
||||
* @param expectedResItem expected batch response item.
|
||||
*/
|
||||
ODataOutsideUpdateImpl(final CommonODataBatchRequest req, final ODataOutsideUpdateResponseItem expectedResItem) {
|
||||
super(req);
|
||||
this.expectedResItem = expectedResItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close item.
|
||||
*/
|
||||
@Override
|
||||
protected void closeItem() {
|
||||
// nop
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataOutsideUpdate setRequest(final ODataBatchableRequest request) {
|
||||
if (!isOpen()) {
|
||||
throw new IllegalStateException("Current batch item is closed");
|
||||
}
|
||||
|
||||
if (((ODataRequestImpl) request).getMethod() == HttpMethod.GET) {
|
||||
throw new IllegalArgumentException("Invalid request. Use ODataRetrieve for GET method");
|
||||
}
|
||||
|
||||
hasStreamedSomething = true;
|
||||
|
||||
// stream the request
|
||||
streamRequestHeader(request, ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID);
|
||||
|
||||
request.batch(req, ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID);
|
||||
|
||||
// close before in order to avoid any further setRequest calls.
|
||||
close();
|
||||
|
||||
// add request to the list
|
||||
expectedResItem.addResponse(
|
||||
ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.request.batch.v4;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchResponseItem;
|
||||
import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
|
||||
import org.apache.olingo.client.core.communication.response.batch.ODataBatchErrorResponse;
|
||||
|
||||
/**
|
||||
* Retrieve response wrapper for the corresponding batch item.
|
||||
*/
|
||||
public class ODataOutsideUpdateResponseItem extends AbstractODataBatchResponseItem {
|
||||
|
||||
public static final String OUTSIDE_CONTENT_ID = "__OUTSIDEUPDATE__";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ODataOutsideUpdateResponseItem() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
@Override
|
||||
public ODataResponse next() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException("Invalid request - the item has been closed");
|
||||
}
|
||||
|
||||
final Map.Entry<Integer, String> responseLine = ODataBatchUtilities.readResponseLine(batchLineIterator);
|
||||
LOG.debug("Retrieved item response {}", responseLine);
|
||||
|
||||
final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator);
|
||||
LOG.debug("Retrieved item headers {}", headers);
|
||||
|
||||
final ODataResponse res;
|
||||
|
||||
if (responseLine.getKey() >= 400) {
|
||||
// generate error response
|
||||
res = new ODataBatchErrorResponse(responseLine, headers, batchLineIterator, boundary);
|
||||
} else {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException("No item found");
|
||||
}
|
||||
res = expectedItemsIterator.next().initFromBatch(responseLine, headers, batchLineIterator, boundary);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsupported operation.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Operation not supported.");
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ import org.apache.olingo.client.api.CommonODataClient;
|
|||
import org.apache.olingo.client.api.communication.request.ODataStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamer;
|
||||
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.commons.api.format.ODataMediaFormat;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
|
@ -112,7 +112,7 @@ public abstract class AbstractODataStreamedRequest<V extends ODataResponse, T ex
|
|||
*
|
||||
* @param req destination batch request.
|
||||
*/
|
||||
public void batch(final ODataBatchRequest req) {
|
||||
public void batch(final CommonODataBatchRequest req) {
|
||||
batch(req, null);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ public abstract class AbstractODataStreamedRequest<V extends ODataResponse, T ex
|
|||
* @param req destination batch request.
|
||||
* @param contentId ContentId header value to be added to the serialization. Use this in case of changeset items.
|
||||
*/
|
||||
public void batch(final ODataBatchRequest req, final String contentId) {
|
||||
public void batch(final CommonODataBatchRequest req, final String contentId) {
|
||||
final InputStream input = getStreamManager().getBody();
|
||||
|
||||
try {
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
|
|||
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.streamed.MediaEntityCreateStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityCreateRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataMediaEntityCreateResponse;
|
||||
|
@ -42,7 +41,7 @@ import org.apache.olingo.commons.api.data.Entry;
|
|||
*/
|
||||
public class ODataMediaEntityCreateRequestImpl<E extends CommonODataEntity>
|
||||
extends AbstractODataStreamedEntityRequest<ODataMediaEntityCreateResponse<E>, MediaEntityCreateStreamManager<E>>
|
||||
implements ODataMediaEntityCreateRequest<E>, ODataBatchableRequest {
|
||||
implements ODataMediaEntityCreateRequest<E> {
|
||||
|
||||
private final InputStream media;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
|
|||
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.streamed.MediaEntityUpdateStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
|
||||
|
@ -42,7 +41,7 @@ import org.apache.olingo.commons.api.data.Entry;
|
|||
*/
|
||||
public class ODataMediaEntityUpdateRequestImpl<E extends CommonODataEntity>
|
||||
extends AbstractODataStreamedEntityRequest<ODataMediaEntityUpdateResponse<E>, MediaEntityUpdateStreamManager<E>>
|
||||
implements ODataMediaEntityUpdateRequest<E>, ODataBatchableRequest {
|
||||
implements ODataMediaEntityUpdateRequest<E> {
|
||||
|
||||
private final InputStream media;
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ 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.batch.v3.ODataBatchRequest;
|
||||
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;
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.apache.olingo.client.core.it.v4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
@ -35,11 +33,12 @@ import org.apache.olingo.client.api.ODataBatchConstants;
|
|||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.header.ODataPreferences;
|
||||
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.batch.v4.BatchStreamManager;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataBatchRequest;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
|
||||
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.v4.UpdateType;
|
||||
|
@ -54,15 +53,20 @@ import org.apache.olingo.client.core.communication.request.AbstractODataStreamMa
|
|||
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.batch.v4.ODataOutsideUpdateResponseItem;
|
||||
import org.apache.olingo.client.core.communication.request.retrieve.ODataEntityRequestImpl;
|
||||
import org.apache.olingo.client.core.communication.request.retrieve.ODataEntityRequestImpl.ODataEntityResponseImpl;
|
||||
import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BatchTestITCase extends AbstractTestITCase {
|
||||
|
@ -73,6 +77,14 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
|
||||
private static final int MAX = 10000;
|
||||
|
||||
// ------------------------
|
||||
// Uncomment to performe check externally ...
|
||||
// ------------------------
|
||||
// private final static String testStaticServiceRootURL= "http://odatae2etest.azurewebsites.net/javatest/DefaultService/";
|
||||
// private final static String ACCEPT = ContentType.MULTIPART_MIXED;
|
||||
// ------------------------
|
||||
private final static String ACCEPT = ContentType.APPLICATION_OCTET_STREAM;
|
||||
|
||||
@Test
|
||||
public void stringStreaming() {
|
||||
final TestStreamManager streaming = new TestStreamManager();
|
||||
|
@ -93,6 +105,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
public void emptyBatchRequest() {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
|
||||
final BatchStreamManager payload = request.execute();
|
||||
final ODataBatchResponse response = payload.getResponse();
|
||||
|
@ -108,6 +121,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
public void changesetWithError() {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
|
||||
final BatchStreamManager payload = request.execute();
|
||||
final ODataChangeset changeset = payload.addChangeset();
|
||||
|
@ -164,6 +178,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
private void continueOnError(final boolean continueOnError) {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
|
||||
if (continueOnError) {
|
||||
request.addCustomHeader(HeaderName.prefer, new ODataPreferences(client.getServiceVersion()).continueOnError());
|
||||
|
@ -232,6 +247,7 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
public void changesetWithReference() throws EdmPrimitiveTypeException {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
final BatchStreamManager streamManager = request.execute();
|
||||
|
||||
final ODataChangeset changeset = streamManager.addChangeset();
|
||||
|
@ -310,11 +326,83 @@ public class BatchTestITCase extends AbstractTestITCase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void batchRequestWithOutsideUpdates() throws EdmPrimitiveTypeException {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
final BatchStreamManager streamManager = request.execute();
|
||||
|
||||
// -------------------------------------------
|
||||
// Add retrieve item
|
||||
// -------------------------------------------
|
||||
ODataRetrieve retrieve = streamManager.addRetrieve();
|
||||
|
||||
// prepare URI
|
||||
URIBuilder targetURI = client.getURIBuilder(testStaticServiceRootURL);
|
||||
targetURI.appendEntitySetSegment("Customers").appendKeySegment(1).
|
||||
expand("Orders").select("PersonID,Orders/OrderID");
|
||||
|
||||
// create new request
|
||||
ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
|
||||
queryReq.setFormat(ODataPubFormat.ATOM);
|
||||
|
||||
retrieve.setRequest(queryReq);
|
||||
// -------------------------------------------
|
||||
|
||||
// -------------------------------------------
|
||||
// Add new order with outside item
|
||||
// -------------------------------------------
|
||||
final ODataOutsideUpdate outside = streamManager.addOutsideUpdate();
|
||||
|
||||
// prepare URI
|
||||
targetURI = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Orders");
|
||||
final ODataEntity original = newOrder(2000);
|
||||
final ODataEntityCreateRequest<ODataEntity> createReq =
|
||||
client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
|
||||
createReq.setFormat(ODataPubFormat.ATOM);
|
||||
outside.setRequest(createReq);
|
||||
// -------------------------------------------
|
||||
|
||||
final ODataBatchResponse response = streamManager.getResponse();
|
||||
assertEquals(200, response.getStatusCode());
|
||||
assertEquals("OK", response.getStatusMessage());
|
||||
final Iterator<ODataBatchResponseItem> iter = response.getBody();
|
||||
|
||||
// retrieve 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());
|
||||
|
||||
// retrieve the second item (ODataChangeset)
|
||||
item = iter.next();
|
||||
assertTrue(item instanceof ODataOutsideUpdateResponseItem);
|
||||
|
||||
final ODataOutsideUpdateResponseItem outitem = (ODataOutsideUpdateResponseItem) item;
|
||||
res = outitem.next();
|
||||
assertTrue(res instanceof ODataEntityCreateResponse);
|
||||
assertEquals(201, res.getStatusCode());
|
||||
assertEquals("Created", res.getStatusMessage());
|
||||
|
||||
final ODataEntityCreateResponse<ODataEntity> entres = (ODataEntityCreateResponse<ODataEntity>) res;
|
||||
final ODataEntity entity = entres.getBody();
|
||||
assertEquals(2000, entity.getProperty("OrderID").getPrimitiveValue().toCastValue(Integer.class).intValue());
|
||||
|
||||
assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void batchRequest() throws EdmPrimitiveTypeException {
|
||||
// create your request
|
||||
final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(testStaticServiceRootURL);
|
||||
request.setAccept(ACCEPT);
|
||||
|
||||
final BatchStreamManager streamManager = request.execute();
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ public abstract class ContentType {
|
|||
|
||||
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
public static final String MULTIPART_MIXED = "multipart/mixed";
|
||||
|
||||
public static final String APPLICATION_SVG_XML = "application/svg+xml";
|
||||
|
||||
public static final String APPLICATION_XHTML_XML = "application/xhtml+xml";
|
||||
|
|
Loading…
Reference in New Issue