You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/11/13 17:17:30 UTC
[1/9] olingo-odata4 git commit: Tech Servlet
Repository: olingo-odata4
Updated Branches:
refs/heads/olingo472 32247295f -> ad177ac11
Tech Servlet
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/15bd1526
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/15bd1526
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/15bd1526
Branch: refs/heads/olingo472
Commit: 15bd15267a36ab2318e0824f6fcbb06f3d7a3351
Parents: 3224729
Author: Christian Holzer <c....@sap.com>
Authored: Tue Oct 28 16:55:57 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:54 2014 +0100
----------------------------------------------------------------------
.../olingo/server/api/batch/BatchException.java | 65 +++++++++
.../olingo/server/api/batch/BatchOperation.java | 36 +++++
.../server/api/processor/BatchProcessor.java | 31 ++++
.../apache/olingo/server/core/ODataHandler.java | 12 +-
.../server/core/batch/BatchException.java | 65 ---------
.../batch/handler/BatchChangeSetSorter.java | 145 +++++++++++++++++++
.../server/core/batch/handler/BatchHandler.java | 68 +++++++++
.../core/batch/handler/BatchOperationImpl.java | 74 ++++++++++
.../core/batch/handler/BatchPartHandler.java | 66 +++++++++
.../batch/handler/ODataResponsePartImpl.java | 44 ++++++
.../server/core/batch/parser/BatchBodyPart.java | 2 +-
.../core/batch/parser/BatchChangeSetPart.java | 2 +-
.../server/core/batch/parser/BatchParser.java | 2 +-
.../core/batch/parser/BatchParserCommon.java | 5 +-
.../core/batch/parser/BatchQueryOperation.java | 2 +-
.../BatchRequestTransformator.java | 8 +-
.../batch/transformator/BatchTransformator.java | 2 +-
.../transformator/BatchTransformatorCommon.java | 4 +-
.../core/batch/writer/BatchResponseWriter.java | 4 +-
.../core/batch/BatchRequestParserTest.java | 3 +-
.../batch/parser/BatchParserCommonTest.java | 2 +-
.../batch/writer/BatchResponseWriterTest.java | 2 +-
.../tecsvc/processor/TechnicalProcessor.java | 39 ++++-
23 files changed, 598 insertions(+), 85 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchException.java
new file mode 100644
index 0000000..8da47a8
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchException.java
@@ -0,0 +1,65 @@
+/*
+ * 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.server.api.batch;
+
+import org.apache.olingo.server.api.ODataTranslatedException;
+
+public class BatchException extends ODataTranslatedException {
+ public static enum MessageKeys implements MessageKey {
+ INVALID_BOUNDARY,
+ INVALID_CHANGESET_METHOD,
+ INVALID_CONTENT,
+ INVALID_CONTENT_LENGTH,
+ INVALID_CONTENT_TRANSFER_ENCODING,
+ INVALID_CONTENT_TYPE,
+ INVALID_HEADER,
+ INVALID_HTTP_VERSION,
+ INVALID_METHOD,
+ INVALID_QUERY_OPERATION_METHOD,
+ INVALID_STATUS_LINE,
+ INVALID_URI,
+ MISSING_BLANK_LINE,
+ MISSING_BOUNDARY_DELIMITER,
+ MISSING_CLOSE_DELIMITER,
+ MISSING_CONTENT_ID,
+ MISSING_CONTENT_TRANSFER_ENCODING,
+ MISSING_CONTENT_TYPE,
+ MISSING_MANDATORY_HEADER, FORBIDDEN_HEADER, INVALID_CONTENT_ID;
+
+ @Override
+ public String getKey() {
+ return name();
+ }
+ }
+
+ private static final long serialVersionUID = -907752788975531134L;
+
+ public BatchException(final String developmentMessage, final MessageKey messageKey, final int lineNumber) {
+ this(developmentMessage, messageKey, "" + lineNumber);
+ }
+
+ public BatchException(final String developmentMessage, final MessageKey messageKey, final String... parameters) {
+ super(developmentMessage, messageKey, parameters);
+ }
+
+ @Override
+ protected String getBundleName() {
+ return DEFAULT_SERVER_BUNDLE_NAME;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
new file mode 100644
index 0000000..8e438cf
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
@@ -0,0 +1,36 @@
+/*
+ * 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.server.api.batch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+
+public interface BatchOperation {
+ public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException;
+
+ public ODataResponse handleODataRequest(ODataRequest request);
+
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request);
+
+ public void writeResponseParts(List<ODataResponsePart> batchResponses, ODataResponse response) throws BatchException,
+ IOException;
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
new file mode 100644
index 0000000..5a9518d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.server.api.processor;
+
+import java.util.List;
+
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchOperation;
+
+public interface BatchProcessor extends Processor {
+ void executeBatch(BatchOperation operation, ODataRequest requst, ODataResponse response);
+
+ List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests);
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index a13ef6f..48d75de 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -35,6 +35,8 @@ import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.api.processor.DefaultProcessor;
import org.apache.olingo.server.api.processor.EntitySetProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
@@ -52,6 +54,7 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourceProperty;
+import org.apache.olingo.server.core.batch.handler.BatchHandler;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
@@ -115,7 +118,7 @@ public class ODataHandler {
private void processInternal(final ODataRequest request, final ODataResponse response)
throws ODataHandlerException, UriParserException, UriValidationException, ContentNegotiatorException,
- ODataApplicationException, SerializerException {
+ ODataApplicationException, SerializerException, BatchException {
validateODataVersion(request, response);
uriInfo = new Parser().parseUri(request.getRawODataPath(), request.getRawQueryPath(), null,
@@ -158,6 +161,13 @@ public class ODataHandler {
case resource:
handleResourceDispatching(request, response);
break;
+ case batch:
+ BatchProcessor bp = selectProcessor(BatchProcessor.class);
+
+ final BatchHandler handler = new BatchHandler(this, request, bp, true);
+ handler.process(response);
+
+ break;
default:
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/BatchException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/BatchException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/BatchException.java
deleted file mode 100644
index aafe141..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/BatchException.java
+++ /dev/null
@@ -1,65 +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.server.core.batch;
-
-import org.apache.olingo.server.api.ODataTranslatedException;
-
-public class BatchException extends ODataTranslatedException {
- public static enum MessageKeys implements MessageKey {
- INVALID_BOUNDARY,
- INVALID_CHANGESET_METHOD,
- INVALID_CONTENT,
- INVALID_CONTENT_LENGTH,
- INVALID_CONTENT_TRANSFER_ENCODING,
- INVALID_CONTENT_TYPE,
- INVALID_HEADER,
- INVALID_HTTP_VERSION,
- INVALID_METHOD,
- INVALID_QUERY_OPERATION_METHOD,
- INVALID_STATUS_LINE,
- INVALID_URI,
- MISSING_BLANK_LINE,
- MISSING_BOUNDARY_DELIMITER,
- MISSING_CLOSE_DELIMITER,
- MISSING_CONTENT_ID,
- MISSING_CONTENT_TRANSFER_ENCODING,
- MISSING_CONTENT_TYPE,
- MISSING_MANDATORY_HEADER, FORBIDDEN_HEADER;
-
- @Override
- public String getKey() {
- return name();
- }
- }
-
- private static final long serialVersionUID = -907752788975531134L;
-
- public BatchException(final String developmentMessage, final MessageKey messageKey, final int lineNumber) {
- this(developmentMessage, messageKey, "" + lineNumber);
- }
-
- public BatchException(final String developmentMessage, final MessageKey messageKey, final String... parameters) {
- super(developmentMessage, messageKey, parameters);
- }
-
- @Override
- protected String getBundleName() {
- return DEFAULT_SERVER_BUNDLE_NAME;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
new file mode 100644
index 0000000..c348512
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
@@ -0,0 +1,145 @@
+/*
+ * 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.server.core.batch.handler;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+
+public class BatchChangeSetSorter {
+ private static final String REG_EX_REFERENCE = "\\$(.*)(/.*)?";
+
+ final List<ODataRequest> orderdList = new ArrayList<ODataRequest>();
+
+ private static Pattern referencePattern = Pattern.compile(REG_EX_REFERENCE);
+ private Set<String> knownContentId = new HashSet<String>();
+ private Map<String, List<ODataRequest>> requestContentIdMapping = new HashMap<String, List<ODataRequest>>();
+
+ public BatchChangeSetSorter(List<ODataRequest> requests) throws BatchException {
+ sort(requests);
+ }
+
+ public List<ODataRequest> getOrderdRequests() {
+ return orderdList;
+ }
+
+ private List<ODataRequest> sort(final List<ODataRequest> requests) throws BatchException {
+ extractUrlContentId(requests);
+ orderdList.addAll(getRequestsWithoutReferences());
+
+ boolean areRequestsProcessed = true;
+ while (requestsToProcessAvailable() && areRequestsProcessed) {
+ areRequestsProcessed = processRemainingRequests(orderdList);
+ }
+
+ if (requestsToProcessAvailable()) {
+ throw new BatchException("Invalid content id", MessageKeys.INVALID_CONTENT_ID, 0);
+ }
+
+ return orderdList;
+ }
+
+ private boolean requestsToProcessAvailable() {
+ return requestContentIdMapping.keySet().size() != 0;
+ }
+
+ private boolean processRemainingRequests(List<ODataRequest> orderdList) {
+ final List<ODataRequest> addedRequests = getRemainingRequestsWithKownContentId();
+ addRequestsToKnownContentIds(addedRequests);
+ orderdList.addAll(addedRequests);
+
+ return addedRequests.size() != 0;
+ }
+
+ private List<ODataRequest> getRemainingRequestsWithKownContentId() {
+ List<ODataRequest> result = new ArrayList<ODataRequest>();
+
+ for (String contextId : knownContentId) {
+ List<ODataRequest> processedRequests = requestContentIdMapping.get(contextId);
+ if (processedRequests != null && processedRequests.size() != 0) {
+ result.addAll(processedRequests);
+ requestContentIdMapping.remove(contextId);
+ }
+ }
+
+ return result;
+ }
+
+ private List<ODataRequest> getRequestsWithoutReferences() {
+ final List<ODataRequest> requestsWithoutReference = requestContentIdMapping.get(null);
+ requestContentIdMapping.remove(null);
+
+ addRequestsToKnownContentIds(requestsWithoutReference);
+ return requestsWithoutReference;
+ }
+
+ private void addRequestsToKnownContentIds(List<ODataRequest> requestsWithoutReference) {
+ for (ODataRequest request : requestsWithoutReference) {
+ final String contentId = getContentIdFromHeader(request);
+ if (contentId != null) {
+ knownContentId.add(contentId);
+ }
+ }
+ }
+
+ private String getContentIdFromHeader(ODataRequest request) {
+ return request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
+ }
+
+ private void extractUrlContentId(List<ODataRequest> requests) {
+ for (ODataRequest request : requests) {
+ final String reference = getReferenceInURI(request);
+ addRequestToMapping(reference, request);
+ }
+ }
+
+ private void addRequestToMapping(final String reference, final ODataRequest request) {
+ List<ODataRequest> requestList = requestContentIdMapping.get(reference);
+ requestList = (requestList == null) ? new ArrayList<ODataRequest>() : requestList;
+
+ requestList.add(request);
+ requestContentIdMapping.put(reference, requestList);
+ }
+
+ public static String getReferenceInURI(ODataRequest request) {
+ Matcher matcher = referencePattern.matcher(removeFollingPathSegments(request.getRawODataPath()));
+ return (matcher.matches()) ? matcher.group(1) : null;
+ }
+
+ private static String removeFollingPathSegments(String rawODataPath) {
+ final int indexOfSlash = rawODataPath.indexOf("/");
+ return (indexOfSlash != -1) ? rawODataPath.substring(0, indexOfSlash) : rawODataPath;
+ }
+
+ public static void replaceContentIdReference(ODataRequest request, String contentId, String resourceUri) {
+ final String newUri = request.getRawODataPath().replace("$" + contentId, resourceUri);
+ request.setRawODataPath(newUri);
+ request.setRawRequestUri(request.getRawBaseUri() + "/" + newUri);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
new file mode 100644
index 0000000..01a149e
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
@@ -0,0 +1,68 @@
+/*
+ * 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.server.core.batch.handler;
+
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.core.ODataHandler;
+import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+
+public class BatchHandler {
+ private final BatchOperation operation;
+ private final BatchProcessor batchProcessor;
+ private ODataRequest request;
+
+ public BatchHandler(final ODataHandler oDataHandler, final ODataRequest request, final BatchProcessor batchProcessor,
+ final boolean isStrict) {
+
+ this.request = request;
+ this.batchProcessor = batchProcessor;
+ operation = new BatchOperationImpl(oDataHandler, request, batchProcessor, isStrict);
+ }
+
+ public void process(ODataResponse response) throws BatchException {
+ validateRequest();
+ batchProcessor.executeBatch(operation, request, response);
+ }
+
+ private void validateRequest() throws BatchException {
+ validateHttpMethod();
+ validateContentType();
+ }
+
+ private void validateContentType() throws BatchException {
+ final String contentType = request.getHeader(HttpHeader.CONTENT_TYPE);
+
+ if(contentType == null || !BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches()) {
+ throw new BatchException("Invalid content type", MessageKeys.INVALID_CONTENT_TYPE, 0);
+ }
+ }
+
+ private void validateHttpMethod() throws BatchException {
+ if(request.getMethod() != HttpMethod.POST) {
+ throw new BatchException("Invalid HTTP method", MessageKeys.INVALID_METHOD, 0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
new file mode 100644
index 0000000..bc148f0
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
@@ -0,0 +1,74 @@
+/*
+ * 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.server.core.batch.handler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
+import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.core.ODataHandler;
+import org.apache.olingo.server.core.batch.parser.BatchParser;
+import org.apache.olingo.server.core.batch.writer.BatchResponseWriter;
+
+public class BatchOperationImpl implements BatchOperation {
+ private final BatchPartHandler partHandler;
+ private final BatchResponseWriter writer;
+ private final BatchParser parser;
+
+ public BatchOperationImpl(ODataHandler oDataHandler, ODataRequest request, BatchProcessor batchProcessor,
+ final boolean isStrict) {
+ partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
+ writer = new BatchResponseWriter();
+ parser = new BatchParser(getContentType(request), request.getRawBaseUri(),
+ request.getRawServiceResolutionUri(), isStrict);
+ }
+
+ @Override
+ public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException {
+ return parser.parseBatchRequest(in);
+ }
+
+ @Override
+ public ODataResponse handleODataRequest(ODataRequest request) {
+ return partHandler.handleODataRequest(request);
+ }
+
+ @Override
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request) {
+ return partHandler.handleBatchRequest(request);
+ }
+
+ @Override
+ public void writeResponseParts(List<ODataResponsePart> batchResponses, ODataResponse response) throws BatchException,
+ IOException {
+ writer.toODataResponse(batchResponses, response);
+ }
+
+ private String getContentType(ODataRequest request) {
+ return request.getHeader(HttpHeader.CONTENT_TYPE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
new file mode 100644
index 0000000..a78d585
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -0,0 +1,66 @@
+/*
+ * 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.server.core.batch.handler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
+import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.core.ODataHandler;
+import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+
+public class BatchPartHandler {
+
+ private ODataHandler oDataHandler;
+ private BatchProcessor batchProcessor;
+ private BatchOperation batchOperation;
+
+ public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor,
+ final BatchOperation batchOperation) {
+ this.oDataHandler = oDataHandler;
+ this.batchProcessor = processor;
+ this.batchOperation = batchOperation;
+ }
+
+ public ODataResponse handleODataRequest(ODataRequest request) {
+ final ODataResponse response = oDataHandler.process(request);
+ response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, request.getHeader(BatchParserCommon.HTTP_CONTENT_ID));
+
+ return response;
+ }
+
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request) {
+ final List<ODataResponse> responses = new ArrayList<ODataResponse>();
+
+ if (request.isChangeSet()) {
+ responses.addAll(batchProcessor.executeChangeSet(batchOperation, request.getRequests()));
+ return new ODataResponsePartImpl(responses, true);
+ } else {
+ responses.add(handleODataRequest(request.getRequests().get(0)));
+ return new ODataResponsePartImpl(responses, false);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
new file mode 100644
index 0000000..da52a37
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.core.batch.handler;
+
+import java.util.List;
+
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
+
+public class ODataResponsePartImpl implements ODataResponsePart {
+ private List<ODataResponse> responses;
+ private boolean isChangeSet;
+
+ public ODataResponsePartImpl(List<ODataResponse> responses, boolean isChangeSet) {
+ this.responses = responses;
+ this.isChangeSet = isChangeSet;
+ }
+
+ @Override
+ public List<ODataResponse> getResponses() {
+ return responses;
+ }
+
+ @Override
+ public boolean isChangeSet() {
+ return isChangeSet;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchBodyPart.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchBodyPart.java
index c2d2e0f..2b93783 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchBodyPart.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchBodyPart.java
@@ -22,7 +22,7 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.server.core.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
public class BatchBodyPart implements BatchPart {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchChangeSetPart.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchChangeSetPart.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchChangeSetPart.java
index 1d0bd6f..aaa2660 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchChangeSetPart.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchChangeSetPart.java
@@ -20,7 +20,7 @@ package org.apache.olingo.server.core.batch.parser;
import java.util.List;
-import org.apache.olingo.server.core.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
public class BatchChangeSetPart extends BatchQueryOperation {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
index 37b1a9c..75c0084 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
@@ -25,9 +25,9 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchParserResult;
import org.apache.olingo.server.api.batch.BatchRequestPart;
-import org.apache.olingo.server.core.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.server.core.batch.transformator.BatchRequestTransformator;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
index e2dc5e5..43a09b6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
@@ -29,7 +29,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.olingo.commons.api.http.HttpContentType;
-import org.apache.olingo.server.core.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
public class BatchParserCommon {
@@ -186,7 +186,8 @@ public class BatchParserCommon {
}
public static void consumeBlankLine(final List<Line> remainingMessage, final boolean isStrict) throws BatchException {
- if (remainingMessage.size() > 0 && remainingMessage.get(0).toString().matches("\\s*\r\n\\s*")) {
+ //TODO is \r\n to strict?
+ if (remainingMessage.size() > 0 && remainingMessage.get(0).toString().matches("\\s*(\r\n|\n)\\s*")) {
remainingMessage.remove(0);
} else {
if (isStrict) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchQueryOperation.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchQueryOperation.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchQueryOperation.java
index 5ff7faf..6a5309e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchQueryOperation.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchQueryOperation.java
@@ -20,7 +20,7 @@ package org.apache.olingo.server.core.batch.parser;
import java.util.List;
-import org.apache.olingo.server.core.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
public class BatchQueryOperation implements BatchPart {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
index 02c8118..94d5226 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
@@ -27,9 +27,9 @@ import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchParserResult;
-import org.apache.olingo.server.core.batch.BatchException;
-import org.apache.olingo.server.core.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
import org.apache.olingo.server.core.batch.parser.BatchBodyPart;
import org.apache.olingo.server.core.batch.parser.BatchChangeSetPart;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
@@ -84,10 +84,10 @@ public class BatchRequestTransformator implements BatchTransformator {
final HeaderField contentIdRequest = getContentId(request);
if (contentIdChangeRequestPart == null && contentIdRequest == null) {
- throw new BatchException("Missing content type", MessageKeys.MISSING_CONTENT_ID, changeRequestPart.getHeaders()
+ throw new BatchException("Missing content id", MessageKeys.MISSING_CONTENT_ID, changeRequestPart.getHeaders()
.getLineNumber());
} else if (contentIdChangeRequestPart != null) {
- request.getHeaders().replaceHeaderField(contentIdChangeRequestPart);
+ request.getHeaders().replaceHeaderField(contentIdChangeRequestPart);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformator.java
index becb6c7..286c0cc 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformator.java
@@ -20,8 +20,8 @@ package org.apache.olingo.server.core.batch.transformator;
import java.util.List;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchParserResult;
-import org.apache.olingo.server.core.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BatchBodyPart;
public interface BatchTransformator {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
index a351cca..c9da563 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
@@ -28,8 +28,8 @@ import java.util.regex.Pattern;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.core.batch.BatchException;
-import org.apache.olingo.server.core.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.server.core.batch.parser.Header;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
index a063747..812ea8b 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
@@ -31,9 +31,9 @@ import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.ODataResponsePart;
-import org.apache.olingo.server.core.batch.BatchException;
-import org.apache.olingo.server.core.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
index 1d68307..c9778e3 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
@@ -33,8 +33,9 @@ import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchRequestPart;
-import org.apache.olingo.server.core.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
import org.apache.olingo.server.core.batch.parser.BatchParser;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/parser/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/parser/BatchParserCommonTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/parser/BatchParserCommonTest.java
index 6fb0796..e3a1acc 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/parser/BatchParserCommonTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/parser/BatchParserCommonTest.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.server.core.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.server.core.batch.parser.Header;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
index ec45a22..b7169b9 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
@@ -30,8 +30,8 @@ import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.ODataResponsePart;
-import org.apache.olingo.server.core.batch.BatchException;
import org.apache.olingo.server.core.batch.StringUtil;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15bd1526/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index d88a02f..b59c92e 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -19,11 +19,14 @@
package org.apache.olingo.server.tecsvc.processor;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
@@ -46,6 +49,11 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
+import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.processor.EntitySetProcessor;
import org.apache.olingo.server.api.processor.PropertyProcessor;
@@ -66,7 +74,7 @@ import org.apache.olingo.server.tecsvc.data.DataProvider;
/**
* Technical Processor which provides currently implemented processor functionality.
*/
-public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
+public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor, BatchProcessor {
private OData odata;
private DataProvider dataProvider;
@@ -326,4 +334,33 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
}
}
}
+
+ @Override
+ public void executeBatch(BatchOperation operation, ODataRequest requst, ODataResponse response) {
+ try {
+ final List<BatchRequestPart> parts = operation.parseBatchRequest(requst.getBody());
+ final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
+
+ for(BatchRequestPart part : parts) {
+ responseParts.add(operation.handleBatchRequest(part));
+ }
+
+ operation.writeResponseParts(responseParts, response);
+ } catch (BatchException e) {
+ throw new ODataRuntimeException(e);
+ } catch (IOException e) {
+ throw new ODataRuntimeException(e);
+ }
+ }
+
+ @Override
+ public List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests) {
+ List<ODataResponse> responses = new ArrayList<ODataResponse>();
+
+ for(ODataRequest request : requests) {
+ responses.add(operation.handleODataRequest(request));
+ }
+
+ return responses;
+ }
}
[4/9] olingo-odata4 git commit: Batch handler clean up
Posted by ch...@apache.org.
Batch handler clean up
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/6c7d11f4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/6c7d11f4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/6c7d11f4
Branch: refs/heads/olingo472
Commit: 6c7d11f4d77cb3d95684543b79c039c11990c63a
Parents: 0bd3295
Author: Christian Holzer <c....@sap.com>
Authored: Wed Nov 5 16:02:12 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:57 2014 +0100
----------------------------------------------------------------------
.../apache/olingo/server/core/ODataHandler.java | 6 +-
.../batch/handler/BatchChangeSetSorter.java | 35 ++++++------
.../server/core/batch/handler/BatchHandler.java | 40 +++++++-------
.../core/batch/handler/BatchPartHandler.java | 17 +++++-
.../server/core/batch/handler/UriMapping.java | 34 ------------
.../batch/handler/MockedBatchHandlerTest.java | 58 ++++++++------------
6 files changed, 79 insertions(+), 111 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 48d75de..af092cf 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -162,10 +162,10 @@ public class ODataHandler {
handleResourceDispatching(request, response);
break;
case batch:
- BatchProcessor bp = selectProcessor(BatchProcessor.class);
+ final BatchProcessor bp = selectProcessor(BatchProcessor.class);
+ final BatchHandler handler = new BatchHandler(this, bp);
- final BatchHandler handler = new BatchHandler(this, request, bp, true);
- handler.process(response);
+ handler.process(request, response, true);
break;
default:
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
index f8ac653..408159e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
@@ -38,7 +38,7 @@ public class BatchChangeSetSorter {
final List<ODataRequest> orderdList = new ArrayList<ODataRequest>();
private static Pattern referencePattern = Pattern.compile(REG_EX_REFERENCE);
- private Set<String> knownContentId = new HashSet<String>();
+ private Set<String> knownContentIds = new HashSet<String>();
private Map<String, List<ODataRequest>> requestReferenceMapping = new HashMap<String, List<ODataRequest>>();
public BatchChangeSetSorter(List<ODataRequest> requests) throws BatchException {
@@ -52,15 +52,19 @@ public class BatchChangeSetSorter {
private List<ODataRequest> sort(final List<ODataRequest> requests) throws BatchException {
extractUrlReference(requests);
+ // Add requests without reference (roots)
final List<ODataRequest> requestsWithoutReferences = getRequestsWithoutReferences();
orderdList.addAll(requestsWithoutReferences);
addRequestsToKnownContentIds(requestsWithoutReferences);
+ // Find all requests which can be processed (parent request has been processed)
+ // Compare level order
boolean areRequestsProcessed = true;
while (requestsToProcessAvailable() && areRequestsProcessed) {
- areRequestsProcessed = processRemainingRequests(orderdList);
+ areRequestsProcessed = processNextLevel();
}
+ // Check if there are some requests which are not connected to a tree
if (requestsToProcessAvailable()) {
throw new BatchException("Invalid content id", MessageKeys.INVALID_CONTENT_ID, 0);
}
@@ -72,7 +76,7 @@ public class BatchChangeSetSorter {
return requestReferenceMapping.keySet().size() != 0;
}
- private boolean processRemainingRequests(List<ODataRequest> orderdList) {
+ private boolean processNextLevel() {
final List<ODataRequest> addedRequests = getRemainingRequestsWithKownContentId();
addRequestsToKnownContentIds(addedRequests);
orderdList.addAll(addedRequests);
@@ -83,10 +87,10 @@ public class BatchChangeSetSorter {
private List<ODataRequest> getRemainingRequestsWithKownContentId() {
List<ODataRequest> result = new ArrayList<ODataRequest>();
- for (String contextId : knownContentId) {
- List<ODataRequest> processedRequests = requestReferenceMapping.get(contextId);
- if (processedRequests != null && processedRequests.size() != 0) {
- result.addAll(processedRequests);
+ for (String contextId : knownContentIds) {
+ final List<ODataRequest> requestsToProcess = requestReferenceMapping.get(contextId);
+ if (requestsToProcess != null && requestsToProcess.size() != 0) {
+ result.addAll(requestsToProcess);
requestReferenceMapping.remove(contextId);
}
}
@@ -105,7 +109,7 @@ public class BatchChangeSetSorter {
for (ODataRequest request : requestsWithoutReference) {
final String contentId = getContentIdFromHeader(request);
if (contentId != null) {
- knownContentId.add(contentId);
+ knownContentIds.add(contentId);
}
}
}
@@ -130,18 +134,17 @@ public class BatchChangeSetSorter {
}
public static String getReferenceInURI(ODataRequest request) {
- Matcher matcher = referencePattern.matcher(removeFollingPathSegments(removeFirstSplash(request.getRawODataPath())));
+ Matcher matcher = referencePattern.matcher(removeSlash(removeSlash(request.getRawODataPath(), true), false));
return (matcher.matches()) ? matcher.group(1) : null;
}
- private static String removeFirstSplash(String rawODataPath) {
+ private static String removeSlash(String rawODataPath, boolean first) {
final int indexOfSlash = rawODataPath.indexOf("/");
- return (indexOfSlash == 0) ? rawODataPath.substring(1) : rawODataPath;
- }
-
- private static String removeFollingPathSegments(String rawODataPath) {
- final int indexOfSlash = rawODataPath.indexOf("/");
- return (indexOfSlash != -1) ? rawODataPath.substring(0, indexOfSlash) : rawODataPath;
+ if(first) {
+ return (indexOfSlash == 0) ? rawODataPath.substring(1) : rawODataPath;
+ } else {
+ return (indexOfSlash != -1) ? rawODataPath.substring(0, indexOfSlash) : rawODataPath;
+ }
}
public static void replaceContentIdReference(ODataRequest request, String contentId, String resourceUri) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
index 01a149e..df16c90 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchHandler.java
@@ -6,9 +6,9 @@
* 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
@@ -30,38 +30,38 @@ import org.apache.olingo.server.core.ODataHandler;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
public class BatchHandler {
- private final BatchOperation operation;
private final BatchProcessor batchProcessor;
- private ODataRequest request;
+ private final ODataHandler oDataHandler;
+
+ public BatchHandler(final ODataHandler oDataHandler, final BatchProcessor batchProcessor) {
- public BatchHandler(final ODataHandler oDataHandler, final ODataRequest request, final BatchProcessor batchProcessor,
- final boolean isStrict) {
-
- this.request = request;
this.batchProcessor = batchProcessor;
- operation = new BatchOperationImpl(oDataHandler, request, batchProcessor, isStrict);
+ this.oDataHandler = oDataHandler;
}
- public void process(ODataResponse response) throws BatchException {
- validateRequest();
+ public void process(final ODataRequest request, final ODataResponse response, final boolean isStrict)
+ throws BatchException {
+ validateRequest(request);
+
+ final BatchOperation operation = new BatchOperationImpl(oDataHandler, request, batchProcessor, isStrict);
batchProcessor.executeBatch(operation, request, response);
}
-
- private void validateRequest() throws BatchException {
- validateHttpMethod();
- validateContentType();
+
+ private void validateRequest(final ODataRequest request) throws BatchException {
+ validateHttpMethod(request);
+ validateContentType(request);
}
- private void validateContentType() throws BatchException {
+ private void validateContentType(final ODataRequest request) throws BatchException {
final String contentType = request.getHeader(HttpHeader.CONTENT_TYPE);
-
- if(contentType == null || !BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches()) {
+
+ if (contentType == null || !BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches()) {
throw new BatchException("Invalid content type", MessageKeys.INVALID_CONTENT_TYPE, 0);
}
}
- private void validateHttpMethod() throws BatchException {
- if(request.getMethod() != HttpMethod.POST) {
+ private void validateHttpMethod(final ODataRequest request) throws BatchException {
+ if (request.getMethod() != HttpMethod.POST) {
throw new BatchException("Invalid HTTP method", MessageKeys.INVALID_METHOD, 0);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
index c678355..5bec30b 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -58,7 +58,8 @@ public class BatchPartHandler {
final UriMapping mapping = replaceReference(request, requestPart);
response = oDataHandler.process(request);
-
+
+ // Store resource URI
final String resourceUri = getODataPath(request, response);
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
@@ -67,6 +68,7 @@ public class BatchPartHandler {
response = oDataHandler.process(request);
}
+ // Add content id to response
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
if(contentId != null) {
response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId);
@@ -85,7 +87,7 @@ public class BatchPartHandler {
resourceUri = uri.getRawODataPath();
} else {
// Update, Upsert (PUT, PATCH, Delete)
- // These methods still addresses a given URI, so we use the URI given by the request
+ // These methods still addresses a given resource, so we use the URI given by the request
resourceUri = request.getRawODataPath();
}
@@ -140,4 +142,15 @@ public class BatchPartHandler {
return new ODataResponsePartImpl(responses, true);
}
+ private static class UriMapping {
+ private Map<String, String> uriMapping = new HashMap<String, String>();
+
+ public void addMapping(final String contentId, final String uri) {
+ uriMapping.put(contentId, uri);
+ }
+
+ public String getUri(final String contentId) {
+ return uriMapping.get(contentId);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
deleted file mode 100644
index 0123320..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
+++ /dev/null
@@ -1,34 +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.server.core.batch.handler;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class UriMapping {
- private Map<String, String> uriMapping = new HashMap<String, String>();
-
- public void addMapping(final String contentId, final String uri) {
- uriMapping.put(contentId, uri);
- }
-
- public String getUri(final String contentId) {
- return uriMapping.get(contentId);
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6c7d11f4/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
index ac111e0..d772fbc 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -61,9 +61,19 @@ public class MockedBatchHandlerTest {
private static final String BATCH_REQUEST_URI = "http://localhost:8080/odata/$batch";
private static final String BASE_URI = "http://localhost:8080/odata";
private static final String CRLF = "\r\n";
- private ODataHandler handler;
+ private ODataHandler oDataHandler;
+ private BatchHandler batchHandler;
private int entityCounter = 1;
+ @Before
+ public void setup() {
+ final BatchProcessor batchProcessor = new BatchTestProcessorImpl();
+
+ entityCounter = 1;
+ oDataHandler = mock(ODataHandler.class);
+ batchHandler = new BatchHandler(oDataHandler, batchProcessor);
+ }
+
@Test
public void test() throws BatchException, IOException {
final String content = "--batch_12345" + CRLF
@@ -130,9 +140,9 @@ public class MockedBatchHandlerTest {
+ "--batch_12345--";
final Map<String, List<String>> header = getMimeHeader();
final ODataResponse response = new ODataResponse();
- final BatchHandler batchHandler = buildBatchHandler(content, header);
+ final ODataRequest request = buildODataRequest(content, header);
- batchHandler.process(response);
+ batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
@@ -244,9 +254,9 @@ public class MockedBatchHandlerTest {
+ "--batch_12345--";
final Map<String, List<String>> header = getMimeHeader();
final ODataResponse response = new ODataResponse();
- final BatchHandler batchHandler = buildBatchHandler(content, header);
+ final ODataRequest request = buildODataRequest(content, header);
- batchHandler.process(response);
+ batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
@@ -365,9 +375,9 @@ public class MockedBatchHandlerTest {
final Map<String, List<String>> header = getMimeHeader();
final ODataResponse response = new ODataResponse();
- final BatchHandler batchHandler = buildBatchHandler(content, header);
+ final ODataRequest request = buildODataRequest(content, header);
- batchHandler.process(response);
+ batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
@@ -418,12 +428,6 @@ public class MockedBatchHandlerTest {
assertEquals(45, line);
}
- @Before
- public void setup() {
- handler = null;
- entityCounter = 1;
- }
-
private String checkChangeSetPartHeader(final List<String> response, int line) {
assertEquals(CRLF, response.get(line++));
assertTrue(response.get(line++).contains("--changeset_"));
@@ -442,7 +446,6 @@ public class MockedBatchHandlerTest {
/*
* Helper methods
*/
-
private Map<String, List<String>> getMimeHeader() {
final Map<String, List<String>> header = new HashMap<String, List<String>>();
header.put(HttpHeader.CONTENT_TYPE, Arrays.asList(new String[] { BATCH_CONTENT_TYPE }));
@@ -450,24 +453,7 @@ public class MockedBatchHandlerTest {
return header;
}
- private BatchHandler buildBatchHandler(final String content, Map<String, List<String>> header) throws BatchException,
- UnsupportedEncodingException {
-
- final ODataRequest request = buildODataRequest(content, header);
- final ODataHandler oDataHandler = buildODataHandler(request);
- final BatchProcessor batchProcessor = new BatchProcessorImpl();
-
- return new BatchHandler(oDataHandler, request, batchProcessor, true);
- }
-
- private ODataHandler buildODataHandler(ODataRequest request) {
- handler = mock(ODataHandler.class);
- when(handler.process(request)).thenCallRealMethod();
-
- return handler;
- }
-
- private ODataRequest buildODataRequest(String content, Map<String, List<String>> header)
+ private ODataRequest buildODataRequest(final String content, final Map<String, List<String>> header)
throws UnsupportedEncodingException {
final ODataRequest request = new ODataRequest();
@@ -490,7 +476,7 @@ public class MockedBatchHandlerTest {
/**
* Batch processor
*/
- private class BatchProcessorImpl implements BatchProcessor {
+ private class BatchTestProcessorImpl implements BatchProcessor {
@Override
public void init(OData odata, ServiceMetadata serviceMetadata) {}
@@ -500,8 +486,8 @@ public class MockedBatchHandlerTest {
List<ODataResponse> responses = new ArrayList<ODataResponse>();
for (ODataRequest request : requests) {
- // Mock the processor of the changeset requests
- when(handler.process(request)).then(new Answer<ODataResponse>() {
+ // Mock the processor for a given requests
+ when(oDataHandler.process(request)).then(new Answer<ODataResponse>() {
@Override
public ODataResponse answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
@@ -565,7 +551,7 @@ public class MockedBatchHandlerTest {
// Entity Collection
oDataPath = parts[1];
} else {
- // Navigationproperty
+ // Navigation property
final String navProperty = parts[parts.length - 1];
if (navProperty.equals("NavPropertyETTwoPrimMany")) {
[7/9] olingo-odata4 git commit: Batch IT test case
Posted by ch...@apache.org.
Batch IT test case
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/4ff5fb9c
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/4ff5fb9c
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/4ff5fb9c
Branch: refs/heads/olingo472
Commit: 4ff5fb9c8ce045e87657dec69f76db52001f1508
Parents: 5f4eb03
Author: Christian Holzer <c....@sap.com>
Authored: Mon Nov 10 17:30:18 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:11:00 2014 +0100
----------------------------------------------------------------------
.../fit/tecsvc/client/BatchClientITCase.java | 459 +++++++++++++++++++
.../server/api/batch/ODataResponsePart.java | 52 ++-
.../server/api/processor/BatchProcessor.java | 3 +-
.../server/api/processor/DefaultProcessor.java | 93 +++-
.../core/batch/handler/BatchPartHandler.java | 7 +-
.../batch/handler/ODataResponsePartImpl.java | 44 --
.../core/batch/parser/BatchParserCommon.java | 8 -
.../core/batch/writer/BatchResponseWriter.java | 2 +-
.../batch/writer/ODataResponsePartImpl.java | 44 --
.../core/batch/BatchRequestParserTest.java | 28 +-
.../batch/handler/MockedBatchHandlerTest.java | 4 +-
.../batch/writer/BatchResponseWriterTest.java | 8 +-
12 files changed, 627 insertions(+), 125 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
new file mode 100644
index 0000000..f2e1ab6
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
@@ -0,0 +1,459 @@
+/*
+ * 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.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.communication.request.batch.BatchManager;
+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.v4.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.v4.UpdateType;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
+import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.uri.v4.URIBuilder;
+import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
+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.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.apache.olingo.fit.v4.AbstractTestITCase;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class BatchClientITCase extends AbstractTestITCase {
+ private final static String ACCEPT = ContentType.APPLICATION_OCTET_STREAM.toContentTypeString();
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI;
+
+ @Before
+ public void setup() {
+ client.getConfiguration().setContinueOnError(false);
+ }
+
+ @Test
+ public void emptyBatchRequest() {
+ // create your request
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+
+ final BatchManager payload = request.payloadManager();
+ final ODataBatchResponse response = payload.getResponse();
+
+ assertEquals(202, response.getStatusCode());
+ assertEquals("Accepted", response.getStatusMessage());
+
+ final Iterator<ODataBatchResponseItem> iter = response.getBody();
+ assertFalse(iter.hasNext());
+ }
+
+ @Test
+ public void getBatchRequest() {
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+
+ final BatchManager payload = request.payloadManager();
+
+ // create new request
+ appendGetRequest(payload, "ESAllPrim", 32767);
+
+ // Fetch result
+ final ODataBatchResponse response = payload.getResponse();
+
+ assertEquals(202, response.getStatusCode());
+ assertEquals("Accepted", response.getStatusMessage());
+
+ final Iterator<ODataBatchResponseItem> iter = response.getBody();
+ assertTrue(iter.hasNext());
+
+ ODataBatchResponseItem item = iter.next();
+ assertFalse(item.isChangeset());
+
+ ODataResponse oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
+ assertEquals(1, oDataResonse.getHeader("OData-Version").size());
+ assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
+ assertEquals(1, oDataResonse.getHeader("Content-Length").size());
+ assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
+ }
+
+ @Test
+ public void testErrorWithoutContinueOnErrorPreferHeader() {
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+
+ final BatchManager payload = request.payloadManager();
+
+ appendGetRequest(payload, "ESAllPrim", 32767); // Without error
+ appendGetRequest(payload, "ESAllPrim", 42); // Error ( Key does not exist )
+ appendGetRequest(payload, "ESAllPrim", 0); // Without error
+
+ // Fetch result
+ final ODataBatchResponse response = payload.getResponse();
+ assertEquals(202, response.getStatusCode());
+
+ final Iterator<ODataBatchResponseItem> iter = response.getBody();
+
+ // Check first get request
+ assertTrue(iter.hasNext());
+ ODataBatchResponseItem item = iter.next();
+ assertFalse(item.isChangeset());
+
+ ODataResponse oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
+ assertEquals(1, oDataResonse.getHeader("OData-Version").size());
+ assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
+ assertEquals(1, oDataResonse.getHeader("Content-Length").size());
+ assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
+
+ // Check second get request
+ assertTrue(iter.hasNext());
+ item = iter.next();
+ assertFalse(item.isChangeset());
+
+ oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResonse.getStatusCode());
+
+ // Check if third request is available
+ assertFalse(iter.hasNext());
+ }
+
+ @Test
+ public void testErrorWithContinueOnErrorPreferHeader() {
+ client.getConfiguration().setContinueOnError(true);
+
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+
+ final BatchManager payload = request.payloadManager();
+
+ appendGetRequest(payload, "ESAllPrim", 32767); // Without error
+ appendGetRequest(payload, "ESAllPrim", 42); // Error ( Key does not exist )
+ appendGetRequest(payload, "ESAllPrim", 0); // Without error
+
+ // Fetch result
+ final ODataBatchResponse response = payload.getResponse();
+ assertEquals(202, response.getStatusCode());
+
+ final Iterator<ODataBatchResponseItem> bodyIterator = response.getBody();
+
+ // Check first get request
+ assertTrue(bodyIterator.hasNext());
+ ODataBatchResponseItem item = bodyIterator.next();
+ assertFalse(item.isChangeset());
+
+ ODataResponse oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
+ assertEquals(1, oDataResonse.getHeader("OData-Version").size());
+ assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
+ assertEquals(1, oDataResonse.getHeader("Content-Length").size());
+ assertEquals("538", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
+
+ // Check second get request
+ assertTrue(bodyIterator.hasNext());
+ item = bodyIterator.next();
+ assertFalse(item.isChangeset());
+
+ oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResonse.getStatusCode());
+
+ // Check if third request is available
+ assertTrue(bodyIterator.hasNext());
+ item = bodyIterator.next();
+ assertFalse(item.isChangeset());
+
+ oDataResonse = item.next();
+ assertNotNull(oDataResonse);
+ assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
+ assertEquals(1, oDataResonse.getHeader("OData-Version").size());
+ assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
+ assertEquals(1, oDataResonse.getHeader("Content-Length").size());
+ assertEquals("446", oDataResonse.getHeader("Content-Length").toArray()[0]);
+ assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ @Ignore("Not implemented")
+ public void changesetWithReferences() throws EdmPrimitiveTypeException {
+ // create your request
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+ final BatchManager streamManager = request.payloadManager();
+
+ final ODataChangeset changeset = streamManager.addChangeset();
+ ODataEntity esAllPrim = newESAllPrim((short) 23);
+
+ final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim");
+
+ // add create request
+ final ODataEntityCreateRequest<ODataEntity> createReq =
+ client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), esAllPrim);
+
+ changeset.addRequest(createReq);
+
+ // retrieve request reference
+ int createRequestRef = changeset.getLastContentId();
+
+ // add update request
+ final ODataEntity customerChanges = client.getObjectFactory().newEntity(esAllPrim.getTypeName());
+ customerChanges.addLink(client.getObjectFactory().newEntitySetNavigationLink(
+ "NavPropertyETTwoPrimMany",
+ client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("NavPropertyETTwoPrimMany").
+ appendKeySegment(new HashMap<String, Object>() {
+ private static final long serialVersionUID = 3109256773218160485L;
+
+ {
+ put("PropertyInt16", 4242);
+ put("PropertyString", "Test");
+ }
+ }).build()));
+
+ final ODataEntityUpdateRequest<ODataEntity> updateReq = client.getCUDRequestFactory().getEntityUpdateRequest(
+ URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges);
+
+ changeset.addRequest(updateReq);
+
+ final ODataBatchResponse response = streamManager.getResponse();
+ assertEquals(200, response.getStatusCode());
+ assertEquals("OK", response.getStatusMessage());
+
+ // verify response payload ...
+ final Iterator<ODataBatchResponseItem> iter = response.getBody();
+
+ final ODataBatchResponseItem item = iter.next();
+ assertTrue(item instanceof ODataChangesetResponseItem);
+
+ final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item;
+
+ ODataResponse res = chgitem.next();
+ assertEquals(201, res.getStatusCode());
+ assertTrue(res instanceof ODataEntityCreateResponse);
+
+ esAllPrim = ((ODataEntityCreateResponse<ODataEntity>) res).getBody();
+ final ODataEntitySetRequest<ODataEntitySet> req = client.getRetrieveRequestFactory().getEntitySetRequest(
+ URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString() + "/NavPropertyETTwoPrimMany"));
+
+ assertEquals(Integer.valueOf(4242),
+ req.execute().getBody().getEntities().get(0).getProperty("PropertyInt16").getPrimitiveValue().
+ toCastValue(Integer.class));
+
+ res = chgitem.next();
+ assertEquals(204, res.getStatusCode());
+ assertTrue(res instanceof ODataEntityUpdateResponse);
+
+ // clean ...
+ assertEquals(204, client.getCUDRequestFactory().getDeleteRequest(
+ URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString())).execute().
+ getStatusCode());
+
+ try {
+ client.getRetrieveRequestFactory().getEntityRequest(
+ URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString())).
+ execute().getBody();
+ fail("Entity not deleted");
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ private ODataEntity newESAllPrim(short id) {
+ final ODataEntity entity = getClient().getObjectFactory().
+ newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim"));
+
+ entity.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyInt16",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildInt16(id)));
+
+ entity.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyDouble",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
+
+ return entity;
+ }
+
+ //TODO If write support is implemented, remove ignore tag
+ @Test
+ @Ignore("Not implemented")
+ public void changesetBatchRequest() {
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+ request.setAccept(ACCEPT);
+
+ final BatchManager payload = request.payloadManager();
+ // -----------------------------
+ // - Append get request
+ // -----------------------------
+ appendGetRequest(payload, "ESAllPrim", 32767); // Without error
+
+ // -----------------------------
+ // - Append change set
+ // -----------------------------
+ final ODataChangeset changeset = payload.addChangeset();
+
+ // ------------------------
+ // POST request (Insert)
+ URIBuilder targetURI =
+ client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim");
+ URI editLink = targetURI.build();
+
+ ODataEntity post = client.getObjectFactory().newEntity(
+ new FullQualifiedName("olingo.odata.test1.ESAllPrim"));
+
+ post.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyInt16",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 15)));
+
+ post.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyDouble",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
+
+ final ODataEntityCreateRequest<ODataEntity> createRequest =
+ client.getCUDRequestFactory().getEntityCreateRequest(editLink, post);
+ createRequest.setFormat(ODataFormat.JSON_FULL_METADATA);
+ createRequest.setContentType("1");
+
+ changeset.addRequest(createRequest);
+
+ // ------------------------
+ // Patch request (Update)
+ targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(0);
+ editLink = targetURI.build();
+
+ ODataEntity patch = client.getObjectFactory().newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim"));
+ patch.setEditLink(editLink);
+
+ patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyDouble",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
+
+ ODataEntityUpdateRequest<ODataEntity> changeReq =
+ client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch);
+ changeReq.setFormat(ODataFormat.JSON_FULL_METADATA);
+ changeReq.setContentType("2");
+ changeset.addRequest(changeReq);
+
+ // ------------------------
+ // Patch request (Upsert)
+ targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(35);
+ editLink = targetURI.build();
+
+ patch = client.getObjectFactory().newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim"));
+ patch.setEditLink(editLink);
+
+ patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty(
+ "PropertyDouble",
+ client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
+
+ changeReq = client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch);
+ changeReq.setFormat(ODataFormat.JSON_FULL_METADATA);
+ changeReq.setContentType("3");
+ changeset.addRequest(changeReq);
+
+ // -----------------------------
+ // - Append get request
+ // -----------------------------
+ appendGetRequest(payload, "ESAllPrim", 32767); // Without error
+
+ // -----------------------------
+ // - Fetch result
+ // -----------------------------
+ final ODataBatchResponse response = payload.getResponse();
+ assertEquals(202, response.getStatusCode());
+ final Iterator<ODataBatchResponseItem> bodyIterator = response.getBody();
+
+ // Check first get request
+ assertTrue(bodyIterator.hasNext());
+ ODataBatchResponseItem item = bodyIterator.next();
+ assertFalse(item.isChangeset());
+
+ // Check change set
+ assertTrue(bodyIterator.hasNext());
+ item = bodyIterator.next();
+ assertTrue(item.isChangeset());
+
+ for (int i = 0; i < 3; i++) {
+ assertTrue(item.hasNext());
+ assertTrue(item instanceof ODataChangesetResponseItem);
+ ODataChangesetResponseItem changeSetResponseItem = (ODataChangesetResponseItem) item.next();
+ assertNotNull(changeSetResponseItem);
+
+ ODataResponse chgRequest = changeSetResponseItem.next();
+ final String contentId = chgRequest.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next();
+
+ if (contentId == "1") {
+ // Insert
+ assertEquals(HttpStatusCode.CREATED.getStatusCode(), chgRequest.getStatusCode());
+ } else if (contentId == "2") {
+ // Update
+ assertEquals(HttpStatusCode.OK.getStatusCode(), chgRequest.getStatusCode());
+ } else if (contentId == "3") {
+ // Upsert
+ assertEquals(HttpStatusCode.CREATED.getStatusCode(), chgRequest.getStatusCode());
+ } else {
+ fail("Unkonwn content id " + contentId);
+ }
+ }
+ assertFalse(item.hasNext());
+
+ // Check second get request
+ assertTrue(bodyIterator.hasNext());
+ item = bodyIterator.next();
+ assertFalse(item.isChangeset());
+ }
+
+ private void appendGetRequest(final BatchManager manager, final String segment, final Object key) {
+ URIBuilder targetURI = client.newURIBuilder(SERVICE_URI);
+ targetURI.appendEntitySetSegment(segment).appendKeySegment(key);
+
+ ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
+ queryReq.setFormat(ODataFormat.JSON);
+ manager.addRequest(queryReq);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/ODataResponsePart.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/ODataResponsePart.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/ODataResponsePart.java
index 8dd7480..c9a914a 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/ODataResponsePart.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/ODataResponsePart.java
@@ -18,25 +18,63 @@
*/
package org.apache.olingo.server.api.batch;
+import java.util.Arrays;
import java.util.List;
import org.apache.olingo.server.api.ODataResponse;
-public interface ODataResponsePart {
+public class ODataResponsePart {
+ private List<ODataResponse> responses;
+ private boolean isChangeSet;
+
/**
- * Returns a collection of ODataResponses.
- * Each collections contains at least one {@link ODataResponse}.
+ * Creates a new ODataResponsePart.
*
- * If this instance represents a change set, there are may many ODataResponses
+ * An ODataResponsePart represents a collections of ODataResponses.
+ * A list of ODataResponseParts can be combined by the BatchSerializer to a single
+ * OData batch response.
*
- * @return a list of {@link ODataResponse}
+ * @param responses A list of {@link ODataResponse}
+ * @param isChangeSet True this ODataResponsePart represents a change set, otherwise false
+ */
+ public ODataResponsePart(List<ODataResponse> responses, boolean isChangeSet) {
+ this.responses = responses;
+ this.isChangeSet = isChangeSet;
+ }
+
+ /**
+ * Creates a new ODataResponsePart.
+ *
+ * An ODataResponsePart represents a collections of ODataResponses.
+ * A list of ODataResponseParts can be combined by the BatchSerializer to a single
+ * OData batch response.
+ *
+ * @param responses A single {@link ODataResponse}
+ * @param isChangeSet True this ODataResponsePart represents a change set, otherwise false
*/
- public List<ODataResponse> getResponses();
+ public ODataResponsePart(ODataResponse response, boolean isChangeSet) {
+ this.responses = Arrays.asList(new ODataResponse[] { response });
+ this.isChangeSet = isChangeSet;
+ }
/**
* Returns true if the current instance represents a change set.
*
* @return true or false
*/
- public boolean isChangeSet();
+ public List<ODataResponse> getResponses() {
+ return responses;
+ }
+
+ /**
+ * Returns a collection of ODataResponses.
+ * Each collections contains at least one {@link ODataResponse}.
+ *
+ * If this instance represents a change set, there are may many ODataResponses
+ *
+ * @return a list of {@link ODataResponse}
+ */
+ public boolean isChangeSet() {
+ return isChangeSet;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
index a0a7135..843fa28 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
@@ -24,10 +24,11 @@ import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.batch.BatchOperation;
import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
public interface BatchProcessor extends Processor {
void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response);
- List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
+ ODataResponsePart executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
BatchRequestPart requestPart);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
index 473c904..25778e3 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
@@ -19,7 +19,11 @@
package org.apache.olingo.server.api.processor;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
@@ -30,6 +34,10 @@ import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
@@ -42,8 +50,12 @@ import org.apache.olingo.server.api.uri.UriInfo;
* <p>This implementation is registered in the ODataHandler by default.
* The default can be replaced by re-registering a custom implementation.</p>
*/
-public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProcessor, ExceptionProcessor {
-
+public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProcessor, ExceptionProcessor,
+ BatchProcessor {
+
+ private static final String PREFERENCE_CONTINUE_ON_ERROR = "odata.continue-on-error";
+ private static final String PREFER_HEADER = "Prefer";
+
private OData odata;
private ServiceMetadata serviceMetadata;
@@ -89,4 +101,81 @@ public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProce
response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.APPLICATION_JSON.toContentTypeString());
}
}
+
+ @Override
+ public void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response) {
+ boolean continueOnError = shouldContinueOnError(request);
+
+ try {
+ final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody());
+ final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
+
+ for (BatchRequestPart part : parts) {
+ final ODataResponsePart responsePart = operation.handleBatchRequest(part);
+ responseParts.add(responsePart); // Also add failed responses
+
+ if (responsePart.getResponses().get(0).getStatusCode() >= 400
+ && !continueOnError) {
+
+ // Perform some additions actions
+ // ...
+
+ break; // Stop processing, but serialize all recent requests
+ }
+ }
+
+ operation.writeResponseParts(responseParts, response); // Serialize responses
+ } catch (BatchException e) {
+ throw new ODataRuntimeException(e);
+ } catch (IOException e) {
+ throw new ODataRuntimeException(e);
+ }
+ }
+
+ private boolean shouldContinueOnError(ODataRequest request) {
+ final List<String> preferValues = request.getHeaders(PREFER_HEADER);
+
+ if (preferValues != null) {
+ for (final String preference : preferValues) {
+ if (PREFERENCE_CONTINUE_ON_ERROR.equals(preference)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ODataResponsePart executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
+ BatchRequestPart requestPart) {
+ List<ODataResponse> responses = new ArrayList<ODataResponse>();
+
+ for (ODataRequest request : requests) {
+ try {
+ final ODataResponse oDataResponse = operation.handleODataRequest(request, requestPart);
+
+ if (oDataResponse.getStatusCode() < 400) {
+ responses.add(oDataResponse);
+ } else {
+ // Rollback
+ // ...
+
+ // OData Version 4.0 Part 1: Protocol Plus Errata 01
+ // 11.7.4 Responding to a Batch Request
+ //
+ // When a request within a change set fails, the change set response is not represented using
+ // the multipart/mixed media type. Instead, a single response, using the application/http media type
+ // and a Content-Transfer-Encoding header with a value of binary, is returned that applies to all requests
+ // in the change set and MUST be formatted according to the Error Handling defined
+ // for the particular response format.
+
+ return new ODataResponsePart(oDataResponse, false);
+ }
+ } catch (BatchException e) {
+ throw new ODataRuntimeException(e);
+ }
+ }
+
+ return new ODataResponsePart(responses, true);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
index 5bec30b..23ba106 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -129,17 +129,14 @@ public class BatchPartHandler {
final List<ODataResponse> responses = new ArrayList<ODataResponse>();
responses.add(handleODataRequest(request.getRequests().get(0), request));
- return new ODataResponsePartImpl(responses, false);
+ return new ODataResponsePart(responses, false);
}
}
private ODataResponsePart handleChangeSet(BatchRequestPart request) throws BatchException {
- final List<ODataResponse> responses = new ArrayList<ODataResponse>();
final BatchChangeSetSorter sorter = new BatchChangeSetSorter(request.getRequests());
-
- responses.addAll(batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request));
- return new ODataResponsePartImpl(responses, true);
+ return batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request);
}
private static class UriMapping {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
deleted file mode 100644
index da52a37..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/ODataResponsePartImpl.java
+++ /dev/null
@@ -1,44 +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.server.core.batch.handler;
-
-import java.util.List;
-
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.batch.ODataResponsePart;
-
-public class ODataResponsePartImpl implements ODataResponsePart {
- private List<ODataResponse> responses;
- private boolean isChangeSet;
-
- public ODataResponsePartImpl(List<ODataResponse> responses, boolean isChangeSet) {
- this.responses = responses;
- this.isChangeSet = isChangeSet;
- }
-
- @Override
- public List<ODataResponse> getResponses() {
- return responses;
- }
-
- @Override
- public boolean isChangeSet() {
- return isChangeSet;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
index 43a09b6..b87f8ef 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParserCommon.java
@@ -123,9 +123,6 @@ public class BatchParserCommon {
// Remove preamble
if (messageParts.size() > 0) {
messageParts.remove(0);
- } else {
- throw new BatchException("Missing boundary delimiter", BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER, ""
- + lineNumer);
}
if (!isEndReached) {
@@ -133,11 +130,6 @@ public class BatchParserCommon {
"" + lineNumer);
}
- if (messageParts.size() == 0) {
- throw new BatchException("No boundary delimiter found",
- BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER, boundary, "" + lineNumer);
- }
-
return messageParts;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
index 812ea8b..0c13cb9 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriter.java
@@ -149,7 +149,7 @@ public class BatchResponseWriter {
final Map<String, String> header = response.getHeaders();
for (final String key : header.keySet()) {
- // Requests do never have content id header
+ // Requests do never has a content id header
if (!key.equalsIgnoreCase(BatchParserCommon.HTTP_CONTENT_ID)) {
appendHeader(key, header.get(key), writer);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/ODataResponsePartImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/ODataResponsePartImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/ODataResponsePartImpl.java
deleted file mode 100644
index a9711c9..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/writer/ODataResponsePartImpl.java
+++ /dev/null
@@ -1,44 +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.server.core.batch.writer;
-
-import java.util.List;
-
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.batch.ODataResponsePart;
-
-public class ODataResponsePartImpl implements ODataResponsePart {
- private final List<ODataResponse> responses;
- private final boolean isChangeSet;
-
- public ODataResponsePartImpl(final List<ODataResponse> responses, final boolean isChangeSet) {
- this.responses = responses;
- this.isChangeSet = isChangeSet;
- }
-
- @Override
- public List<ODataResponse> getResponses() {
- return responses;
- }
-
- @Override
- public boolean isChangeSet() {
- return isChangeSet;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
index c9778e3..88fdf08 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
@@ -274,7 +274,8 @@ public class BatchRequestParserTest {
+ GET_REQUEST
+ "--batch_8194-cf13-1f56--";
- parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER);
+ final List<BatchRequestPart> parts = parse(batch);
+ assertEquals(0, parts.size());
}
@Test
@@ -450,14 +451,23 @@ public class BatchRequestParserTest {
+ "POST Employees('1')/EmployeeName HTTP/1.1" + CRLF
+ CRLF;
- parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER);
+ parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_CLOSE_DELIMITER);
}
-
+
+ @Test
+ public void testEmptyRequest() throws BatchException, UnsupportedEncodingException {
+ final String batch = ""
+ + "--batch_8194-cf13-1f56--";
+
+ final List<BatchRequestPart> parts = parse(batch);
+ assertEquals(0, parts.size());
+ }
+
@Test
public void testBadRequest() throws UnsupportedEncodingException {
final String batch = "This is a bad request. There is no syntax and also no semantic";
- parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER);
+ parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_CLOSE_DELIMITER);
}
@Test
@@ -496,7 +506,7 @@ public class BatchRequestParserTest {
}
@Test
- public void testInvalidChangeSetBoundary() throws UnsupportedEncodingException {
+ public void testInvalidChangeSetBoundary() throws UnsupportedEncodingException, BatchException {
final String batch = "--batch_8194-cf13-1f56" + CRLF
+ "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
+ CRLF
@@ -511,7 +521,12 @@ public class BatchRequestParserTest {
+ CRLF
+ "--batch_8194-cf13-1f56--";
- parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_BOUNDARY_DELIMITER);
+ final List<BatchRequestPart> parts = parse(batch);
+ assertEquals(1, parts.size());
+
+ final BatchRequestPart part = parts.get(0);
+ assertTrue(part.isChangeSet());
+ assertEquals(0, part.getRequests().size());
}
@Test
@@ -1261,7 +1276,6 @@ public class BatchRequestParserTest {
final List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
assertNotNull(batchRequestParts);
- assertFalse(batchRequestParts.isEmpty());
return batchRequestParts;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
index e1864e2..7a85ffa 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -535,7 +535,7 @@ public class MockedBatchHandlerTest {
public void init(OData odata, ServiceMetadata serviceMetadata) {}
@Override
- public List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
+ public ODataResponsePart executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
BatchRequestPart requestPart) {
List<ODataResponse> responses = new ArrayList<ODataResponse>();
@@ -557,7 +557,7 @@ public class MockedBatchHandlerTest {
}
}
- return responses;
+ return new ODataResponsePart(responses, true);
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4ff5fb9c/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
index b7169b9..ea05bfb 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/writer/BatchResponseWriterTest.java
@@ -50,14 +50,14 @@ public class BatchResponseWriterTest {
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
- parts.add(new ODataResponsePartImpl(responses, false));
+ parts.add(new ODataResponsePart(responses, false));
ODataResponse changeSetResponse = new ODataResponse();
changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
changeSetResponse.setHeader(BatchParserCommon.HTTP_CONTENT_ID, "1");
responses = new ArrayList<ODataResponse>(1);
responses.add(changeSetResponse);
- parts.add(new ODataResponsePartImpl(responses, true));
+ parts.add(new ODataResponsePart(responses, true));
BatchResponseWriter writer = new BatchResponseWriter();
ODataResponse batchResponse = new ODataResponse();
@@ -109,7 +109,7 @@ public class BatchResponseWriterTest {
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
- parts.add(new ODataResponsePartImpl(responses, false));
+ parts.add(new ODataResponsePart(responses, false));
ODataResponse batchResponse = new ODataResponse();
new BatchResponseWriter().toODataResponse(parts, batchResponse);
@@ -144,7 +144,7 @@ public class BatchResponseWriterTest {
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
- parts.add(new ODataResponsePartImpl(responses, true));
+ parts.add(new ODataResponsePart(responses, true));
BatchResponseWriter writer = new BatchResponseWriter();
ODataResponse batchResponse = new ODataResponse();
[9/9] olingo-odata4 git commit: Api Refactoring
Posted by ch...@apache.org.
Api Refactoring
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/ad177ac1
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/ad177ac1
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/ad177ac1
Branch: refs/heads/olingo472
Commit: ad177ac11e9cf43087167a9146fa0bcff0f6dc23
Parents: bc46b53
Author: Christian Holzer <c....@sap.com>
Authored: Tue Nov 11 16:50:03 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:11:02 2014 +0100
----------------------------------------------------------------------
.../olingo/server/api/batch/BatchOperation.java | 3 +-
.../server/api/processor/DefaultProcessor.java | 2 +-
.../core/batch/handler/BatchOperationImpl.java | 9 ++-
.../core/batch/handler/BatchPartHandler.java | 59 ++++++++++----------
.../server/core/batch/parser/BatchParser.java | 23 ++++----
.../core/batch/BatchRequestParserTest.java | 53 +++++++++---------
.../batch/handler/MockedBatchHandlerTest.java | 2 +-
7 files changed, 73 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
index 2d09a94..a9edef0 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
@@ -18,14 +18,13 @@
*/package org.apache.olingo.server.api.batch;
import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
public interface BatchOperation {
- public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException;
+ public List<BatchRequestPart> parseBatchRequest(ODataRequest request, boolean isStrict) throws BatchException;
public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
index 25778e3..c4493a1 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
@@ -107,7 +107,7 @@ public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProce
boolean continueOnError = shouldContinueOnError(request);
try {
- final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody());
+ final List<BatchRequestPart> parts = operation.parseBatchRequest(request, true);
final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
for (BatchRequestPart part : parts) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
index cf7ad7c..b5a4eb4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
@@ -19,7 +19,6 @@
package org.apache.olingo.server.core.batch.handler;
import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader;
@@ -43,13 +42,13 @@ public class BatchOperationImpl implements BatchOperation {
final boolean isStrict) {
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
writer = new BatchResponseWriter();
- parser = new BatchParser(getContentType(request), request.getRawBaseUri(),
- request.getRawServiceResolutionUri(), isStrict);
+ parser = new BatchParser();
}
@Override
- public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException {
- return parser.parseBatchRequest(in);
+ public List<BatchRequestPart> parseBatchRequest(ODataRequest request, boolean isStrict) throws BatchException {
+ return parser.parseBatchRequest(request.getBody(), getContentType(request), request.getRawBaseUri(),
+ request.getRawServiceResolutionUri(), isStrict);
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
index 23ba106..2147a2e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -6,9 +6,9 @@
* 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
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.server.core.batch.handler;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import org.apache.olingo.commons.api.ODataRuntimeException;
@@ -43,7 +41,7 @@ public class BatchPartHandler {
private BatchProcessor batchProcessor;
private BatchOperation batchOperation;
private Map<BatchRequestPart, UriMapping> uriMapping = new HashMap<BatchRequestPart, UriMapping>();
-
+
public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor,
final BatchOperation batchOperation) {
this.oDataHandler = oDataHandler;
@@ -53,12 +51,12 @@ public class BatchPartHandler {
public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException {
final ODataResponse response;
-
- if(requestPart.isChangeSet()) {
+
+ if (requestPart.isChangeSet()) {
final UriMapping mapping = replaceReference(request, requestPart);
response = oDataHandler.process(request);
-
+
// Store resource URI
final String resourceUri = getODataPath(request, response);
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
@@ -67,20 +65,20 @@ public class BatchPartHandler {
} else {
response = oDataHandler.process(request);
}
-
+
// Add content id to response
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
- if(contentId != null) {
+ if (contentId != null) {
response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId);
}
-
- return response;
+
+ return response;
}
private String getODataPath(ODataRequest request, ODataResponse response) throws BatchException {
String resourceUri = null;
-
- if(request.getMethod() == HttpMethod.POST) {
+
+ if (request.getMethod() == HttpMethod.POST) {
// Create entity
// The URI of the new resource will be generated by the server and published in the location header
ODataURI uri = new ODataURI(response.getHeaders().get(HttpHeader.LOCATION), request.getRawBaseUri());
@@ -90,62 +88,61 @@ public class BatchPartHandler {
// These methods still addresses a given resource, so we use the URI given by the request
resourceUri = request.getRawODataPath();
}
-
+
return resourceUri;
}
private UriMapping replaceReference(ODataRequest request, BatchRequestPart requestPart) {
final UriMapping mapping = getUriMappingOrDefault(requestPart);
final String reference = BatchChangeSetSorter.getReferenceInURI(request);
-
- if(reference != null) {
+
+ if (reference != null) {
final String replacement = mapping.getUri(reference);
-
- if(replacement != null) {
+
+ if (replacement != null) {
BatchChangeSetSorter.replaceContentIdReference(request, reference, replacement);
} else {
throw new ODataRuntimeException("Required Content-Id for reference \"" + reference + "\" not found.");
}
}
-
+
return mapping;
}
-
+
private UriMapping getUriMappingOrDefault(final BatchRequestPart requestPart) {
UriMapping mapping = uriMapping.get(requestPart);
-
- if(mapping == null) {
+
+ if (mapping == null) {
mapping = new UriMapping();
}
uriMapping.put(requestPart, mapping);
-
+
return mapping;
}
-
+
public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException {
if (request.isChangeSet()) {
return handleChangeSet(request);
} else {
- final List<ODataResponse> responses = new ArrayList<ODataResponse>();
- responses.add(handleODataRequest(request.getRequests().get(0), request));
+ final ODataResponse response = handleODataRequest(request.getRequests().get(0), request);
- return new ODataResponsePart(responses, false);
+ return new ODataResponsePart(response, false);
}
}
private ODataResponsePart handleChangeSet(BatchRequestPart request) throws BatchException {
final BatchChangeSetSorter sorter = new BatchChangeSetSorter(request.getRequests());
-
+
return batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request);
}
private static class UriMapping {
private Map<String, String> uriMapping = new HashMap<String, String>();
-
+
public void addMapping(final String contentId, final String uri) {
uriMapping.put(contentId, uri);
}
-
+
public String getUri(final String contentId) {
return uriMapping.get(contentId);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
index 75c0084..3a89440 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchParser.java
@@ -6,9 +6,9 @@
* 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
@@ -33,21 +33,18 @@ import org.apache.olingo.server.core.batch.transformator.BatchRequestTransformat
public class BatchParser {
- private final String contentTypeMime;
- private final String baseUri;
- private final String rawServiceResolutionUri;
- private final boolean isStrict;
-
- public BatchParser(final String contentType, final String baseUri, final String serviceResolutionUri,
- final boolean isStrict) {
+ private String contentTypeMime;
+ private String rawServiceResolutionUri;
+ private boolean isStrict;
+
+ @SuppressWarnings("unchecked")
+ public List<BatchRequestPart> parseBatchRequest(final InputStream in, final String contentType, final String baseUri,
+ final String serviceResolutionUri, final boolean isStrict) throws BatchException {
+
contentTypeMime = contentType;
- this.baseUri = BatchParserCommon.removeEndingSlash(baseUri);
this.isStrict = isStrict;
this.rawServiceResolutionUri = serviceResolutionUri;
- }
- @SuppressWarnings("unchecked")
- public List<BatchRequestPart> parseBatchRequest(final InputStream in) throws BatchException {
return (List<BatchRequestPart>) parse(in, new BatchRequestTransformator(baseUri, rawServiceResolutionUri));
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
index 88fdf08..cc249be 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/BatchRequestParserTest.java
@@ -6,9 +6,9 @@
* 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
@@ -196,8 +196,9 @@ public class BatchRequestParserTest {
+ "--batch_1.2+34:2j)0?" + CRLF
+ GET_REQUEST
+ "--batch_1.2+34:2j)0?--";
- final BatchParser parser = new BatchParser(contentType, SERVICE_ROOT, "", true);
- final List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(StringUtil.toInputStream(batch));
+ final BatchParser parser = new BatchParser();
+ final List<BatchRequestPart> batchRequestParts =
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), contentType, SERVICE_ROOT, "", true);
assertNotNull(batchRequestParts);
assertFalse(batchRequestParts.isEmpty());
@@ -210,10 +211,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb84-2f7f" + CRLF
+ GET_REQUEST
+ "--batch_1740-bb84-2f7f--";
- final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true);
+ final BatchParser parser = new BatchParser();
try {
- parser.parseBatchRequest(StringUtil.toInputStream(batch));
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail();
} catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE);
@@ -224,15 +225,16 @@ public class BatchRequestParserTest {
public void testContentTypeCharset() throws BatchException {
final String contentType = "multipart/mixed; charset=UTF-8;boundary=batch_14d1-b293-b99a";
final String batch = ""
- + "--batch_14d1-b293-b99a" + CRLF
- + GET_REQUEST
- + "--batch_14d1-b293-b99a--";
- final BatchParser parser = new BatchParser(contentType, SERVICE_ROOT, "", true);
- final List<BatchRequestPart> parts = parser.parseBatchRequest(StringUtil.toInputStream(batch));
-
+ + "--batch_14d1-b293-b99a" + CRLF
+ + GET_REQUEST
+ + "--batch_14d1-b293-b99a--";
+ final BatchParser parser = new BatchParser();
+ final List<BatchRequestPart> parts =
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), contentType, SERVICE_ROOT, "", true);
+
assertEquals(1, parts.size());
}
-
+
@Test
public void testBatchWithoutBoundaryParameter() throws UnsupportedEncodingException {
final String invalidContentType = "multipart/mixed";
@@ -240,10 +242,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb84-2f7f" + CRLF
+ GET_REQUEST
+ "--batch_1740-bb84-2f7f--";
- final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true);
+ final BatchParser parser = new BatchParser();
try {
- parser.parseBatchRequest(StringUtil.toInputStream(batch));
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail();
} catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE);
@@ -257,10 +259,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb:84-2f7f" + CRLF
+ GET_REQUEST
+ "--batch_1740-bb:84-2f7f--";
- final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true);
+ final BatchParser parser = new BatchParser();
try {
- parser.parseBatchRequest(StringUtil.toInputStream(batch));
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail();
} catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_BOUNDARY);
@@ -453,16 +455,16 @@ public class BatchRequestParserTest {
parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_CLOSE_DELIMITER);
}
-
+
@Test
public void testEmptyRequest() throws BatchException, UnsupportedEncodingException {
final String batch = ""
+ "--batch_8194-cf13-1f56--";
-
+
final List<BatchRequestPart> parts = parse(batch);
assertEquals(0, parts.size());
}
-
+
@Test
public void testBadRequest() throws UnsupportedEncodingException {
final String batch = "This is a bad request. There is no syntax and also no semantic";
@@ -523,7 +525,7 @@ public class BatchRequestParserTest {
final List<BatchRequestPart> parts = parse(batch);
assertEquals(1, parts.size());
-
+
final BatchRequestPart part = parts.get(0);
assertTrue(part.isChangeSet());
assertEquals(0, part.getRequests().size());
@@ -1272,8 +1274,9 @@ public class BatchRequestParserTest {
}
private List<BatchRequestPart> parse(final InputStream in, final boolean isStrict) throws BatchException {
- final BatchParser parser = new BatchParser(CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
- final List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+ final BatchParser parser = new BatchParser();
+ final List<BatchRequestPart> batchRequestParts =
+ parser.parseBatchRequest(in, CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
assertNotNull(batchRequestParts);
@@ -1295,10 +1298,10 @@ public class BatchRequestParserTest {
private void parseInvalidBatchBody(final String batch, final MessageKeys key, final boolean isStrict)
throws UnsupportedEncodingException {
- final BatchParser parser = new BatchParser(CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
+ final BatchParser parser = new BatchParser();
try {
- parser.parseBatchRequest(StringUtil.toInputStream(batch));
+ parser.parseBatchRequest(StringUtil.toInputStream(batch), CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
fail("No exception thrown. Expect: " + key.toString());
} catch (BatchException e) {
assertMessageKey(e, key);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ad177ac1/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
index b81edb8..c68919c 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -593,7 +593,7 @@ public class MockedBatchHandlerTest {
@Override
public void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response) {
try {
- final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody());
+ final List<BatchRequestPart> parts = operation.parseBatchRequest(request, true);
final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
for (BatchRequestPart part : parts) {
[3/9] olingo-odata4 git commit: MockedBatchHandler Test
Posted by ch...@apache.org.
MockedBatchHandler Test
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/0bd32951
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/0bd32951
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/0bd32951
Branch: refs/heads/olingo472
Commit: 0bd32951b8ebcfce895fa5d5eb8fd76954d6bfd3
Parents: ee2451c
Author: Christian Holzer <c....@sap.com>
Authored: Mon Nov 3 17:16:47 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:56 2014 +0100
----------------------------------------------------------------------
.../olingo/server/api/batch/BatchOperation.java | 2 +-
.../server/api/processor/BatchProcessor.java | 2 +-
.../batch/handler/BatchChangeSetSorter.java | 41 +-
.../core/batch/handler/BatchOperationImpl.java | 2 +-
.../core/batch/handler/BatchPartHandler.java | 56 +-
.../BatchRequestTransformator.java | 17 +-
.../transformator/BatchTransformatorCommon.java | 159 -----
.../transformator/HttpRequestStatusLine.java | 229 ++++++++
.../batch/handler/BatchChangeSetSorterTest.java | 4 +-
.../batch/handler/MockedBatchHandlerTest.java | 582 +++++++++++++++++++
10 files changed, 894 insertions(+), 200 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
index af7d9c1..2d09a94 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
@@ -27,7 +27,7 @@ import org.apache.olingo.server.api.ODataResponse;
public interface BatchOperation {
public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException;
- public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart);
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException;
public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
index 221b38a..a0a7135 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
@@ -26,7 +26,7 @@ import org.apache.olingo.server.api.batch.BatchOperation;
import org.apache.olingo.server.api.batch.BatchRequestPart;
public interface BatchProcessor extends Processor {
- void executeBatch(BatchOperation operation, ODataRequest requests, ODataResponse response);
+ void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response);
List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
BatchRequestPart requestPart);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
index c348512..f8ac653 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
@@ -39,7 +39,7 @@ public class BatchChangeSetSorter {
private static Pattern referencePattern = Pattern.compile(REG_EX_REFERENCE);
private Set<String> knownContentId = new HashSet<String>();
- private Map<String, List<ODataRequest>> requestContentIdMapping = new HashMap<String, List<ODataRequest>>();
+ private Map<String, List<ODataRequest>> requestReferenceMapping = new HashMap<String, List<ODataRequest>>();
public BatchChangeSetSorter(List<ODataRequest> requests) throws BatchException {
sort(requests);
@@ -50,9 +50,12 @@ public class BatchChangeSetSorter {
}
private List<ODataRequest> sort(final List<ODataRequest> requests) throws BatchException {
- extractUrlContentId(requests);
- orderdList.addAll(getRequestsWithoutReferences());
-
+ extractUrlReference(requests);
+
+ final List<ODataRequest> requestsWithoutReferences = getRequestsWithoutReferences();
+ orderdList.addAll(requestsWithoutReferences);
+ addRequestsToKnownContentIds(requestsWithoutReferences);
+
boolean areRequestsProcessed = true;
while (requestsToProcessAvailable() && areRequestsProcessed) {
areRequestsProcessed = processRemainingRequests(orderdList);
@@ -66,7 +69,7 @@ public class BatchChangeSetSorter {
}
private boolean requestsToProcessAvailable() {
- return requestContentIdMapping.keySet().size() != 0;
+ return requestReferenceMapping.keySet().size() != 0;
}
private boolean processRemainingRequests(List<ODataRequest> orderdList) {
@@ -81,10 +84,10 @@ public class BatchChangeSetSorter {
List<ODataRequest> result = new ArrayList<ODataRequest>();
for (String contextId : knownContentId) {
- List<ODataRequest> processedRequests = requestContentIdMapping.get(contextId);
+ List<ODataRequest> processedRequests = requestReferenceMapping.get(contextId);
if (processedRequests != null && processedRequests.size() != 0) {
result.addAll(processedRequests);
- requestContentIdMapping.remove(contextId);
+ requestReferenceMapping.remove(contextId);
}
}
@@ -92,10 +95,9 @@ public class BatchChangeSetSorter {
}
private List<ODataRequest> getRequestsWithoutReferences() {
- final List<ODataRequest> requestsWithoutReference = requestContentIdMapping.get(null);
- requestContentIdMapping.remove(null);
+ final List<ODataRequest> requestsWithoutReference = requestReferenceMapping.get(null);
+ requestReferenceMapping.remove(null);
- addRequestsToKnownContentIds(requestsWithoutReference);
return requestsWithoutReference;
}
@@ -112,33 +114,38 @@ public class BatchChangeSetSorter {
return request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
}
- private void extractUrlContentId(List<ODataRequest> requests) {
+ private void extractUrlReference(List<ODataRequest> requests) {
for (ODataRequest request : requests) {
final String reference = getReferenceInURI(request);
- addRequestToMapping(reference, request);
+ addRequestToReferenceMapping(reference, request);
}
}
- private void addRequestToMapping(final String reference, final ODataRequest request) {
- List<ODataRequest> requestList = requestContentIdMapping.get(reference);
+ private void addRequestToReferenceMapping(final String reference, final ODataRequest request) {
+ List<ODataRequest> requestList = requestReferenceMapping.get(reference);
requestList = (requestList == null) ? new ArrayList<ODataRequest>() : requestList;
requestList.add(request);
- requestContentIdMapping.put(reference, requestList);
+ requestReferenceMapping.put(reference, requestList);
}
public static String getReferenceInURI(ODataRequest request) {
- Matcher matcher = referencePattern.matcher(removeFollingPathSegments(request.getRawODataPath()));
+ Matcher matcher = referencePattern.matcher(removeFollingPathSegments(removeFirstSplash(request.getRawODataPath())));
return (matcher.matches()) ? matcher.group(1) : null;
}
+ private static String removeFirstSplash(String rawODataPath) {
+ final int indexOfSlash = rawODataPath.indexOf("/");
+ return (indexOfSlash == 0) ? rawODataPath.substring(1) : rawODataPath;
+ }
+
private static String removeFollingPathSegments(String rawODataPath) {
final int indexOfSlash = rawODataPath.indexOf("/");
return (indexOfSlash != -1) ? rawODataPath.substring(0, indexOfSlash) : rawODataPath;
}
public static void replaceContentIdReference(ODataRequest request, String contentId, String resourceUri) {
- final String newUri = request.getRawODataPath().replace("$" + contentId, resourceUri);
+ final String newUri = request.getRawODataPath().replace("/$" + contentId, resourceUri);
request.setRawODataPath(newUri);
request.setRawRequestUri(request.getRawBaseUri() + "/" + newUri);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
index 1f5e243..cf7ad7c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
@@ -53,7 +53,7 @@ public class BatchOperationImpl implements BatchOperation {
}
@Override
- public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) {
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException {
return partHandler.handleODataRequest(request, requestPart);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
index df23c55..c678355 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -23,7 +23,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.batch.BatchException;
@@ -33,6 +35,7 @@ import org.apache.olingo.server.api.batch.ODataResponsePart;
import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.core.ODataHandler;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+import org.apache.olingo.server.core.batch.transformator.HttpRequestStatusLine.ODataURI;
public class BatchPartHandler {
@@ -48,21 +51,18 @@ public class BatchPartHandler {
this.batchOperation = batchOperation;
}
- public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) {
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException {
final ODataResponse response;
if(requestPart.isChangeSet()) {
- final UriMapping mapping = getUriMappingOrDefault(requestPart);
- final String reference = BatchChangeSetSorter.getReferenceInURI(request);
- if(reference != null) {
- BatchChangeSetSorter.replaceContentIdReference(request, reference, mapping.getUri(reference));
- }
-
- response = oDataHandler.process(request);
+ final UriMapping mapping = replaceReference(request, requestPart);
+
+ response = oDataHandler.process(request);
+ final String resourceUri = getODataPath(request, response);
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
- final String locationHeader = request.getHeader(HttpHeader.LOCATION);
- mapping.addMapping(contentId, locationHeader);
+
+ mapping.addMapping(contentId, resourceUri);
} else {
response = oDataHandler.process(request);
}
@@ -74,11 +74,45 @@ public class BatchPartHandler {
return response;
}
+
+ private String getODataPath(ODataRequest request, ODataResponse response) throws BatchException {
+ String resourceUri = null;
+
+ if(request.getMethod() == HttpMethod.POST) {
+ // Create entity
+ // The URI of the new resource will be generated by the server and published in the location header
+ ODataURI uri = new ODataURI(response.getHeaders().get(HttpHeader.LOCATION), request.getRawBaseUri());
+ resourceUri = uri.getRawODataPath();
+ } else {
+ // Update, Upsert (PUT, PATCH, Delete)
+ // These methods still addresses a given URI, so we use the URI given by the request
+ resourceUri = request.getRawODataPath();
+ }
+
+ return resourceUri;
+ }
+
+ private UriMapping replaceReference(ODataRequest request, BatchRequestPart requestPart) {
+ final UriMapping mapping = getUriMappingOrDefault(requestPart);
+ final String reference = BatchChangeSetSorter.getReferenceInURI(request);
+
+ if(reference != null) {
+ final String replacement = mapping.getUri(reference);
+
+ if(replacement != null) {
+ BatchChangeSetSorter.replaceContentIdReference(request, reference, replacement);
+ } else {
+ throw new ODataRuntimeException("Required Content-Id for reference \"" + reference + "\" not found.");
+ }
+ }
+
+ return mapping;
+ }
private UriMapping getUriMappingOrDefault(final BatchRequestPart requestPart) {
UriMapping mapping = uriMapping.get(requestPart);
- if(uriMapping == null) {
+ if(mapping == null) {
mapping = new UriMapping();
}
uriMapping.put(requestPart, mapping);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
index 94d5226..0bf0104 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchRequestTransformator.java
@@ -38,7 +38,7 @@ import org.apache.olingo.server.core.batch.parser.BatchQueryOperation;
import org.apache.olingo.server.core.batch.parser.BatchRequestPartImpl;
import org.apache.olingo.server.core.batch.parser.Header;
import org.apache.olingo.server.core.batch.parser.HeaderField;
-import org.apache.olingo.server.core.batch.transformator.BatchTransformatorCommon.HttpRequestStatusLine;
+import org.apache.olingo.server.core.batch.transformator.HttpRequestStatusLine.ODataURI;
public class BatchRequestTransformator implements BatchTransformator {
private final String baseUri;
@@ -111,20 +111,21 @@ public class BatchRequestTransformator implements BatchTransformator {
new HttpRequestStatusLine(operation.getHttpStatusLine(), baseUri, rawServiceResolutionUri, operation
.getHeaders());
statusLine.validateHttpMethod(isChangeSet);
-
+ final ODataURI uri = statusLine.getUri();
+
validateBody(statusLine, operation);
InputStream bodyStrean = getBodyStream(operation, statusLine);
validateForbiddenHeader(operation);
-
+
final ODataRequest request = new ODataRequest();
request.setBody(bodyStrean);
request.setMethod(statusLine.getMethod());
- request.setRawBaseUri(statusLine.getRawBaseUri());
- request.setRawODataPath(statusLine.getRawODataPath());
- request.setRawQueryPath(statusLine.getRawQueryPath());
- request.setRawRequestUri(statusLine.getRawRequestUri());
- request.setRawServiceResolutionUri(statusLine.getRawServiceResolutionUri());
+ request.setRawBaseUri(uri.getRawBaseUri());
+ request.setRawODataPath(uri.getRawODataPath());
+ request.setRawQueryPath(uri.getRawQueryPath());
+ request.setRawRequestUri(uri.getRawRequestUri());
+ request.setRawServiceResolutionUri(uri.getRawServiceResolutionUri());
for (final HeaderField field : operation.getHeaders()) {
request.addHeader(field.getFieldName(), field.getValues());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
index c9da563..fc2035a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/BatchTransformatorCommon.java
@@ -18,20 +18,14 @@
*/
package org.apache.olingo.server.core.batch.transformator;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
-import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
import org.apache.olingo.server.core.batch.parser.Header;
import org.apache.olingo.server.core.batch.parser.HeaderField;
@@ -94,157 +88,4 @@ public class BatchTransformatorCommon {
return -1;
}
-
- public static class HttpRequestStatusLine {
- private static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(?:\\?(.*))?");
- private static final Pattern PATTERN_ABSOLUTE_URI_WITH_HOST = Pattern.compile("(/[^?]*)(?:\\?(.*))?");
- private static final Pattern PATTERN_ABSOLUTE_URI = Pattern.compile("(http[s]?://[^?]*)(?:\\?(.*))?");
-
- private static final Set<String> HTTP_BATCH_METHODS = new HashSet<String>(Arrays.asList(new String[] { "GET" }));
- private static final Set<String> HTTP_CHANGE_SET_METHODS = new HashSet<String>(Arrays.asList(new String[] { "POST",
- "PUT", "DELETE", "MERGE", "PATCH" }));
- private static final String HTTP_VERSION = "HTTP/1.1";
-
- final private Line statusLine;
- final String requestBaseUri;
-
- private HttpMethod method;
- private String httpVersion;
- private String rawServiceResolutionUri;
- private String rawQueryPath;
- private String rawODataPath;
- private String rawBaseUri;
- private Header header;
- private String rawRequestUri;
-
- public HttpRequestStatusLine(final Line httpStatusLine, final String baseUri, final String serviceResolutionUri,
- final Header requestHeader)
- throws BatchException {
- statusLine = httpStatusLine;
- requestBaseUri = baseUri;
- header = requestHeader;
- rawServiceResolutionUri = serviceResolutionUri;
-
- parse();
- }
-
- private void parse() throws BatchException {
- final String[] parts = statusLine.toString().split(" ");
-
- if (parts.length == 3) {
- method = parseMethod(parts[0]);
- parseRawPaths(parts[1]);
- httpVersion = parseHttpVersion(parts[2]);
- } else {
- throw new BatchException("Invalid status line", MessageKeys.INVALID_STATUS_LINE, statusLine.getLineNumber());
- }
- }
-
- private HttpMethod parseMethod(final String method) throws BatchException {
- try {
- return HttpMethod.valueOf(method.trim());
- } catch (IllegalArgumentException e) {
- throw new BatchException("Illegal http method", MessageKeys.INVALID_METHOD, statusLine.getLineNumber());
- }
- }
-
- private void parseRawPaths(final String rawUrl) throws BatchException {
- final Matcher absoluteUriMatcher = PATTERN_ABSOLUTE_URI.matcher(rawUrl);
- final Matcher absoluteUriWtithHostMatcher = PATTERN_ABSOLUTE_URI_WITH_HOST.matcher(rawUrl);
- final Matcher relativeUriMatcher = PATTERN_RELATIVE_URI.matcher(rawUrl);
-
- if (absoluteUriMatcher.matches()) {
- buildUri(absoluteUriMatcher.group(1), absoluteUriMatcher.group(2));
-
- } else if (absoluteUriWtithHostMatcher.matches()) {
- final List<String> hostHeader = header.getHeaders(HttpHeader.HOST);
- if (hostHeader.size() == 1) {
- buildUri(hostHeader.get(0) + absoluteUriWtithHostMatcher.group(1), absoluteUriWtithHostMatcher.group(2));
- } else {
- throw new BatchException("Exactly one host header is required", MessageKeys.MISSING_MANDATORY_HEADER,
- statusLine.getLineNumber());
- }
-
- } else if (relativeUriMatcher.matches()) {
- buildUri(requestBaseUri + "/" + relativeUriMatcher.group(1), relativeUriMatcher.group(2));
-
- } else {
- throw new BatchException("Invalid uri", MessageKeys.INVALID_URI, statusLine.getLineNumber());
- }
- }
-
- private void buildUri(final String resourceUri, final String queryOptions) throws BatchException {
- if(!resourceUri.startsWith(requestBaseUri)) {
- throw new BatchException("Host do not match", MessageKeys.INVALID_URI, statusLine.getLineNumber());
- }
-
- final int oDataPathIndex = resourceUri.indexOf(requestBaseUri);
-
- rawBaseUri = requestBaseUri;
- rawODataPath = resourceUri.substring(oDataPathIndex + requestBaseUri.length());
- rawServiceResolutionUri = "";
- rawRequestUri = requestBaseUri + rawODataPath;
-
- if (queryOptions != null) {
- rawRequestUri += "?" + queryOptions;
- rawQueryPath = queryOptions;
- } else {
- rawQueryPath = "";
- }
- }
-
- private String parseHttpVersion(final String httpVersion) throws BatchException {
- if (!HTTP_VERSION.equals(httpVersion.trim())) {
- throw new BatchException("Invalid http version", MessageKeys.INVALID_HTTP_VERSION, statusLine.getLineNumber());
- } else {
- return HTTP_VERSION;
- }
- }
-
- public void validateHttpMethod(boolean isChangeSet) throws BatchException {
- Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
-
- if (!validMethods.contains(getMethod().toString())) {
- if (isChangeSet) {
- throw new BatchException("Invalid change set method", MessageKeys.INVALID_CHANGESET_METHOD, statusLine
- .getLineNumber());
- } else {
- throw new BatchException("Invalid query operation method", MessageKeys.INVALID_QUERY_OPERATION_METHOD,
- statusLine.getLineNumber());
- }
- }
- }
-
- public HttpMethod getMethod() {
- return method;
- }
-
- public String getHttpVersion() {
- return httpVersion;
- }
-
- public int getLineNumber() {
- return statusLine.getLineNumber();
- }
-
- public String getRawBaseUri() {
- return rawBaseUri;
- }
-
- public String getRawODataPath() {
- return rawODataPath;
- }
-
- public String getRawQueryPath() {
- return rawQueryPath;
- }
-
- public String getRawRequestUri() {
- return rawRequestUri;
- }
-
- public String getRawServiceResolutionUri() {
- return rawServiceResolutionUri;
- }
- }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
new file mode 100644
index 0000000..416d593
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
@@ -0,0 +1,229 @@
+/*
+ * 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.server.core.batch.transformator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchException.MessageKeys;
+import org.apache.olingo.server.core.batch.parser.Header;
+import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings.Line;
+
+public class HttpRequestStatusLine {
+ private static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(?:\\?(.*))?");
+ private static final Pattern PATTERN_ABSOLUTE_URI_WITH_HOST = Pattern.compile("(/[^?]*)(?:\\?(.*))?");
+ private static final Pattern PATTERN_ABSOLUTE_URI = Pattern.compile("(http[s]?://[^?]*)(?:\\?(.*))?");
+
+ private static final Set<String> HTTP_BATCH_METHODS = new HashSet<String>(Arrays.asList(new String[] { "GET" }));
+ private static final Set<String> HTTP_CHANGE_SET_METHODS = new HashSet<String>(Arrays.asList(new String[] { "POST",
+ "PUT", "DELETE", "MERGE", "PATCH" }));
+ // TODO Is Merge still supported?
+ // What`s New in OData 4: 2.7.2 Pruned: MERGE
+ // MERGE was used to do PATCH before PATCH existed. Now that we have PATCH, we no longer need MERGE. => No
+ private static final String HTTP_VERSION = "HTTP/1.1";
+
+ final private Line statusLine;
+ final String requestBaseUri;
+
+ private HttpMethod method;
+ private String httpVersion;
+ private Header header;
+ private ODataURI uri;
+
+ public HttpRequestStatusLine(final Line httpStatusLine, final String baseUri, final String serviceResolutionUri,
+ final Header requestHeader)
+ throws BatchException {
+ statusLine = httpStatusLine;
+ requestBaseUri = baseUri;
+ header = requestHeader;
+
+ parse();
+ }
+
+ private void parse() throws BatchException {
+ final String[] parts = statusLine.toString().split(" ");
+
+ if (parts.length == 3) {
+ method = parseMethod(parts[0]);
+ uri = new ODataURI(parts[1], requestBaseUri, statusLine.getLineNumber(), header.getHeaders(HttpHeader.HOST));
+ httpVersion = parseHttpVersion(parts[2]);
+ } else {
+ throw new BatchException("Invalid status line", MessageKeys.INVALID_STATUS_LINE, statusLine.getLineNumber());
+ }
+ }
+
+ private HttpMethod parseMethod(final String method) throws BatchException {
+ try {
+ return HttpMethod.valueOf(method.trim());
+ } catch (IllegalArgumentException e) {
+ throw new BatchException("Illegal http method", MessageKeys.INVALID_METHOD, statusLine.getLineNumber());
+ }
+ }
+
+ private String parseHttpVersion(final String httpVersion) throws BatchException {
+ if (!HTTP_VERSION.equals(httpVersion.trim())) {
+ throw new BatchException("Invalid http version", MessageKeys.INVALID_HTTP_VERSION, statusLine.getLineNumber());
+ } else {
+ return HTTP_VERSION;
+ }
+ }
+
+ public void validateHttpMethod(boolean isChangeSet) throws BatchException {
+ Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
+
+ if (!validMethods.contains(getMethod().toString())) {
+ if (isChangeSet) {
+ throw new BatchException("Invalid change set method", MessageKeys.INVALID_CHANGESET_METHOD, statusLine
+ .getLineNumber());
+ } else {
+ throw new BatchException("Invalid query operation method", MessageKeys.INVALID_QUERY_OPERATION_METHOD,
+ statusLine.getLineNumber());
+ }
+ }
+ }
+
+ public HttpMethod getMethod() {
+ return method;
+ }
+
+ public String getHttpVersion() {
+ return httpVersion;
+ }
+
+ public int getLineNumber() {
+ return statusLine.getLineNumber();
+ }
+
+ public ODataURI getUri() {
+ return uri;
+ }
+
+ public static class ODataURI {
+ private String rawServiceResolutionUri;
+ private String rawQueryPath;
+ private String rawODataPath;
+ private String rawBaseUri;
+ private String rawRequestUri;
+ private final String requestBaseUri;
+ private final int lineNumber;
+
+ public ODataURI(final String rawUri, String requestBaseUri) throws BatchException {
+ this(rawUri, requestBaseUri, 0, new ArrayList<String>());
+ }
+
+ public ODataURI(final String rawUri, String requestBaseUri, int lineNumber, List<String> hostHeader)
+ throws BatchException {
+ this.lineNumber = lineNumber;
+ this.requestBaseUri = requestBaseUri;
+
+ final Matcher absoluteUriMatcher = PATTERN_ABSOLUTE_URI.matcher(rawUri);
+ final Matcher absoluteUriWtithHostMatcher = PATTERN_ABSOLUTE_URI_WITH_HOST.matcher(rawUri);
+ final Matcher relativeUriMatcher = PATTERN_RELATIVE_URI.matcher(rawUri);
+
+ if (absoluteUriMatcher.matches()) {
+ buildUri(absoluteUriMatcher.group(1), absoluteUriMatcher.group(2));
+
+ } else if (absoluteUriWtithHostMatcher.matches()) {
+ if (hostHeader != null && hostHeader.size() == 1) {
+ buildUri(hostHeader.get(0) + absoluteUriWtithHostMatcher.group(1), absoluteUriWtithHostMatcher.group(2));
+ } else {
+ throw new BatchException("Exactly one host header is required", MessageKeys.MISSING_MANDATORY_HEADER,
+ lineNumber);
+ }
+
+ } else if (relativeUriMatcher.matches()) {
+ buildUri(requestBaseUri + "/" + relativeUriMatcher.group(1), relativeUriMatcher.group(2));
+
+ } else {
+ throw new BatchException("Invalid uri", MessageKeys.INVALID_URI, lineNumber);
+ }
+ }
+
+ private void buildUri(final String resourceUri, final String queryOptions) throws BatchException {
+ if (!resourceUri.startsWith(requestBaseUri)) {
+ throw new BatchException("Host do not match", MessageKeys.INVALID_URI, lineNumber);
+ }
+
+ final int oDataPathIndex = resourceUri.indexOf(requestBaseUri);
+
+ rawBaseUri = requestBaseUri;
+ rawODataPath = resourceUri.substring(oDataPathIndex + requestBaseUri.length());
+ rawRequestUri = requestBaseUri + rawODataPath;
+
+ if (queryOptions != null) {
+ rawRequestUri += "?" + queryOptions;
+ rawQueryPath = queryOptions;
+ } else {
+ rawQueryPath = "";
+ }
+ }
+
+ public String getRawServiceResolutionUri() {
+ return rawServiceResolutionUri;
+ }
+
+ public void setRawServiceResolutionUri(String rawServiceResolutionUri) {
+ this.rawServiceResolutionUri = rawServiceResolutionUri;
+ }
+
+ public String getRawQueryPath() {
+ return rawQueryPath;
+ }
+
+ public void setRawQueryPath(String rawQueryPath) {
+ this.rawQueryPath = rawQueryPath;
+ }
+
+ public String getRawODataPath() {
+ return rawODataPath;
+ }
+
+ public void setRawODataPath(String rawODataPath) {
+ this.rawODataPath = rawODataPath;
+ }
+
+ public String getRawBaseUri() {
+ return rawBaseUri;
+ }
+
+ public void setRawBaseUri(String rawBaseUri) {
+ this.rawBaseUri = rawBaseUri;
+ }
+
+ public String getRawRequestUri() {
+ return rawRequestUri;
+ }
+
+ public void setRawRequestUri(String rawRequestUri) {
+ this.rawRequestUri = rawRequestUri;
+ }
+
+ public String getRequestBaseUri() {
+ return requestBaseUri;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
index 9196514..c8b725a 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
@@ -39,7 +39,7 @@ public class BatchChangeSetSorterTest {
public void test() throws BatchException {
final List<ODataRequest> changeSet = new ArrayList<ODataRequest>();
changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$1/Adress", "2"));
- changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employees", "1"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "/Employees", "1"));
BatchChangeSetSorter sorter = new BatchChangeSetSorter(changeSet);
final List<ODataRequest> sortedChangeSet = sorter.getOrderdRequests();
@@ -110,7 +110,7 @@ public class BatchChangeSetSorterTest {
@Test
public void testRewriting() {
final String CONTENT_ID = "1";
- final String ODATA_PATH ="$" + CONTENT_ID + "/Address";
+ final String ODATA_PATH ="/$" + CONTENT_ID + "/Address";
final String RESOURCE_URI = "Employee('1')";
final ODataRequest request = createRequest(HttpMethod.POST, BASE_URI, ODATA_PATH);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0bd32951/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
new file mode 100644
index 0000000..ac111e0
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -0,0 +1,582 @@
+/*
+ * 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.server.core.batch.handler;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
+import org.apache.olingo.server.api.batch.ODataResponsePart;
+import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.core.ODataHandler;
+import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class MockedBatchHandlerTest {
+
+ private static final String BATCH_CONTENT_TYPE = "multipart/mixed;boundary=batch_12345";
+ private static final String BATCH_ODATA_PATH = "/$batch";
+ private static final String BATCH_REQUEST_URI = "http://localhost:8080/odata/$batch";
+ private static final String BASE_URI = "http://localhost:8080/odata";
+ private static final String CRLF = "\r\n";
+ private ODataHandler handler;
+ private int entityCounter = 1;
+
+ @Test
+ public void test() throws BatchException, IOException {
+ final String content = "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_12345" + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 4" + CRLF
+ + CRLF
+ + "PUT /$3/PropertyInt32 HTTP/1.1" + CRLF // Absolute URI with separate Host header and ref.
+ + "Host: http://localhost:8080/odata" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 5" + CRLF
+ + CRLF
+ + "POST http://localhost:8080/odata/$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF // Absolute URI with ref.
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 2" + CRLF
+ + CRLF
+ + "POST $1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF // Relative URI with ref.
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "POST http://localhost:8080/odata/ESAllPrim HTTP/1.1" + CRLF // Absolute URI
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 3" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF // Relative URI
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 6" + CRLF
+ + CRLF
+ + "PUT /ESAllPrim(1) HTTP/1.1" + CRLF // Absolute URI with separate Host header
+ + "Host: http://localhost:8080/odata"
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345--" + CRLF
+ + CRLF
+ + "--batch_12345--";
+ final Map<String, List<String>> header = getMimeHeader();
+ final ODataResponse response = new ODataResponse();
+ final BatchHandler batchHandler = buildBatchHandler(content, header);
+
+ batchHandler.process(response);
+
+ BufferedReaderIncludingLineEndings reader =
+ new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+
+ final List<String> responseContent = reader.toList();
+ reader.close();
+
+ int line = 0;
+ assertEquals(63, responseContent.size());
+
+ // Check change set
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertTrue(responseContent.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+
+ for (int i = 0; i < 6; i++) {
+ String contentId = checkChangeSetPartHeader(responseContent, line);
+ line += 6;
+
+ if ("1".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESAllPrim(1)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("2".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(3)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("3".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("4".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("5".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(2)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("6".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else {
+ fail();
+ }
+
+ assertEquals(CRLF, responseContent.get(line++));
+ }
+
+ // Close body part (change set)
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--changeset_"));
+
+ // Close batch
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertEquals(63, line);
+ }
+
+ @Test
+ public void testMultipleChangeSets() throws BatchException, IOException {
+ final String content = ""
+ + "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_12345" + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 2" + CRLF
+ + CRLF
+ + "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
+ + "Host: http://localhost:8080/odata" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345--" + CRLF
+
+ + "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_54321" + CRLF
+ + CRLF
+ + "--changeset_54321" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 2" + CRLF
+ + CRLF
+ + "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
+ + "Host: http://localhost:8080/odata" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_54321" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(2) HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_54321--" + CRLF
+
+ + CRLF
+ + "--batch_12345--";
+ final Map<String, List<String>> header = getMimeHeader();
+ final ODataResponse response = new ODataResponse();
+ final BatchHandler batchHandler = buildBatchHandler(content, header);
+
+ batchHandler.process(response);
+
+ BufferedReaderIncludingLineEndings reader =
+ new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+
+ final List<String> responseContent = reader.toList();
+ reader.close();
+
+ int line = 0;
+ assertEquals(49, responseContent.size());
+
+ // Check first change set
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertTrue(responseContent.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+
+ for (int i = 0; i < 2; i++) {
+ String contentId = checkChangeSetPartHeader(responseContent, line);
+ line += 6;
+
+ if ("1".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("2".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(1)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else {
+ fail();
+ }
+
+ assertEquals(CRLF, responseContent.get(line++));
+ }
+ // Close body part (1st change set)
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--changeset_"));
+
+ // Check second change set
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertTrue(responseContent.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+
+ for (int i = 0; i < 2; i++) {
+ String contentId = checkChangeSetPartHeader(responseContent, line);
+ line += 6;
+
+ if ("1".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("2".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(2)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else {
+ fail();
+ }
+
+ assertEquals(CRLF, responseContent.get(line++));
+ }
+ // Close body part (2nd change set)
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--changeset_"));
+
+ // Close batch
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+
+ assertEquals(49, line);
+ }
+
+ @Test
+ public void testMineBodyPartTransitiv() throws BatchException, IOException {
+ final String content = ""
+ + "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_12345" + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 4" + CRLF
+ + CRLF
+ + "POST $3/NavPropertyETTwoPrimOne HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 2" + CRLF
+ + CRLF
+ + "POST /$1/NavPropertyETTwoPrimMany HTTP/1.1" + CRLF
+ + "Host: http://localhost:8080/odata" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 3" + CRLF
+ + CRLF
+ + "POST $2/NavPropertyETAllPrimMany HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345--" + CRLF
+
+ + CRLF
+ + "--batch_12345--";
+
+ final Map<String, List<String>> header = getMimeHeader();
+ final ODataResponse response = new ODataResponse();
+ final BatchHandler batchHandler = buildBatchHandler(content, header);
+
+ batchHandler.process(response);
+
+ BufferedReaderIncludingLineEndings reader =
+ new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+
+ final List<String> responseContent = reader.toList();
+ reader.close();
+
+ int line = 0;
+ assertEquals(45, responseContent.size());
+
+ // Check change set
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertTrue(responseContent.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+
+ for (int i = 0; i < 4; i++) {
+ String contentId = checkChangeSetPartHeader(responseContent, line);
+ line += 6;
+
+ if ("1".equals(contentId)) {
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("2".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(1)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("3".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESAllPrim(2)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else if ("4".equals(contentId)) {
+ assertEquals("HTTP/1.1 201 Created" + CRLF, responseContent.get(line++));
+ assertEquals("Location: " + BASE_URI + "/ESTwoPrim(3)" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ } else {
+ fail();
+ }
+
+ assertEquals(CRLF, responseContent.get(line++));
+ }
+
+ // Close body part (change set)
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--changeset_"));
+
+ // Close batch
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertEquals(45, line);
+ }
+
+ @Before
+ public void setup() {
+ handler = null;
+ entityCounter = 1;
+ }
+
+ private String checkChangeSetPartHeader(final List<String> response, int line) {
+ assertEquals(CRLF, response.get(line++));
+ assertTrue(response.get(line++).contains("--changeset_"));
+ assertEquals("Content-Type: application/http" + CRLF, response.get(line++));
+ assertEquals("Content-Transfer-Encoding: binary" + CRLF, response.get(line++));
+
+ assertTrue(response.get(line).contains("Content-Id:"));
+ String contentId = response.get(line).split(":")[1].trim();
+ line++;
+
+ assertEquals(CRLF, response.get(line++));
+
+ return contentId;
+ }
+
+ /*
+ * Helper methods
+ */
+
+ private Map<String, List<String>> getMimeHeader() {
+ final Map<String, List<String>> header = new HashMap<String, List<String>>();
+ header.put(HttpHeader.CONTENT_TYPE, Arrays.asList(new String[] { BATCH_CONTENT_TYPE }));
+
+ return header;
+ }
+
+ private BatchHandler buildBatchHandler(final String content, Map<String, List<String>> header) throws BatchException,
+ UnsupportedEncodingException {
+
+ final ODataRequest request = buildODataRequest(content, header);
+ final ODataHandler oDataHandler = buildODataHandler(request);
+ final BatchProcessor batchProcessor = new BatchProcessorImpl();
+
+ return new BatchHandler(oDataHandler, request, batchProcessor, true);
+ }
+
+ private ODataHandler buildODataHandler(ODataRequest request) {
+ handler = mock(ODataHandler.class);
+ when(handler.process(request)).thenCallRealMethod();
+
+ return handler;
+ }
+
+ private ODataRequest buildODataRequest(String content, Map<String, List<String>> header)
+ throws UnsupportedEncodingException {
+ final ODataRequest request = new ODataRequest();
+
+ for (final String key : header.keySet()) {
+ request.addHeader(key, header.get(key));
+ }
+
+ request.setMethod(HttpMethod.POST);
+ request.setRawBaseUri(BASE_URI);
+ request.setRawODataPath(BATCH_ODATA_PATH);
+ request.setRawQueryPath("");
+ request.setRawRequestUri(BATCH_REQUEST_URI);
+ request.setRawServiceResolutionUri("");
+
+ request.setBody(new ByteArrayInputStream(content.getBytes("UTF-8")));
+
+ return request;
+ }
+
+ /**
+ * Batch processor
+ */
+ private class BatchProcessorImpl implements BatchProcessor {
+ @Override
+ public void init(OData odata, ServiceMetadata serviceMetadata) {}
+
+ @Override
+ public List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
+ BatchRequestPart requestPart) {
+ List<ODataResponse> responses = new ArrayList<ODataResponse>();
+
+ for (ODataRequest request : requests) {
+ // Mock the processor of the changeset requests
+ when(handler.process(request)).then(new Answer<ODataResponse>() {
+ @Override
+ public ODataResponse answer(InvocationOnMock invocation) throws Throwable {
+ Object[] arguments = invocation.getArguments();
+
+ return buildResponse((ODataRequest) arguments[0]);
+ }
+ });
+
+ try {
+ responses.add(operation.handleODataRequest(request, requestPart));
+ } catch (BatchException e) {
+ fail();
+ }
+ }
+
+ return responses;
+ }
+
+ @Override
+ public void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response) {
+ try {
+ final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody());
+ final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
+
+ for (BatchRequestPart part : parts) {
+ responseParts.add(operation.handleBatchRequest(part));
+ }
+
+ operation.writeResponseParts(responseParts, response);
+ } catch (BatchException e) {
+ throw new ODataRuntimeException(e);
+ } catch (IOException e) {
+ throw new ODataRuntimeException(e);
+ }
+ }
+ }
+
+ private ODataResponse buildResponse(ODataRequest request) {
+ final ODataResponse oDataResponse = new ODataResponse();
+
+ if (request.getMethod() == HttpMethod.POST) {
+ oDataResponse.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
+ oDataResponse.setHeader(HttpHeader.LOCATION, createResourceUri(request));
+ } else {
+ oDataResponse.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ }
+
+ final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
+ if (contentId != null) {
+ oDataResponse.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId);
+ }
+
+ return oDataResponse;
+ }
+
+ private String createResourceUri(final ODataRequest request) {
+ final String parts[] = request.getRawODataPath().split("/");
+ String oDataPath = "";
+
+ if (parts.length == 2) {
+ // Entity Collection
+ oDataPath = parts[1];
+ } else {
+ // Navigationproperty
+
+ final String navProperty = parts[parts.length - 1];
+ if (navProperty.equals("NavPropertyETTwoPrimMany")) {
+ oDataPath = "ESTwoPrim";
+ } else if (navProperty.equals("NavPropertyETAllPrimMany")) {
+ oDataPath = "ESAllPrim";
+ } else if (navProperty.equals("NavPropertyETTwoPrimOne")) {
+ oDataPath = "ESTwoPrim";
+ }
+ }
+
+ return BASE_URI + "/" + oDataPath + "(" + entityCounter++ + ")";
+ }
+}
[2/9] olingo-odata4 git commit: Changeset Sorter
Posted by ch...@apache.org.
Changeset Sorter
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/ee2451cb
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/ee2451cb
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/ee2451cb
Branch: refs/heads/olingo472
Commit: ee2451cbd064e3a5b4585f37192c983f32fe5c55
Parents: 15bd152
Author: Christian Holzer <c....@sap.com>
Authored: Tue Oct 28 18:18:21 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:55 2014 +0100
----------------------------------------------------------------------
.../olingo/server/api/batch/BatchOperation.java | 4 +-
.../server/api/processor/BatchProcessor.java | 10 +-
.../olingo/server/core/batch/StringUtil.java | 54 ------
.../core/batch/handler/BatchOperationImpl.java | 16 +-
.../core/batch/handler/BatchPartHandler.java | 65 ++++++--
.../server/core/batch/handler/UriMapping.java | 34 ++++
.../core/batch/parser/BatchRequestPartImpl.java | 4 +
.../olingo/server/core/batch/StringUtil.java | 54 ++++++
.../batch/handler/BatchChangeSetSorterTest.java | 164 +++++++++++++++++++
.../tecsvc/processor/TechnicalProcessor.java | 44 +----
10 files changed, 333 insertions(+), 116 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
index 8e438cf..af7d9c1 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/batch/BatchOperation.java
@@ -27,9 +27,9 @@ import org.apache.olingo.server.api.ODataResponse;
public interface BatchOperation {
public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException;
- public ODataResponse handleODataRequest(ODataRequest request);
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart);
- public ODataResponsePart handleBatchRequest(BatchRequestPart request);
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException;
public void writeResponseParts(List<ODataResponsePart> batchResponses, ODataResponse response) throws BatchException,
IOException;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
index 5a9518d..221b38a 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/BatchProcessor.java
@@ -6,9 +6,9 @@
* 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
@@ -23,9 +23,11 @@ import java.util.List;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.batch.BatchOperation;
+import org.apache.olingo.server.api.batch.BatchRequestPart;
public interface BatchProcessor extends Processor {
- void executeBatch(BatchOperation operation, ODataRequest requst, ODataResponse response);
+ void executeBatch(BatchOperation operation, ODataRequest requests, ODataResponse response);
- List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests);
+ List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests,
+ BatchRequestPart requestPart);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/StringUtil.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/StringUtil.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/StringUtil.java
deleted file mode 100644
index 2602852..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/StringUtil.java
+++ /dev/null
@@ -1,54 +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.server.core.batch;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings;
-
-public class StringUtil {
-
-
- public static String toString(final InputStream in) throws IOException {
- final StringBuilder builder = new StringBuilder();
- final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
- String currentLine;
-
- while((currentLine = reader.readLine()) != null) {
- builder.append(currentLine);
- }
-
- reader.close();
-
- return builder.toString();
- }
-
- public static InputStream toInputStream(final String string) {
- try {
- return new ByteArrayInputStream(string.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- throw new ODataRuntimeException("Charset UTF-8 not found");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
index bc148f0..1f5e243 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchOperationImpl.java
@@ -6,9 +6,9 @@
* 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
@@ -44,21 +44,21 @@ public class BatchOperationImpl implements BatchOperation {
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
writer = new BatchResponseWriter();
parser = new BatchParser(getContentType(request), request.getRawBaseUri(),
- request.getRawServiceResolutionUri(), isStrict);
+ request.getRawServiceResolutionUri(), isStrict);
}
@Override
public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException {
return parser.parseBatchRequest(in);
}
-
+
@Override
- public ODataResponse handleODataRequest(ODataRequest request) {
- return partHandler.handleODataRequest(request);
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) {
+ return partHandler.handleODataRequest(request, requestPart);
}
-
+
@Override
- public ODataResponsePart handleBatchRequest(BatchRequestPart request) {
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException {
return partHandler.handleBatchRequest(request);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
index a78d585..df23c55 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchPartHandler.java
@@ -19,11 +19,14 @@
package org.apache.olingo.server.core.batch.handler;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.batch.BatchException;
import org.apache.olingo.server.api.batch.BatchOperation;
import org.apache.olingo.server.api.batch.BatchRequestPart;
import org.apache.olingo.server.api.batch.ODataResponsePart;
@@ -36,7 +39,8 @@ public class BatchPartHandler {
private ODataHandler oDataHandler;
private BatchProcessor batchProcessor;
private BatchOperation batchOperation;
-
+ private Map<BatchRequestPart, UriMapping> uriMapping = new HashMap<BatchRequestPart, UriMapping>();
+
public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor,
final BatchOperation batchOperation) {
this.oDataHandler = oDataHandler;
@@ -44,23 +48,62 @@ public class BatchPartHandler {
this.batchOperation = batchOperation;
}
- public ODataResponse handleODataRequest(ODataRequest request) {
- final ODataResponse response = oDataHandler.process(request);
- response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, request.getHeader(BatchParserCommon.HTTP_CONTENT_ID));
+ public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) {
+ final ODataResponse response;
+
+ if(requestPart.isChangeSet()) {
+ final UriMapping mapping = getUriMappingOrDefault(requestPart);
+ final String reference = BatchChangeSetSorter.getReferenceInURI(request);
+ if(reference != null) {
+ BatchChangeSetSorter.replaceContentIdReference(request, reference, mapping.getUri(reference));
+ }
+
+ response = oDataHandler.process(request);
+
+ final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
+ final String locationHeader = request.getHeader(HttpHeader.LOCATION);
+ mapping.addMapping(contentId, locationHeader);
+ } else {
+ response = oDataHandler.process(request);
+ }
+
+ final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
+ if(contentId != null) {
+ response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId);
+ }
return response;
}
-
- public ODataResponsePart handleBatchRequest(BatchRequestPart request) {
- final List<ODataResponse> responses = new ArrayList<ODataResponse>();
-
+
+ private UriMapping getUriMappingOrDefault(final BatchRequestPart requestPart) {
+ UriMapping mapping = uriMapping.get(requestPart);
+
+ if(uriMapping == null) {
+ mapping = new UriMapping();
+ }
+ uriMapping.put(requestPart, mapping);
+
+ return mapping;
+ }
+
+ public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException {
if (request.isChangeSet()) {
- responses.addAll(batchProcessor.executeChangeSet(batchOperation, request.getRequests()));
- return new ODataResponsePartImpl(responses, true);
+ return handleChangeSet(request);
} else {
- responses.add(handleODataRequest(request.getRequests().get(0)));
+ final List<ODataResponse> responses = new ArrayList<ODataResponse>();
+ responses.add(handleODataRequest(request.getRequests().get(0), request));
+
return new ODataResponsePartImpl(responses, false);
}
}
+ private ODataResponsePart handleChangeSet(BatchRequestPart request) throws BatchException {
+ final List<ODataResponse> responses = new ArrayList<ODataResponse>();
+ final BatchChangeSetSorter sorter = new BatchChangeSetSorter(request.getRequests());
+
+ responses.addAll(batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request));
+
+ return new ODataResponsePartImpl(responses, true);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
new file mode 100644
index 0000000..0123320
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/UriMapping.java
@@ -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.server.core.batch.handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class UriMapping {
+ private Map<String, String> uriMapping = new HashMap<String, String>();
+
+ public void addMapping(final String contentId, final String uri) {
+ uriMapping.put(contentId, uri);
+ }
+
+ public String getUri(final String contentId) {
+ return uriMapping.get(contentId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchRequestPartImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchRequestPartImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchRequestPartImpl.java
index 6c80216..9765b37 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchRequestPartImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/parser/BatchRequestPartImpl.java
@@ -25,6 +25,10 @@ import java.util.List;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.batch.BatchRequestPart;
+/**
+ * Has to be immutable!
+ *
+ */
public class BatchRequestPartImpl implements BatchRequestPart {
private List<ODataRequest> requests = new ArrayList<ODataRequest>();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/StringUtil.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/StringUtil.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/StringUtil.java
new file mode 100644
index 0000000..2602852
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/StringUtil.java
@@ -0,0 +1,54 @@
+/*
+ * 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.server.core.batch;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.server.core.batch.parser.BufferedReaderIncludingLineEndings;
+
+public class StringUtil {
+
+
+ public static String toString(final InputStream in) throws IOException {
+ final StringBuilder builder = new StringBuilder();
+ final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+ String currentLine;
+
+ while((currentLine = reader.readLine()) != null) {
+ builder.append(currentLine);
+ }
+
+ reader.close();
+
+ return builder.toString();
+ }
+
+ public static InputStream toInputStream(final String string) {
+ try {
+ return new ByteArrayInputStream(string.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new ODataRuntimeException("Charset UTF-8 not found");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
new file mode 100644
index 0000000..9196514
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorterTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.server.core.batch.handler;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.batch.BatchException;
+import org.apache.olingo.server.core.batch.parser.BatchParserCommon;
+import org.junit.Test;
+
+public class BatchChangeSetSorterTest {
+
+ private static final String BASE_URI = "http://localhost/odata.src";
+
+ @Test
+ public void test() throws BatchException {
+ final List<ODataRequest> changeSet = new ArrayList<ODataRequest>();
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$1/Adress", "2"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employees", "1"));
+
+ BatchChangeSetSorter sorter = new BatchChangeSetSorter(changeSet);
+ final List<ODataRequest> sortedChangeSet = sorter.getOrderdRequests();
+
+ assertEquals(2, sortedChangeSet.size());
+ assertEquals("1", getContentId(sortedChangeSet.get(0)));
+ assertEquals("2", getContentId(sortedChangeSet.get(1)));
+ }
+
+ private String getContentId(ODataRequest request) {
+ return request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
+ }
+
+ @Test
+ public void testNoContentId() throws BatchException {
+ final List<ODataRequest> changeSet = new ArrayList<ODataRequest>();
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$1/Department", "2"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employees", "1"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('2')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('3')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$2/Manager", "3"));
+
+ BatchChangeSetSorter sorter = new BatchChangeSetSorter(changeSet);
+ final List<ODataRequest> sortedChangeSet = sorter.getOrderdRequests();
+
+ assertEquals(5, sortedChangeSet.size());
+ assertEquals("1", getContentId(sortedChangeSet.get(0)));
+ assertEquals(null, getContentId(sortedChangeSet.get(1)));
+ assertEquals(null, getContentId(sortedChangeSet.get(2)));
+ assertEquals("2", getContentId(sortedChangeSet.get(3)));
+ assertEquals("3", getContentId(sortedChangeSet.get(4)));
+ }
+
+ @SuppressWarnings("unused")
+ @Test(expected=BatchException.class)
+ public void testContentIdNotAvailable() throws BatchException {
+ final List<ODataRequest> changeSet = new ArrayList<ODataRequest>();
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$1/Department", "2"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employees", "1"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('2')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('3')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$4/Manager", "3")); //4 is not available
+
+ BatchChangeSetSorter sorter = new BatchChangeSetSorter(changeSet);
+ final List<ODataRequest> sortedChangeSet = sorter.getOrderdRequests();
+ }
+
+ @Test
+ public void testStringAsContentId() throws BatchException {
+ final List<ODataRequest> changeSet = new ArrayList<ODataRequest>();
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$One/Department", "Two"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employees", "One"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('2')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "Employee('3')/Address"));
+ changeSet.add(createRequest(HttpMethod.POST, BASE_URI, "$Two/Manager", "Three"));
+
+ BatchChangeSetSorter sorter = new BatchChangeSetSorter(changeSet);
+ final List<ODataRequest> sortedChangeSet = sorter.getOrderdRequests();
+
+ assertEquals(5, sortedChangeSet.size());
+ assertEquals("One", getContentId(sortedChangeSet.get(0)));
+ assertEquals(null, getContentId(sortedChangeSet.get(1)));
+ assertEquals(null, getContentId(sortedChangeSet.get(2)));
+ assertEquals("Two", getContentId(sortedChangeSet.get(3)));
+ assertEquals("Three", getContentId(sortedChangeSet.get(4)));
+ }
+
+ @Test
+ public void testRewriting() {
+ final String CONTENT_ID = "1";
+ final String ODATA_PATH ="$" + CONTENT_ID + "/Address";
+ final String RESOURCE_URI = "Employee('1')";
+ final ODataRequest request = createRequest(HttpMethod.POST, BASE_URI, ODATA_PATH);
+
+ BatchChangeSetSorter.replaceContentIdReference(request, CONTENT_ID, RESOURCE_URI);
+ assertEquals(BASE_URI + "/" + "Employee('1')/Address", request.getRawRequestUri());
+ assertEquals("Employee('1')/Address", request.getRawODataPath());
+ }
+
+ @Test
+ public void testRewritingNoContentId() {
+ final String CONTENT_ID = "1";
+ final String ODATA_PATH = /* "$" + CONTENT_ID + */ "Address";
+ final String RESOURCE_URI = "Employee('1')";
+ final ODataRequest request = createRequest(HttpMethod.POST, BASE_URI, ODATA_PATH);
+
+ BatchChangeSetSorter.replaceContentIdReference(request, CONTENT_ID, RESOURCE_URI);
+ assertEquals(BASE_URI + "/" + "Address", request.getRawRequestUri());
+ assertEquals("Address", request.getRawODataPath());
+ }
+
+ @Test
+ public void testWrongRewriting() {
+ final String CONTENT_ID = "1";
+ final String ODATA_PATH = /*"$1" */ "$2" + "/Address";
+ final String RESOURCE_URI = "Employee('1')";
+ final ODataRequest request = createRequest(HttpMethod.POST, BASE_URI, ODATA_PATH);
+
+ BatchChangeSetSorter.replaceContentIdReference(request, CONTENT_ID, RESOURCE_URI);
+ assertEquals(BASE_URI + "/" + "$2/Address", request.getRawRequestUri());
+ assertEquals("$2/Address", request.getRawODataPath());
+ }
+
+ private ODataRequest createRequest(HttpMethod method, String baseUrl, String oDataPath) {
+ return createRequest(method, baseUrl, oDataPath, null);
+ }
+
+ private ODataRequest createRequest(HttpMethod method, String baseUrl, String oDataPath, String contentId) {
+ final ODataRequest request = new ODataRequest();
+ request.setBody(new ByteArrayInputStream(new byte[0]));
+ request.setMethod(HttpMethod.GET);
+ request.setRawBaseUri(baseUrl);
+ request.setRawODataPath(oDataPath);
+ request.setRawRequestUri(baseUrl + "/" + oDataPath);
+ request.setRawQueryPath("");
+
+ if(contentId != null) {
+ request.addHeader(BatchParserCommon.HTTP_CONTENT_ID, Arrays.asList(new String[] { contentId }));
+ }
+ return request;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ee2451cb/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index b59c92e..e5a0d44 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -21,7 +21,6 @@ package org.apache.olingo.server.tecsvc.processor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -74,7 +73,7 @@ import org.apache.olingo.server.tecsvc.data.DataProvider;
/**
* Technical Processor which provides currently implemented processor functionality.
*/
-public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor, BatchProcessor {
+public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
private OData odata;
private DataProvider dataProvider;
@@ -198,12 +197,12 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
List<UriResource> subResPaths = resourcePaths.subList(1, resourcePaths.size());
for (UriResource subResPath : subResPaths) {
UriResourceKind kind = subResPath.getKind();
- if(kind != UriResourceKind.primitiveProperty
- && kind != UriResourceKind.complexProperty
- && kind != UriResourceKind.count
- && kind != UriResourceKind.value) {
+ if (kind != UriResourceKind.primitiveProperty
+ && kind != UriResourceKind.complexProperty
+ && kind != UriResourceKind.count
+ && kind != UriResourceKind.value) {
throw new ODataApplicationException("Invalid resource type.",
- HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}
@@ -219,6 +218,7 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
final EdmEntitySet entitySet, final boolean isSingleEntity,
final ExpandOption expand, final SelectOption select,
final List<UriParameter> keys, final String propertyPath) throws SerializerException {
+
return ContextURL.with().entitySet(entitySet)
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
.suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null)
@@ -226,7 +226,6 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
.navOrPropertyPath(propertyPath)
.build();
}
-
@Override
public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
@@ -334,33 +333,4 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
}
}
}
-
- @Override
- public void executeBatch(BatchOperation operation, ODataRequest requst, ODataResponse response) {
- try {
- final List<BatchRequestPart> parts = operation.parseBatchRequest(requst.getBody());
- final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
-
- for(BatchRequestPart part : parts) {
- responseParts.add(operation.handleBatchRequest(part));
- }
-
- operation.writeResponseParts(responseParts, response);
- } catch (BatchException e) {
- throw new ODataRuntimeException(e);
- } catch (IOException e) {
- throw new ODataRuntimeException(e);
- }
- }
-
- @Override
- public List<ODataResponse> executeChangeSet(BatchOperation operation, List<ODataRequest> requests) {
- List<ODataResponse> responses = new ArrayList<ODataResponse>();
-
- for(ODataRequest request : requests) {
- responses.add(operation.handleODataRequest(request));
- }
-
- return responses;
- }
}
[8/9] olingo-odata4 git commit: Test added to MockedBatchHandlerTest
Posted by ch...@apache.org.
Test added to MockedBatchHandlerTest
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/bc46b535
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/bc46b535
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/bc46b535
Branch: refs/heads/olingo472
Commit: bc46b5352e9cb9dae3e46478dab34287e2ea62bc
Parents: 4ff5fb9
Author: Christian Holzer <c....@sap.com>
Authored: Tue Nov 11 16:17:51 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:11:01 2014 +0100
----------------------------------------------------------------------
.../batch/handler/MockedBatchHandlerTest.java | 84 +++++++++++++++-----
1 file changed, 63 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bc46b535/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
index 7a85ffa..b81edb8 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -200,6 +200,46 @@ public class MockedBatchHandlerTest {
}
@Test
+ public void testGetRequest() throws BatchException, IOException {
+ final String content = ""
+ + "--batch_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + CRLF
+ + "GET ESAllPrim(0) HTTP/1.1" + CRLF
+ + CRLF
+ + CRLF
+ + "--batch_12345--";
+
+ final Map<String, List<String>> header = getMimeHeader();
+ final ODataResponse response = new ODataResponse();
+ final ODataRequest request = buildODataRequest(content, header);
+
+ batchHandler.process(request, response, true);
+
+ BufferedReaderIncludingLineEndings reader =
+ new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+
+ final List<String> responseContent = reader.toList();
+ int line = 0;
+
+ assertEquals(9, responseContent.size());
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+ assertEquals("Content-Type: application/http" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Transfer-Encoding: binary" + CRLF, responseContent.get(line++));
+ assertEquals(CRLF, responseContent.get(line++));
+ assertEquals("HTTP/1.1 200 OK" + CRLF, responseContent.get(line++));
+ assertEquals("Content-Length: 0" + CRLF, responseContent.get(line++));
+ assertEquals(CRLF, responseContent.get(line++));
+ assertEquals(CRLF, responseContent.get(line++));
+ assertTrue(responseContent.get(line++).contains("--batch_"));
+
+ assertEquals(9, line);
+
+ reader.close();
+ }
+
+ @Test
public void testMultipleChangeSets() throws BatchException, IOException {
final String content = ""
+ "--batch_12345" + CRLF
@@ -442,8 +482,8 @@ public class MockedBatchHandlerTest {
return contentId;
}
-
- @Test(expected=BatchException.class)
+
+ @Test(expected = BatchException.class)
public void testInvalidMethod() throws UnsupportedEncodingException, BatchException {
final String content = ""
+ "--batch_12345" + CRLF
@@ -454,23 +494,23 @@ public class MockedBatchHandlerTest {
+ "Content-Transfer-Encoding: binary" + CRLF
+ "Content-Id: 1" + CRLF
+ CRLF
- + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ "Content-Type: application/json;odata=verbose" + CRLF
+ CRLF
+ CRLF
+ "--changeset_12345--" + CRLF
+ CRLF
+ "--batch_12345--";
-
+
final Map<String, List<String>> header = getMimeHeader();
final ODataResponse response = new ODataResponse();
final ODataRequest request = buildODataRequest(content, header);
request.setMethod(HttpMethod.GET);
-
+
batchHandler.process(request, response, true);
}
-
- @Test(expected=BatchException.class)
+
+ @Test(expected = BatchException.class)
public void testInvalidContentType() throws UnsupportedEncodingException, BatchException {
final String content = ""
+ "--batch_12345" + CRLF
@@ -481,22 +521,22 @@ public class MockedBatchHandlerTest {
+ "Content-Transfer-Encoding: binary" + CRLF
+ "Content-Id: 1" + CRLF
+ CRLF
- + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ "Content-Type: application/json;odata=verbose" + CRLF
+ CRLF
+ CRLF
+ "--changeset_12345--" + CRLF
+ CRLF
+ "--batch_12345--";
-
+
final Map<String, List<String>> header = new HashMap<String, List<String>>();
header.put(HttpHeader.CONTENT_TYPE, Arrays.asList(new String[] { "application/http" }));
final ODataResponse response = new ODataResponse();
final ODataRequest request = buildODataRequest(content, header);
-
+
batchHandler.process(request, response, true);
}
-
+
/*
* Helper methods
*/
@@ -540,16 +580,6 @@ public class MockedBatchHandlerTest {
List<ODataResponse> responses = new ArrayList<ODataResponse>();
for (ODataRequest request : requests) {
- // Mock the processor for a given requests
- when(oDataHandler.process(request)).then(new Answer<ODataResponse>() {
- @Override
- public ODataResponse answer(InvocationOnMock invocation) throws Throwable {
- Object[] arguments = invocation.getArguments();
-
- return buildResponse((ODataRequest) arguments[0]);
- }
- });
-
try {
responses.add(operation.handleODataRequest(request, requestPart));
} catch (BatchException e) {
@@ -567,6 +597,18 @@ public class MockedBatchHandlerTest {
final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
for (BatchRequestPart part : parts) {
+ for (final ODataRequest oDataRequest : part.getRequests()) {
+ // Mock the processor for a given requests
+ when(oDataHandler.process(oDataRequest)).then(new Answer<ODataResponse>() {
+ @Override
+ public ODataResponse answer(InvocationOnMock invocation) throws Throwable {
+ Object[] arguments = invocation.getArguments();
+
+ return buildResponse((ODataRequest) arguments[0]);
+ }
+ });
+ }
+
responseParts.add(operation.handleBatchRequest(part));
}
[6/9] olingo-odata4 git commit: Merge method removed
Posted by ch...@apache.org.
Merge method removed
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/5f4eb03d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/5f4eb03d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/5f4eb03d
Branch: refs/heads/olingo472
Commit: 5f4eb03df3e980dd2c4593ddb900e15290ac057d
Parents: bb4b554
Author: Christian Holzer <c....@sap.com>
Authored: Thu Nov 6 17:48:33 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:59 2014 +0100
----------------------------------------------------------------------
.../server/core/batch/transformator/HttpRequestStatusLine.java | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5f4eb03d/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
index 416d593..c08bb2e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/transformator/HttpRequestStatusLine.java
@@ -40,10 +40,7 @@ public class HttpRequestStatusLine {
private static final Set<String> HTTP_BATCH_METHODS = new HashSet<String>(Arrays.asList(new String[] { "GET" }));
private static final Set<String> HTTP_CHANGE_SET_METHODS = new HashSet<String>(Arrays.asList(new String[] { "POST",
- "PUT", "DELETE", "MERGE", "PATCH" }));
- // TODO Is Merge still supported?
- // What`s New in OData 4: 2.7.2 Pruned: MERGE
- // MERGE was used to do PATCH before PATCH existed. Now that we have PATCH, we no longer need MERGE. => No
+ "PUT", "DELETE", "PATCH" }));
private static final String HTTP_VERSION = "HTTP/1.1";
final private Line statusLine;
[5/9] olingo-odata4 git commit: Tests added
Posted by ch...@apache.org.
Tests added
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/bb4b5541
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/bb4b5541
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/bb4b5541
Branch: refs/heads/olingo472
Commit: bb4b554116382e61519c6f7e98010aaff31eb441
Parents: 6c7d11f
Author: Christian Holzer <c....@sap.com>
Authored: Wed Nov 5 16:18:40 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Nov 13 17:10:58 2014 +0100
----------------------------------------------------------------------
.../batch/handler/BatchChangeSetSorter.java | 7 +--
.../batch/handler/MockedBatchHandlerTest.java | 56 +++++++++++++++++++-
2 files changed, 59 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb4b5541/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
index 408159e..5e1c276 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batch/handler/BatchChangeSetSorter.java
@@ -99,10 +99,11 @@ public class BatchChangeSetSorter {
}
private List<ODataRequest> getRequestsWithoutReferences() {
- final List<ODataRequest> requestsWithoutReference = requestReferenceMapping.get(null);
+ List<ODataRequest> requests = requestReferenceMapping.get(null);
requestReferenceMapping.remove(null);
-
- return requestsWithoutReference;
+
+ requests = (requests == null) ? new ArrayList<ODataRequest>() : requests;
+ return requests;
}
private void addRequestsToKnownContentIds(List<ODataRequest> requestsWithoutReference) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb4b5541/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
index d772fbc..e1864e2 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batch/handler/MockedBatchHandlerTest.java
@@ -442,7 +442,61 @@ public class MockedBatchHandlerTest {
return contentId;
}
-
+
+ @Test(expected=BatchException.class)
+ public void testInvalidMethod() throws UnsupportedEncodingException, BatchException {
+ final String content = ""
+ + "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_12345" + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345--" + CRLF
+ + CRLF
+ + "--batch_12345--";
+
+ final Map<String, List<String>> header = getMimeHeader();
+ final ODataResponse response = new ODataResponse();
+ final ODataRequest request = buildODataRequest(content, header);
+ request.setMethod(HttpMethod.GET);
+
+ batchHandler.process(request, response, true);
+ }
+
+ @Test(expected=BatchException.class)
+ public void testInvalidContentType() throws UnsupportedEncodingException, BatchException {
+ final String content = ""
+ + "--batch_12345" + CRLF
+ + "Content-Type: multipart/mixed; boundary=changeset_12345" + CRLF
+ + CRLF
+ + "--changeset_12345" + CRLF
+ + "Content-Type: application/http" + CRLF
+ + "Content-Transfer-Encoding: binary" + CRLF
+ + "Content-Id: 1" + CRLF
+ + CRLF
+ + "PUT ESAllPrim(1) HTTP/1.1" + CRLF
+ + "Content-Type: application/json;odata=verbose" + CRLF
+ + CRLF
+ + CRLF
+ + "--changeset_12345--" + CRLF
+ + CRLF
+ + "--batch_12345--";
+
+ final Map<String, List<String>> header = new HashMap<String, List<String>>();
+ header.put(HttpHeader.CONTENT_TYPE, Arrays.asList(new String[] { "application/http" }));
+ final ODataResponse response = new ODataResponse();
+ final ODataRequest request = buildODataRequest(content, header);
+
+ batchHandler.process(request, response, true);
+ }
+
/*
* Helper methods
*/