You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/08/03 19:27:40 UTC
olingo-odata4 git commit: [OLINGO-708] Enabled async support for
batch case in TecSvc
Repository: olingo-odata4
Updated Branches:
refs/heads/master 5e481b23e -> 955823383
[OLINGO-708] Enabled async support for batch case in TecSvc
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/95582338
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/95582338
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/95582338
Branch: refs/heads/master
Commit: 955823383d8755cace6872e2f9f6b72db22c885d
Parents: 5e481b2
Author: Michael Bolz <mi...@sap.com>
Authored: Mon Aug 3 19:21:38 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Aug 3 19:22:34 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/AsyncSupportITCase.java | 104 ++++++++
.../fit/tecsvc/http/BasicAsyncITCase.java | 238 +++++++++++++++++++
fit/src/test/resources/basicBatchPost.batch | 33 +++
.../processor/TechnicalBatchProcessor.java | 17 ++
4 files changed, 392 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
index ad8fcbc..b99317d 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
@@ -19,9 +19,15 @@
package org.apache.olingo.fit.tecsvc.client;
import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.request.AsyncBatchRequestWrapper;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.response.AsyncResponseWrapper;
+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.ODataResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
@@ -29,6 +35,7 @@ import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.domain.ClientObjectFactory;
import org.apache.olingo.client.api.domain.ClientProperty;
+import org.apache.olingo.client.api.uri.URIBuilder;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
@@ -40,9 +47,11 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
+import org.junit.Ignore;
import org.junit.Test;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -198,6 +207,101 @@ public final class AsyncSupportITCase extends AbstractBaseTestITCase {
assertNull(property2.getPrimitiveValue());
}
+ @Test
+ @Ignore("mibo: Does currently not work as expected -> issue in ODataClient?")
+ public void getBatchRequest() throws Exception {
+ ODataClient client = getClient();
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+
+// final BatchManager payload = request.payloadManager();
+
+ // create new request
+// ODataEntityRequest<ClientEntity> getRequest = appendGetRequest(client, payload, "ESAllPrim", 32767, false);
+// payload.addRequest(getRequest);
+
+ //
+ request.addCustomHeader(HttpHeader.PREFER,
+ "respond-async; " + TechnicalAsyncService.TEC_ASYNC_SLEEP + "=1");
+ ODataBatchableRequest getRequest = appendGetRequest(client, "ESAllPrim", 32767, false);
+ AsyncBatchRequestWrapper asyncRequest =
+ client.getAsyncRequestFactory().getAsyncBatchRequestWrapper(request);
+ asyncRequest.addRetrieve(getRequest);
+ AsyncResponseWrapper<ODataBatchResponse> asyncResponse = asyncRequest.execute();
+
+// Future<ODataBatchResponse> test = payload.getAsyncResponse();
+// ODataBatchResponse res = payload.getResponse();
+//
+// while(!test.isDone()) {
+// System.out.println("Wait...");
+// TimeUnit.SECONDS.sleep(1);
+// }
+
+// // Fetch result
+// final ODataBatchResponse response = asyncResponse.getODataResponse();
+
+ waitTillDone(asyncResponse, 3);
+// assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode());
+// assertEquals("Accepted", response.getStatusMessage());
+
+ ODataResponse firstResponse = asyncResponse.getODataResponse();
+ assertEquals(200, firstResponse.getStatusCode());
+ assertEquals(2, firstResponse.getHeaderNames().size());
+ assertEquals("4.0", firstResponse.getHeader("OData-Version").iterator().next());
+
+ ResWrap<Entity> firWrap = getClient().getDeserializer(ContentType.APPLICATION_JSON)
+ .toEntity(firstResponse.getRawResponse());
+ Entity entity = firWrap.getPayload();
+ assertEquals(32767, entity.getProperty("PropertyInt16").asPrimitive());
+ assertEquals("First Resource - positive values", entity.getProperty("PropertyString").asPrimitive());
+ }
+
+
+ /**
+ * Test delete with async prefer header but without async support from TecSvc.
+ */
+ @Test
+ public void deleteEntity() throws Exception {
+ ODataClient client = getClient();
+ URI uri = client.newURIBuilder(SERVICE_URI)
+ .appendEntitySetSegment(ES_ALL_PRIM)
+ .appendKeySegment(32767).build();
+
+ // asyncDeleteRequest async request
+ ODataRequest deleteRequest = getClient().getCUDRequestFactory().getDeleteRequest(uri)
+ .addCustomHeader(HttpHeader.PREFER, "respond-async; " + TechnicalAsyncService.TEC_ASYNC_SLEEP + "=5");
+ AsyncResponseWrapper<ODataResponse> asyncDeleteRequest =
+ client.getAsyncRequestFactory().getAsyncRequestWrapper(deleteRequest).execute();
+
+ waitTillDone(asyncDeleteRequest, 5);
+
+ ODataResponse response = asyncDeleteRequest.getODataResponse();
+ assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
+
+ // Check that the deleted entity is really gone.
+ // This check has to be in the same session in order to access the same data provider.
+ ODataEntityRequest<ClientEntity> entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri);
+ entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
+ try {
+ entityRequest.execute();
+ fail("Expected exception not thrown!");
+ } catch (final ODataClientErrorException e) {
+ assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode());
+ }
+ }
+
+ private ODataEntityRequest<ClientEntity> appendGetRequest(final ODataClient client, final String segment,
+ final Object key, final boolean isRelative)
+ throws URISyntaxException {
+
+ final URIBuilder targetURI = client.newURIBuilder(SERVICE_URI);
+ targetURI.appendEntitySetSegment(segment).appendKeySegment(key);
+ final URI uri = (isRelative) ? new URI(SERVICE_URI).relativize(targetURI.build()) : targetURI.build();
+
+ ODataEntityRequest<ClientEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(uri);
+ queryReq.setFormat(ContentType.JSON);
+ return queryReq;
+ }
+
private void checkEntityAvailableWith(ClientEntitySet entitySet, String property, Object value) {
List<ClientEntity> entities = entitySet.getEntities();
for (ClientEntity entity : entities) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
new file mode 100644
index 0000000..c4a6779
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.fit.tecsvc.http;
+
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.apache.olingo.fit.util.StringHelper;
+import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test support of asynchronous batch within the TecSvc without using the OData client library (only
+ * use java.net.* components for plain http communication).
+ */
+public class BasicAsyncITCase extends AbstractBaseTestITCase {
+
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
+
+ private static final String HEADER_CONTENT_TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary";
+ private static final String HEADER_CONTENT_TYPE_HTTP =
+ HttpHeader.CONTENT_TYPE + ": " + ContentType.APPLICATION_HTTP.toContentTypeString();
+ private static final String DEFAULT_BATCH_BOUNDARY = "batch_123";
+ private static final String ACCEPT_HEADER_VALUE = ContentType.APPLICATION_JSON.toContentTypeString();
+
+ private static final String CRLF = "\r\n";
+ private static final String DEFAULT_ENCODING = "utf-8";
+
+ /**
+ * Works
+ */
+ @Test
+ public void batchAsync() throws Exception {
+ final String content = getDefaultRequest("ESAllPrim(32767)");
+ final HttpURLConnection connection = postBatch(StringHelper.encapsulate(content), DEFAULT_BATCH_BOUNDARY, 1);
+ StringHelper.Stream response = StringHelper.toStream(connection.getInputStream());
+
+ assertEquals(0, response.byteLength());
+
+ Map<String, List<String>> headerFields = connection.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", headerFields.get(null).get(0));
+ assertTrue(Pattern.matches("http:\\/\\/localhost:9080\\/odata-server-tecsvc\\/status\\/\\d*",
+ headerFields.get("Location").get(0)));
+ assertEquals("respond-async", headerFields.get("Preference-Applied").get(0));
+
+ // get async response (still pending)
+ String respondUri = headerFields.get("Location").get(0);
+ HttpURLConnection statusRequest = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream statusBody = StringHelper.toStream(statusRequest.getInputStream());
+ Map<String, List<String>> statusHeaderFields = statusRequest.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", statusHeaderFields.get(null).get(0));
+ assertEquals(0, statusBody.byteLength());
+
+ // get async response (now finished)
+ TimeUnit.SECONDS.sleep(2);
+ HttpURLConnection result = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream resultBody = StringHelper.toStream(result.getInputStream());
+ Map<String, List<String>> resultHeaderFields = result.getHeaderFields();
+ String resBody = resultBody.asString();
+
+ assertEquals("HTTP/1.1 200 OK", resultHeaderFields.get(null).get(0));
+ assertEquals(1013, resultBody.byteLength());
+ contains(resBody,
+ "HTTP/1.1 200 OK",
+ "OData-Version: 4.0",
+ "Content-Length: 605",
+ "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"",
+ "\"PropertyInt16\":32767",
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\",",
+ "--batch_", "--");
+ }
+
+ /**
+ * Test with changeset
+ */
+ @Test
+ public void asyncChangesetViaPost() throws Exception {
+ InputStream content = Thread.currentThread().getContextClassLoader().getResourceAsStream("basicBatchPost.batch");
+ final HttpURLConnection connection = postBatch(content, "batch_8194-cf13-1f56", 1);
+ StringHelper.Stream response = StringHelper.toStream(connection.getInputStream());
+ assertEquals(0, response.byteLength());
+
+ Map<String, List<String>> headerFields = connection.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", headerFields.get(null).get(0));
+ // because of generated status id it is only checked that the location starts correct and contains a number
+ assertTrue(Pattern.matches("http:\\/\\/localhost:9080\\/odata-server-tecsvc\\/status\\/\\d*",
+ headerFields.get("Location").get(0)));
+ assertEquals("respond-async", headerFields.get("Preference-Applied").get(0));
+
+ // get async response (still pending)
+ String respondUri = headerFields.get("Location").get(0);
+ HttpURLConnection statusRequest = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream statusBody = StringHelper.toStream(statusRequest.getInputStream());
+ Map<String, List<String>> statusHeaderFields = statusRequest.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", statusHeaderFields.get(null).get(0));
+ assertEquals(0, statusBody.byteLength());
+
+ // get async response (now finished)
+ TimeUnit.SECONDS.sleep(2);
+ HttpURLConnection result = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream resultBody = StringHelper.toStream(result.getInputStream());
+ Map<String, List<String>> resultHeaderFields = result.getHeaderFields();
+ String resBody = resultBody.asString();
+ assertEquals("HTTP/1.1 200 OK", resultHeaderFields.get(null).get(0));
+ assertEquals(2324, resultBody.byteLength());
+ contains(resBody,
+ "HTTP/1.1 200 OK",
+ "OData-Version: 4.0",
+ "Content-Length: 605",
+ "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"",
+ "\"PropertyInt16\":32767",
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\",",
+ "--batch_", "--");
+ }
+
+ /**
+ * Validates that the content contains all given values in same order as the parameters are given.
+ * If the content does not contain a value or not in the given order <code>Assert.fail()</code> is called.
+ *
+ * @param content content which is checked
+ * @param values values which must be in content (and in correct order)
+ */
+ private void contains(String content, String... values) {
+ int index = 0;
+ for (String value : values) {
+ int currentIndex = content.indexOf(value, index);
+ if(currentIndex == -1) {
+ if(content.contains(value)) {
+ int foundIndex = content.indexOf(value);
+ fail("Expected value '" + value + "' was found but not were expected " +
+ "(started to search from position '" + index + "' but found first occurrence at index '" +
+ foundIndex + "').");
+ } else {
+ fail("Expected value '" + value + "' was not found");
+ }
+ }
+ index = currentIndex;
+ }
+ }
+
+ private String getDefaultRequest(final String uri) {
+ return "--" + DEFAULT_BATCH_BOUNDARY + CRLF
+ + HEADER_CONTENT_TRANSFER_ENCODING_BINARY + CRLF
+ + HEADER_CONTENT_TYPE_HTTP + CRLF
+ + CRLF
+ + "GET " + uri + " HTTP/1.1" + CRLF
+ + CRLF
+ + CRLF
+ + "--" + DEFAULT_BATCH_BOUNDARY + "--";
+ }
+
+ private HttpURLConnection postRequest(final URL url, final String content, final Map<String, String> headers)
+ throws IOException {
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.POST.toString());
+ //
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.setRequestProperty(header.getKey(), header.getValue());
+ }
+ //
+ connection.setDoOutput(true);
+ final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
+ writer.append(content);
+ writer.close();
+ connection.connect();
+ return connection;
+ }
+
+ private HttpURLConnection getRequest(URL url, Map<String, String> headers) throws IOException {
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.toString());
+ //
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.setRequestProperty(header.getKey(), header.getValue());
+ }
+ //
+ connection.connect();
+ return connection;
+ }
+
+ private HttpURLConnection postBatch(final InputStream content, String batchBoundary, int sleepTime)
+ throws IOException {
+
+ Map<String, String> headers = new HashMap<String, String>();
+ String contentTypeValue = ContentType.create(
+ ContentType.MULTIPART_MIXED, "boundary", batchBoundary).toContentTypeString();
+ headers.put(HttpHeader.CONTENT_TYPE, contentTypeValue);
+ headers.put(HttpHeader.ACCEPT, ACCEPT_HEADER_VALUE);
+ if(sleepTime >= 0) {
+ headers.put(HttpHeader.PREFER, "respond-async; " +
+ TechnicalAsyncService.TEC_ASYNC_SLEEP + "=" + String.valueOf(sleepTime));
+ }
+
+ StringHelper.Stream s = StringHelper.toStream(content);
+ final URL url = new URL(SERVICE_URI + "$batch");
+ return postRequest(url, s.asString(DEFAULT_ENCODING), headers);
+ }
+
+ @Override
+ protected ODataClient getClient() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/resources/basicBatchPost.batch
----------------------------------------------------------------------
diff --git a/fit/src/test/resources/basicBatchPost.batch b/fit/src/test/resources/basicBatchPost.batch
new file mode 100644
index 0000000..ad5f617
--- /dev/null
+++ b/fit/src/test/resources/basicBatchPost.batch
@@ -0,0 +1,33 @@
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET ESAllPrim(32767) HTTP/1.1
+Accept: application/json
+
+
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: changeRequest1
+
+PUT ESAllPrim(32767) HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+
+{"PropertyString":"MODIFIED"}
+
+--changeset_f980-1cb6-94dd--
+
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET ESAllPrim(32767)/PropertyString HTTP/1.1
+Accept: application/json
+
+
+--batch_8194-cf13-1f56--
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
index a2c7629..6821c8f 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
@@ -36,6 +36,8 @@ import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart;
import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.tecsvc.async.AsyncProcessor;
+import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
import org.apache.olingo.server.tecsvc.data.DataProvider;
public class TechnicalBatchProcessor extends TechnicalProcessor implements BatchProcessor {
@@ -47,6 +49,21 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch
@Override
public void processBatch(final BatchFacade facade, final ODataRequest request, final ODataResponse response)
throws ODataApplicationException, ODataLibraryException {
+ // only the first batch call (process batch) must be handled in a separate way for async support
+ // because a changeset has to be wrapped within a process batch call
+ if(odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
+ TechnicalAsyncService asyncService = TechnicalAsyncService.getInstance();
+ BatchProcessor processor = new TechnicalBatchProcessor(dataProvider);
+ processor.init(odata, serviceMetadata);
+ AsyncProcessor<BatchProcessor> asyncProcessor = asyncService.register(processor, BatchProcessor.class);
+ asyncProcessor.prepareFor().processBatch(facade, request, response);
+ String location = asyncProcessor.processAsync();
+ TechnicalAsyncService.acceptedResponse(response, location);
+ //
+ return;
+ }
+
+
final boolean continueOnError =
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasContinueOnError();