[OLINGO-313] version header support

This commit is contained in:
Stephan Klevenz 2014-06-03 16:20:34 +02:00
parent 9ae26a709b
commit f68aa54e12
5 changed files with 85 additions and 17 deletions

View File

@ -152,4 +152,14 @@ public interface HttpHeader {
*/ */
public static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override"; public static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override";
/**
* OData Custom Header
*/
public static final String ODATA_VERSION = "OData-Version";
/**
* OData Custom Header
*/
public static final String ODATA_MAX_VERSION = "OData-MaxVersion";
} }

View File

@ -19,7 +19,6 @@
package org.apache.olingo.server.api; package org.apache.olingo.server.api;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -44,14 +43,23 @@ public class ODataRequest {
this.method = method; this.method = method;
} }
public Map<String, List<String>> getHeaders() { /**
return Collections.unmodifiableMap(headers); * Add header to request where name handled as case insensitive key.
* @param name case insensitive header name
* @param values
*/
public void addHeader(String name, List<String> values) {
headers.put(name.toUpperCase(), values);
} }
public void setHeaders(final Map<String, List<String>> headers) { /**
this.headers = headers; * Returns header value for name where name is a case insensitive key.
* @return the header value or null if not found
*/
public List<String> getHeader(String name) {
return headers.get(name.toUpperCase());
} }
public InputStream getBody() { public InputStream getBody() {
return body; return body;
} }

View File

@ -19,12 +19,15 @@
package org.apache.olingo.server.core; package org.apache.olingo.server.core;
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;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.http.HttpContentType; import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpMethod; import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.OData;
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;
@ -59,6 +62,8 @@ public class ODataHandler {
try { try {
ODataResponse response = new ODataResponse(); ODataResponse response = new ODataResponse();
validateODataVersion(request, response);
Parser parser = new Parser(); Parser parser = new Parser();
String odUri = String odUri =
request.getRawODataPath() + (request.getRawQueryPath() == null ? "" : "?" + request.getRawQueryPath()); request.getRawODataPath() + (request.getRawQueryPath() == null ? "" : "?" + request.getRawQueryPath());
@ -146,6 +151,18 @@ public class ODataHandler {
} }
} }
private void validateODataVersion(ODataRequest request, ODataResponse response) {
List<String> maxVersionHeader = request.getHeader(HttpHeader.ODATA_MAX_VERSION);
if (maxVersionHeader != null && maxVersionHeader.size() > 0) {
if (ODataServiceVersion.isBiggerThan(ODataServiceVersion.V40.toString(), maxVersionHeader.get(0))) {
throw new ODataRuntimeException("400 Bad Request - ODataVersion not supported: " + maxVersionHeader.get(0));
}
}
response.setHeader(HttpHeader.ODATA_VERSION, ODataServiceVersion.V40.toString());
}
private <T extends Processor> T selectProcessor(Class<T> cls) { private <T extends Processor> T selectProcessor(Class<T> cls) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T p = (T) processors.get(cls); T p = (T) processors.get(cls);

View File

@ -23,9 +23,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -185,8 +183,6 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
} }
private void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) { private void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) { for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
String headerName = (String) headerNames.nextElement(); String headerName = (String) headerNames.nextElement();
List<String> headerValues = new ArrayList<String>(); List<String> headerValues = new ArrayList<String>();
@ -194,13 +190,8 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
String value = (String) headers.nextElement(); String value = (String) headers.nextElement();
headerValues.add(value); headerValues.add(value);
} }
if (requestHeaders.containsKey(headerName)) { odRequest.addHeader(headerName, headerValues);
requestHeaders.get(headerName).addAll(headerValues);
} else {
requestHeaders.put(headerName, headerValues);
}
} }
odRequest.setHeaders(requestHeaders);
} }
@Override @Override

View File

@ -23,8 +23,11 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import java.util.Arrays;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.http.HttpContentType; import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod; import org.apache.olingo.commons.api.http.HttpMethod;
@ -139,4 +142,43 @@ public class ODataHandlerTest {
assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\"")); assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\""));
} }
@Test
public void testMaxVersionNone() {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
}
@Test
public void testMaxVersionSupported() {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V40.toString()));
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
}
@Test(expected = Exception.class)
public void testMaxVersionNotSupported() {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V30.toString()));
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
}
} }