[OLINGO-328] refactoring, improvements & fit

This commit is contained in:
Stephan Klevenz 2014-07-01 17:26:20 +02:00
parent a51146a46f
commit 2bd0662645
12 changed files with 123 additions and 64 deletions

View File

@ -210,7 +210,7 @@
<artifactId>olingo-server-tecsvc</artifactId>
<type>war</type>
<properties>
<context>tecsvc</context>
<context>olingo-server-tecsvc</context>
</properties>
</deployable>
<deployable>

View File

@ -31,7 +31,7 @@ import org.junit.Test;
public class BasicITCase {
private static final String BASE_URI = "http://localhost:9080/tecsvc/odata.svc";
private static final String REF_SERVICE = TecSvcConst.BASE_URL;
private ODataClient odata;
@ -42,7 +42,9 @@ public class BasicITCase {
@Test
public void readServiceDocument() {
ODataServiceDocumentRequest request = odata.getRetrieveRequestFactory().getServiceDocumentRequest(BASE_URI + "/");
ODataServiceDocumentRequest request =
odata.getRetrieveRequestFactory().getServiceDocumentRequest(REF_SERVICE);
request.setAccept("application/json;odata.metadata=minimal");
assertNotNull(request);
ODataServiceDocument serviceDocument = request.execute().getBody();
assertNotNull(serviceDocument);
@ -50,7 +52,7 @@ public class BasicITCase {
@Test
public void readMetadata() {
EdmMetadataRequest request = odata.getRetrieveRequestFactory().getMetadataRequest(BASE_URI + "/$metadata");
EdmMetadataRequest request = odata.getRetrieveRequestFactory().getMetadataRequest(REF_SERVICE);
assertNotNull(request);
Edm edm = request.execute().getBody();
assertNotNull(edm);

View File

@ -23,19 +23,27 @@ import static org.junit.Assert.assertEquals;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PingITCase {
private static final String REF_SERVICE = "http://localhost:9080/tecsvc/odata.svc/";
private static final String REDIRECT_URL = "http://localhost:9080/tecsvc/odata.svc";
private static final Logger LOG = LoggerFactory.getLogger(PingITCase.class);
private static final String REF_SERVICE = TecSvcConst.BASE_URL + "/";
private static final String REDIRECT_URL = TecSvcConst.BASE_URL;
@Test
public void ping() throws Exception {
URL url = new URL(REF_SERVICE);
LOG.debug("ping request: " + REF_SERVICE);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
connection.connect();
int code = connection.getResponseCode();
@ -47,8 +55,11 @@ public class PingITCase {
URL url = new URL(REDIRECT_URL);
LOG.debug("redirect request: " + REDIRECT_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
connection.connect();
int code = connection.getResponseCode();

View File

@ -0,0 +1,25 @@
/*
* 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;
public class TecSvcConst {
public final static String BASE_URL = "http://localhost:9080/olingo-server-tecsvc/odata.svc";
}

View File

@ -341,7 +341,7 @@ public class ContentType {
}
return compatible.booleanValue();
}
/**
* Check equal without parameters.
* It is possible that no decision about <code>equal/none equal</code> can be determined a <code>NULL</code> is

View File

@ -19,9 +19,11 @@
package org.apache.olingo.commons.api.format;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
public class AcceptTypeTest {
@ -43,4 +45,16 @@ public class AcceptTypeTest {
assertEquals(1, atl.size());
assertEquals("a/a", atl.get(0).toString());
}
@Test
@Ignore("buggy and not yet fixed")
public void testWildcard() {
List<AcceptType> atl = AcceptType.create("*; q=.2");
assertNotNull(atl);
assertEquals(1, atl.size());
assertEquals("", atl.get(0).getType());
assertEquals("", atl.get(0).getSubtype());
assertEquals(".2", atl.get(0).getParameters().get("q"));
}
}

View File

@ -23,7 +23,6 @@ import java.util.List;
import org.apache.olingo.commons.api.format.AcceptType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
@ -39,7 +38,7 @@ public class ContentNegotiator {
private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiator.class);
private ContentNegotiator() {}
private static List<FormatContentTypeMapping>
getDefaultSupportedContentTypes(final Class<? extends Processor> processorClass) {
List<FormatContentTypeMapping> defaults = new ArrayList<FormatContentTypeMapping>();
@ -48,6 +47,8 @@ public class ContentNegotiator {
defaults.add(new FormatContentTypeMapping("xml", ContentType.APPLICATION_XML.toContentTypeString()));
} else {
defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()));
defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()
+ ";odata.metadata=minimal"));
}
return defaults;
@ -66,9 +67,9 @@ public class ContentNegotiator {
return supportedContentTypes;
}
public static String doContentNegotiation(final FormatOption formatOption, final ODataRequest request,
public static ContentType doContentNegotiation(final FormatOption formatOption, final ODataRequest request,
final Processor processor, final Class<? extends Processor> processorClass) {
String requestedContentType = null;
ContentType requestedContentType = null;
List<FormatContentTypeMapping> supportedContentTypes = getSupportedContentTypes(processor, processorClass);
@ -79,17 +80,17 @@ public class ContentNegotiator {
if (formatOption != null) {
if ("json".equalsIgnoreCase(formatOption.getText().trim())) {
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
requestedContentType = ContentType.APPLICATION_JSON;
for (FormatContentTypeMapping entry : supportedContentTypes) {
if (requestedContentType.equalsIgnoreCase(entry.getContentType().trim())) {
if (requestedContentType.isCompatible(ContentType.create(entry.getContentType().trim()))) {
supported = true;
break;
}
}
} else if ("xml".equalsIgnoreCase(formatOption.getText().trim())) {
requestedContentType = ContentType.APPLICATION_XML.toContentTypeString();
requestedContentType = ContentType.APPLICATION_XML;
for (FormatContentTypeMapping entry : supportedContentTypes) {
if (requestedContentType.equalsIgnoreCase(entry.getContentType().trim())) {
if (requestedContentType.isCompatible(ContentType.create(entry.getContentType().trim()))) {
supported = true;
break;
}
@ -97,7 +98,7 @@ public class ContentNegotiator {
} else {
for (FormatContentTypeMapping entry : supportedContentTypes) {
if (formatOption.getText().equalsIgnoreCase(entry.getFormatAlias().trim())) {
requestedContentType = entry.getContentType();
requestedContentType = ContentType.create(entry.getContentType().trim());
supported = true;
break;
}
@ -113,9 +114,9 @@ public class ContentNegotiator {
for (AcceptType acceptedType : acceptedContentTypes) {
for (FormatContentTypeMapping supportedType : supportedContentTypes) {
ContentType s = ContentType.create(supportedType.getContentType());
if (acceptedType.matches(s)) {
requestedContentType = s.toContentTypeString();
ContentType ct = ContentType.create(supportedType.getContentType());
if (acceptedType.matches(ct)) {
requestedContentType = ct;
supported = true;
break;
}
@ -132,13 +133,13 @@ public class ContentNegotiator {
} else {
if (processorClass == MetadataProcessor.class) {
requestedContentType = HttpContentType.APPLICATION_XML;
requestedContentType = ContentType.APPLICATION_XML;
} else {
requestedContentType = HttpContentType.APPLICATION_JSON;
requestedContentType = ContentType.APPLICATION_JSON;
}
for (FormatContentTypeMapping entry : supportedContentTypes) {
if (requestedContentType.equalsIgnoreCase(entry.getContentType().trim())) {
if (requestedContentType.isCompatible(ContentType.create(entry.getContentType().trim()))) {
supported = true;
break;
}

View File

@ -34,8 +34,16 @@ public class DefaultRedirectProcessor implements RedirectProcessor {
public void redirect(final ODataRequest request, final ODataResponse response) {
response.setStatusCode(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode());
String location = request.getRawRequestUri() + "/";
String location;
String rawUri = request.getRawRequestUri();
String rawQueryPath = request.getRawQueryPath();
if (rawQueryPath == null) {
location = request.getRawRequestUri() + "/";
} else {
location = rawUri.substring(0, rawUri.indexOf(rawQueryPath) - 1) + "/?" + rawQueryPath;
}
response.setHeader(HttpHeader.LOCATION, location);
}
}

View File

@ -25,6 +25,7 @@ import java.util.Map;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.OData;
@ -75,7 +76,7 @@ public class ODataHandler {
UriValidator validator = new UriValidator();
validator.validate(uriInfo, request.getMethod());
String requestedContentType = null;
ContentType requestedContentType = null;
switch (uriInfo.getKind()) {
case metadata:
MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
@ -83,7 +84,7 @@ public class ODataHandler {
requestedContentType =
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, mp, MetadataProcessor.class);
mp.readMetadata(request, response, uriInfo, requestedContentType);
mp.readMetadata(request, response, uriInfo, requestedContentType.toContentTypeString());
break;
case service:
if ("".equals(request.getRawODataPath())) {
@ -96,7 +97,7 @@ public class ODataHandler {
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, sdp,
ServiceDocumentProcessor.class);
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
sdp.readServiceDocument(request, response, uriInfo, requestedContentType.toContentTypeString());
}
break;
case resource:
@ -117,7 +118,7 @@ public class ODataHandler {
handleResourceDispatching(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo) {
int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
String requestedContentType = null;
ContentType requestedContentType = null;
switch (lastPathSegment.getKind()) {
case entitySet:
@ -128,7 +129,7 @@ public class ODataHandler {
requestedContentType =
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, cp, CollectionProcessor.class);
cp.readCollection(request, response, uriInfo, requestedContentType);
cp.readCollection(request, response, uriInfo, requestedContentType.toContentTypeString());
} else {
throw new ODataRuntimeException("not implemented");
}
@ -139,7 +140,7 @@ public class ODataHandler {
requestedContentType =
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, ep, EntityProcessor.class);
ep.readEntity(request, response, uriInfo, requestedContentType);
ep.readEntity(request, response, uriInfo, requestedContentType.toContentTypeString());
} else {
throw new ODataRuntimeException("not implemented");
}
@ -153,7 +154,7 @@ public class ODataHandler {
requestedContentType =
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, cp, CollectionProcessor.class);
cp.readCollection(request, response, uriInfo, requestedContentType);
cp.readCollection(request, response, uriInfo, requestedContentType.toContentTypeString());
} else {
throw new ODataRuntimeException("not implemented");
}
@ -164,7 +165,7 @@ public class ODataHandler {
requestedContentType =
ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, ep, EntityProcessor.class);
ep.readEntity(request, response, uriInfo, requestedContentType);
ep.readEntity(request, response, uriInfo, requestedContentType.toContentTypeString());
} else {
throw new ODataRuntimeException("not implemented");
}

View File

@ -531,7 +531,8 @@ public class MetadataDocumentXmlSerializer {
private void appendReference(final XMLStreamWriter writer) throws XMLStreamException {
writer.writeStartElement(NS_EDMX, "Reference");
// TODO: Where is this value comming from?
writer.writeAttribute("Uri", "http://localhost:9080/tecsvc/v4.0/cs02/vocabularies/Org.OData.Core.V1.xml");
writer.writeAttribute("Uri",
"http://localhost:9080/olingo-server-tecsvc/v4.0/cs02/vocabularies/Org.OData.Core.V1.xml");
writer.writeEmptyElement(NS_EDMX, "Include");
// TODO: Where is this value comming from?
writer.writeAttribute(XML_NAMESPACE, "Org.OData.Core.V1");

View File

@ -30,6 +30,7 @@ import java.util.Arrays;
import java.util.List;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.server.api.OData;
@ -49,6 +50,8 @@ import org.slf4j.LoggerFactory;
public class ContentNegotiatorTest {
static final private String ACCEPT_CASE_MIN = "application/json;odata.metadata=minimal";
static final private String ACCEPT_CASE_FULL = "application/json;odata.metadata=full";
static final private String ACCEPT_CASE_JSON = "application/json;q=0.2";
static final private String ACCEPT_CASE_XML = "application/xml";
static final private String ACCEPT_CASE_WILDCARD1 = "*/*";
@ -67,8 +70,10 @@ public class ContentNegotiatorTest {
{ "application/json", null, ACCEPT_CASE_WILDCARD1, null ,null },
{ "application/json", null, ACCEPT_CASE_WILDCARD2, null ,null },
{ "a/a", "a", null, "a, b" ,"a/a,b/b" },
{ " a/a ", " a ", null, " a , b" ," a/a , b/b " },
{ "a;x=y", "a", ACCEPT_CASE_WILDCARD1, "a" ,"a;x=y" },
{ "a/a", " a ", null, " a , b" ," a/a , b/b " },
{ "a/a;x=y", "a", ACCEPT_CASE_WILDCARD1, "a" ,"a/a;x=y" },
{ "application/json", "json", ACCEPT_CASE_MIN, null ,null },
{ ACCEPT_CASE_FULL, null, ACCEPT_CASE_FULL, "dummy" ,ACCEPT_CASE_FULL },
};
String[][] casesMetadata = {
@ -81,8 +86,8 @@ public class ContentNegotiatorTest {
{ "application/xml", null, ACCEPT_CASE_WILDCARD1, null ,null },
{ "application/xml", null, ACCEPT_CASE_WILDCARD2, null ,null },
{ "a/a", "a", null, "a, b" ,"a/a,b/b" },
{ " a/a ", " a ", null, " a , b" ," a/a , b/b " },
{ "a;x=y", "a", ACCEPT_CASE_WILDCARD1, "a" ,"a;x=y" },
{ "a/a", " a ", null, " a , b" ," a/a , b/b " },
{ "a/a;x=y", "a", ACCEPT_CASE_WILDCARD1, "a" ,"a/a;x=y" },
};
String[][] casesFail = {
@ -90,6 +95,7 @@ public class ContentNegotiatorTest {
{ "application/xml", "xxx", null, null ,null },
{ "a/a", "a", null, "b" ,"b/b" },
{ "application/xml", null, ACCEPT_CASE_JSON, null ,null },
{ "application/json", null, ACCEPT_CASE_FULL, null ,null }, // not jet supported
};
//CHECKSTYLE:ON
//@formatter:on
@ -98,7 +104,7 @@ public class ContentNegotiatorTest {
@Test
public void testServiceDocumentSingleCase() {
String[] useCase = { " a/a ", " a ", null, " a , b", " a/a , b/b " };
String[] useCase = { ACCEPT_CASE_FULL, null, ACCEPT_CASE_FULL, "dummy", ACCEPT_CASE_FULL };
testContentNegotiation(useCase, ServiceDocumentProcessor.class);
}
@ -156,10 +162,10 @@ public class ContentNegotiatorTest {
request.addHeader(HttpHeader.ACCEPT, Arrays.asList(useCase[2]));
}
String requestedContentType = ContentNegotiator.doContentNegotiation(fo, request, p, processorClass);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(fo, request, p, processorClass);
assertNotNull(requestedContentType);
assertEquals(useCase[0], requestedContentType);
assertEquals(useCase[0], requestedContentType.toContentTypeString());
}
private List<FormatContentTypeMapping> createCustomContentTypeMapping(final String formatString,

View File

@ -44,35 +44,25 @@ public class TechnicalServlet extends HttpServlet {
@Override
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException,
IOException {
LOG.debug("ReferenceServlet:service() called");
try {
if (dataProvider == null) {
dataProvider = new DataProvider();
}
if (dataProvider == null) {
dataProvider = new DataProvider();
}
dataProvider.reset();
dataProvider.reset();
OData odata = OData.newInstance();
Edm edm = odata.createEdm(new EdmTechProvider());
OData odata = OData.newInstance();
Edm edm = odata.createEdm(new EdmTechProvider());
ODataHttpHandler handler = odata.createHandler(edm);
ODataHttpHandler handler = odata.createHandler(edm);
// handler.register(new TechnicalProcessor(dataProvider));
handler.register(new SampleJsonProcessor());
handler.register(new SampleJsonProcessor());
handler.process(req, resp);
handler.process(req, resp);
} catch (Exception e) {
LOG.error("Server Error", e);
throw new ServletException(e);
}
}
public void bla(final HttpServletRequest hr, final HttpServletResponse hres) {
// ODataServer s = ODataServer.newInstance();
//
// ODataRequest r = s.createRequest(hr);
//
// Edm edm = server.createEdm(new EdmTechProvider());
//
// ODataResponse res = r.dispatch();
//
// s.sendResponse(res, hres);
}
}