Api Refactoring

Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
Christian Holzer 2014-11-11 16:50:03 +01:00 committed by Christian Amend
parent bc46b5352e
commit ad177ac11e
7 changed files with 75 additions and 80 deletions

View File

@ -18,14 +18,13 @@
*/package org.apache.olingo.server.api.batch; */package org.apache.olingo.server.api.batch;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.List; import java.util.List;
import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ODataResponse;
public interface BatchOperation { 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; public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException;

View File

@ -107,7 +107,7 @@ public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProce
boolean continueOnError = shouldContinueOnError(request); boolean continueOnError = shouldContinueOnError(request);
try { try {
final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody()); final List<BatchRequestPart> parts = operation.parseBatchRequest(request, true);
final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>(); final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
for (BatchRequestPart part : parts) { for (BatchRequestPart part : parts) {

View File

@ -19,7 +19,6 @@
package org.apache.olingo.server.core.batch.handler; package org.apache.olingo.server.core.batch.handler;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.List; import java.util.List;
import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpHeader;
@ -43,13 +42,13 @@ public class BatchOperationImpl implements BatchOperation {
final boolean isStrict) { final boolean isStrict) {
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this); partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
writer = new BatchResponseWriter(); writer = new BatchResponseWriter();
parser = new BatchParser(getContentType(request), request.getRawBaseUri(), parser = new BatchParser();
request.getRawServiceResolutionUri(), isStrict);
} }
@Override @Override
public List<BatchRequestPart> parseBatchRequest(InputStream in) throws BatchException { public List<BatchRequestPart> parseBatchRequest(ODataRequest request, boolean isStrict) throws BatchException {
return parser.parseBatchRequest(in); return parser.parseBatchRequest(request.getBody(), getContentType(request), request.getRawBaseUri(),
request.getRawServiceResolutionUri(), isStrict);
} }
@Override @Override

View File

@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -18,9 +18,7 @@
*/ */
package org.apache.olingo.server.core.batch.handler; package org.apache.olingo.server.core.batch.handler;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.ODataRuntimeException;
@ -43,7 +41,7 @@ public class BatchPartHandler {
private BatchProcessor batchProcessor; private BatchProcessor batchProcessor;
private BatchOperation batchOperation; private BatchOperation batchOperation;
private Map<BatchRequestPart, UriMapping> uriMapping = new HashMap<BatchRequestPart, UriMapping>(); private Map<BatchRequestPart, UriMapping> uriMapping = new HashMap<BatchRequestPart, UriMapping>();
public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor, public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor,
final BatchOperation batchOperation) { final BatchOperation batchOperation) {
this.oDataHandler = oDataHandler; this.oDataHandler = oDataHandler;
@ -53,12 +51,12 @@ public class BatchPartHandler {
public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException { public ODataResponse handleODataRequest(ODataRequest request, BatchRequestPart requestPart) throws BatchException {
final ODataResponse response; final ODataResponse response;
if(requestPart.isChangeSet()) { if (requestPart.isChangeSet()) {
final UriMapping mapping = replaceReference(request, requestPart); final UriMapping mapping = replaceReference(request, requestPart);
response = oDataHandler.process(request); response = oDataHandler.process(request);
// Store resource URI // Store resource URI
final String resourceUri = getODataPath(request, response); final String resourceUri = getODataPath(request, response);
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID); final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
@ -67,20 +65,20 @@ public class BatchPartHandler {
} else { } else {
response = oDataHandler.process(request); response = oDataHandler.process(request);
} }
// Add content id to response // Add content id to response
final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID); final String contentId = request.getHeader(BatchParserCommon.HTTP_CONTENT_ID);
if(contentId != null) { if (contentId != null) {
response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId); response.setHeader(BatchParserCommon.HTTP_CONTENT_ID, contentId);
} }
return response; return response;
} }
private String getODataPath(ODataRequest request, ODataResponse response) throws BatchException { private String getODataPath(ODataRequest request, ODataResponse response) throws BatchException {
String resourceUri = null; String resourceUri = null;
if(request.getMethod() == HttpMethod.POST) { if (request.getMethod() == HttpMethod.POST) {
// Create entity // Create entity
// The URI of the new resource will be generated by the server and published in the location header // 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()); 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 // These methods still addresses a given resource, so we use the URI given by the request
resourceUri = request.getRawODataPath(); resourceUri = request.getRawODataPath();
} }
return resourceUri; return resourceUri;
} }
private UriMapping replaceReference(ODataRequest request, BatchRequestPart requestPart) { private UriMapping replaceReference(ODataRequest request, BatchRequestPart requestPart) {
final UriMapping mapping = getUriMappingOrDefault(requestPart); final UriMapping mapping = getUriMappingOrDefault(requestPart);
final String reference = BatchChangeSetSorter.getReferenceInURI(request); final String reference = BatchChangeSetSorter.getReferenceInURI(request);
if(reference != null) { if (reference != null) {
final String replacement = mapping.getUri(reference); final String replacement = mapping.getUri(reference);
if(replacement != null) { if (replacement != null) {
BatchChangeSetSorter.replaceContentIdReference(request, reference, replacement); BatchChangeSetSorter.replaceContentIdReference(request, reference, replacement);
} else { } else {
throw new ODataRuntimeException("Required Content-Id for reference \"" + reference + "\" not found."); throw new ODataRuntimeException("Required Content-Id for reference \"" + reference + "\" not found.");
} }
} }
return mapping; return mapping;
} }
private UriMapping getUriMappingOrDefault(final BatchRequestPart requestPart) { private UriMapping getUriMappingOrDefault(final BatchRequestPart requestPart) {
UriMapping mapping = uriMapping.get(requestPart); UriMapping mapping = uriMapping.get(requestPart);
if(mapping == null) { if (mapping == null) {
mapping = new UriMapping(); mapping = new UriMapping();
} }
uriMapping.put(requestPart, mapping); uriMapping.put(requestPart, mapping);
return mapping; return mapping;
} }
public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException { public ODataResponsePart handleBatchRequest(BatchRequestPart request) throws BatchException {
if (request.isChangeSet()) { if (request.isChangeSet()) {
return handleChangeSet(request); return handleChangeSet(request);
} else { } else {
final List<ODataResponse> responses = new ArrayList<ODataResponse>(); final ODataResponse response = handleODataRequest(request.getRequests().get(0), request);
responses.add(handleODataRequest(request.getRequests().get(0), request));
return new ODataResponsePart(responses, false); return new ODataResponsePart(response, false);
} }
} }
private ODataResponsePart handleChangeSet(BatchRequestPart request) throws BatchException { private ODataResponsePart handleChangeSet(BatchRequestPart request) throws BatchException {
final BatchChangeSetSorter sorter = new BatchChangeSetSorter(request.getRequests()); final BatchChangeSetSorter sorter = new BatchChangeSetSorter(request.getRequests());
return batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request); return batchProcessor.executeChangeSet(batchOperation, sorter.getOrderdRequests(), request);
} }
private static class UriMapping { private static class UriMapping {
private Map<String, String> uriMapping = new HashMap<String, String>(); private Map<String, String> uriMapping = new HashMap<String, String>();
public void addMapping(final String contentId, final String uri) { public void addMapping(final String contentId, final String uri) {
uriMapping.put(contentId, uri); uriMapping.put(contentId, uri);
} }
public String getUri(final String contentId) { public String getUri(final String contentId) {
return uriMapping.get(contentId); return uriMapping.get(contentId);
} }

View File

@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "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 { public class BatchParser {
private final String contentTypeMime; private String contentTypeMime;
private final String baseUri; private String rawServiceResolutionUri;
private final String rawServiceResolutionUri; private boolean isStrict;
private final boolean isStrict;
public BatchParser(final String contentType, final String baseUri, final String serviceResolutionUri,
final boolean isStrict) {
contentTypeMime = contentType;
this.baseUri = BatchParserCommon.removeEndingSlash(baseUri);
this.isStrict = isStrict;
this.rawServiceResolutionUri = serviceResolutionUri;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<BatchRequestPart> parseBatchRequest(final InputStream in) throws BatchException { public List<BatchRequestPart> parseBatchRequest(final InputStream in, final String contentType, final String baseUri,
final String serviceResolutionUri, final boolean isStrict) throws BatchException {
contentTypeMime = contentType;
this.isStrict = isStrict;
this.rawServiceResolutionUri = serviceResolutionUri;
return (List<BatchRequestPart>) parse(in, new BatchRequestTransformator(baseUri, rawServiceResolutionUri)); return (List<BatchRequestPart>) parse(in, new BatchRequestTransformator(baseUri, rawServiceResolutionUri));
} }

View File

@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -196,8 +196,9 @@ public class BatchRequestParserTest {
+ "--batch_1.2+34:2j)0?" + CRLF + "--batch_1.2+34:2j)0?" + CRLF
+ GET_REQUEST + GET_REQUEST
+ "--batch_1.2+34:2j)0?--"; + "--batch_1.2+34:2j)0?--";
final BatchParser parser = new BatchParser(contentType, SERVICE_ROOT, "", true); final BatchParser parser = new BatchParser();
final List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(StringUtil.toInputStream(batch)); final List<BatchRequestPart> batchRequestParts =
parser.parseBatchRequest(StringUtil.toInputStream(batch), contentType, SERVICE_ROOT, "", true);
assertNotNull(batchRequestParts); assertNotNull(batchRequestParts);
assertFalse(batchRequestParts.isEmpty()); assertFalse(batchRequestParts.isEmpty());
@ -210,10 +211,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb84-2f7f" + CRLF + "--batch_1740-bb84-2f7f" + CRLF
+ GET_REQUEST + GET_REQUEST
+ "--batch_1740-bb84-2f7f--"; + "--batch_1740-bb84-2f7f--";
final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true); final BatchParser parser = new BatchParser();
try { try {
parser.parseBatchRequest(StringUtil.toInputStream(batch)); parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail(); fail();
} catch (BatchException e) { } catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE); assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE);
@ -224,15 +225,16 @@ public class BatchRequestParserTest {
public void testContentTypeCharset() throws BatchException { public void testContentTypeCharset() throws BatchException {
final String contentType = "multipart/mixed; charset=UTF-8;boundary=batch_14d1-b293-b99a"; final String contentType = "multipart/mixed; charset=UTF-8;boundary=batch_14d1-b293-b99a";
final String batch = "" final String batch = ""
+ "--batch_14d1-b293-b99a" + CRLF + "--batch_14d1-b293-b99a" + CRLF
+ GET_REQUEST + GET_REQUEST
+ "--batch_14d1-b293-b99a--"; + "--batch_14d1-b293-b99a--";
final BatchParser parser = new BatchParser(contentType, SERVICE_ROOT, "", true); final BatchParser parser = new BatchParser();
final List<BatchRequestPart> parts = parser.parseBatchRequest(StringUtil.toInputStream(batch)); final List<BatchRequestPart> parts =
parser.parseBatchRequest(StringUtil.toInputStream(batch), contentType, SERVICE_ROOT, "", true);
assertEquals(1, parts.size()); assertEquals(1, parts.size());
} }
@Test @Test
public void testBatchWithoutBoundaryParameter() throws UnsupportedEncodingException { public void testBatchWithoutBoundaryParameter() throws UnsupportedEncodingException {
final String invalidContentType = "multipart/mixed"; final String invalidContentType = "multipart/mixed";
@ -240,10 +242,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb84-2f7f" + CRLF + "--batch_1740-bb84-2f7f" + CRLF
+ GET_REQUEST + GET_REQUEST
+ "--batch_1740-bb84-2f7f--"; + "--batch_1740-bb84-2f7f--";
final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true); final BatchParser parser = new BatchParser();
try { try {
parser.parseBatchRequest(StringUtil.toInputStream(batch)); parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail(); fail();
} catch (BatchException e) { } catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE); assertMessageKey(e, BatchException.MessageKeys.INVALID_CONTENT_TYPE);
@ -257,10 +259,10 @@ public class BatchRequestParserTest {
+ "--batch_1740-bb:84-2f7f" + CRLF + "--batch_1740-bb:84-2f7f" + CRLF
+ GET_REQUEST + GET_REQUEST
+ "--batch_1740-bb:84-2f7f--"; + "--batch_1740-bb:84-2f7f--";
final BatchParser parser = new BatchParser(invalidContentType, SERVICE_ROOT, "", true); final BatchParser parser = new BatchParser();
try { try {
parser.parseBatchRequest(StringUtil.toInputStream(batch)); parser.parseBatchRequest(StringUtil.toInputStream(batch), invalidContentType, SERVICE_ROOT, "", true);
fail(); fail();
} catch (BatchException e) { } catch (BatchException e) {
assertMessageKey(e, BatchException.MessageKeys.INVALID_BOUNDARY); assertMessageKey(e, BatchException.MessageKeys.INVALID_BOUNDARY);
@ -453,16 +455,16 @@ public class BatchRequestParserTest {
parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_CLOSE_DELIMITER); parseInvalidBatchBody(batch, BatchException.MessageKeys.MISSING_CLOSE_DELIMITER);
} }
@Test @Test
public void testEmptyRequest() throws BatchException, UnsupportedEncodingException { public void testEmptyRequest() throws BatchException, UnsupportedEncodingException {
final String batch = "" final String batch = ""
+ "--batch_8194-cf13-1f56--"; + "--batch_8194-cf13-1f56--";
final List<BatchRequestPart> parts = parse(batch); final List<BatchRequestPart> parts = parse(batch);
assertEquals(0, parts.size()); assertEquals(0, parts.size());
} }
@Test @Test
public void testBadRequest() throws UnsupportedEncodingException { public void testBadRequest() throws UnsupportedEncodingException {
final String batch = "This is a bad request. There is no syntax and also no semantic"; 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); final List<BatchRequestPart> parts = parse(batch);
assertEquals(1, parts.size()); assertEquals(1, parts.size());
final BatchRequestPart part = parts.get(0); final BatchRequestPart part = parts.get(0);
assertTrue(part.isChangeSet()); assertTrue(part.isChangeSet());
assertEquals(0, part.getRequests().size()); assertEquals(0, part.getRequests().size());
@ -1272,8 +1274,9 @@ public class BatchRequestParserTest {
} }
private List<BatchRequestPart> parse(final InputStream in, final boolean isStrict) throws BatchException { private List<BatchRequestPart> parse(final InputStream in, final boolean isStrict) throws BatchException {
final BatchParser parser = new BatchParser(CONTENT_TYPE, SERVICE_ROOT, "", isStrict); final BatchParser parser = new BatchParser();
final List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in); final List<BatchRequestPart> batchRequestParts =
parser.parseBatchRequest(in, CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
assertNotNull(batchRequestParts); assertNotNull(batchRequestParts);
@ -1295,10 +1298,10 @@ public class BatchRequestParserTest {
private void parseInvalidBatchBody(final String batch, final MessageKeys key, final boolean isStrict) private void parseInvalidBatchBody(final String batch, final MessageKeys key, final boolean isStrict)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
final BatchParser parser = new BatchParser(CONTENT_TYPE, SERVICE_ROOT, "", isStrict); final BatchParser parser = new BatchParser();
try { try {
parser.parseBatchRequest(StringUtil.toInputStream(batch)); parser.parseBatchRequest(StringUtil.toInputStream(batch), CONTENT_TYPE, SERVICE_ROOT, "", isStrict);
fail("No exception thrown. Expect: " + key.toString()); fail("No exception thrown. Expect: " + key.toString());
} catch (BatchException e) { } catch (BatchException e) {
assertMessageKey(e, key); assertMessageKey(e, key);

View File

@ -593,7 +593,7 @@ public class MockedBatchHandlerTest {
@Override @Override
public void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response) { public void executeBatch(BatchOperation operation, ODataRequest request, ODataResponse response) {
try { try {
final List<BatchRequestPart> parts = operation.parseBatchRequest(request.getBody()); final List<BatchRequestPart> parts = operation.parseBatchRequest(request, true);
final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>(); final List<ODataResponsePart> responseParts = new ArrayList<ODataResponsePart>();
for (BatchRequestPart part : parts) { for (BatchRequestPart part : parts) {