diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/BatchTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/BatchTestITCase.java index db196c337..793f06f89 100644 --- a/fit/src/test/java/org/apache/olingo/fit/v4/BatchTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/v4/BatchTestITCase.java @@ -26,10 +26,8 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.math.BigDecimal; import java.net.URI; -import java.net.URISyntaxException; import java.util.Calendar; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java index 120d6b2f6..6c37ea81f 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java @@ -26,6 +26,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; import org.apache.olingo.commons.api.format.ContentType; +import org.apache.olingo.server.api.debug.DebugResponseHelper; import org.apache.olingo.server.api.deserializer.DeserializerException; import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer; import org.apache.olingo.server.api.deserializer.ODataDeserializer; @@ -143,4 +144,12 @@ public abstract class OData { * It can be used in Processor implementations. */ public abstract Preferences createPreferences(Collection preferHeaders); + + /** + * This method creates a DebugResponseHelper for the given debugFormat. If the format is not supported no + * exception is thrown. Instead we give back the implementation for the json format. + * @param debugFormat to be used. + * @return a debug response serializer + */ + public abstract DebugResponseHelper createDebugResponseHelper(String debugFormat); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java index 20ed77eec..d641581ad 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java @@ -21,6 +21,7 @@ package org.apache.olingo.server.api; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.olingo.server.api.debug.DebugSupport; import org.apache.olingo.server.api.etag.CustomETagSupport; import org.apache.olingo.server.api.processor.Processor; import org.apache.olingo.server.api.serializer.CustomContentTypeSupport; @@ -66,4 +67,10 @@ public interface ODataHttpHandler { */ void register(CustomETagSupport customConcurrencyControlSupport); + /** + * Register the debug support handler + * @param debugSupport + */ + void register(DebugSupport debugSupport); + } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java new file mode 100644 index 000000000..62a2d8a87 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java @@ -0,0 +1,38 @@ +/* + * 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.debug; + +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; + +/** + * This class supports applications in creating debug responses. + */ +public interface DebugResponseHelper { + + /** + * Creates a debug response based on the given parameters. Will never throw an exception. + * @param request + * @param applicationResponse + * @param exception + * @return the debug response or the raw application response in case an exception occurred. + */ + ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception); + +} diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java new file mode 100644 index 000000000..3ed39a515 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java @@ -0,0 +1,49 @@ +/* + * 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.debug; + +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; + +/** + * Register this interface to add debug support to your service. + */ +public interface DebugSupport { + + public static final String ODATA_DEBUG_QUERY_PARAMETER = "odata-debug"; + public static final String ODATA_DEBUG_JSON = "json"; + public static final String ODATA_DEBUG_HTML = "html"; + public static final String ODATA_DEBUG_DOWNLOAD = "download"; + + void init(OData odata); + + /** + * This method should create a debug response and deliver it back to the Olingo library. This method MUST NEVER throw + * an exception. + * @param debugFormat which is requested via the odata-debug query parameter + * @param request object which was send to the server + * @param response object which was filled by the application + * @param exception which has been thrown. Might be null in case there was no exception + * @return a new debug response which will be send to the client + */ + ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse response, + Exception exception); + +} diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java new file mode 100644 index 000000000..fb8851de7 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java @@ -0,0 +1,52 @@ +/* + * 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.debug; + +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; + +/** + * Supports the default debug case. Will always deliver a debug response if requested from the server. + */ +public class DefaultDebugSupport implements DebugSupport { + + private OData odata; + + @Override + public void init(OData odata) { + this.odata = odata; + } + + @Override + public ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse applicationResponse, + Exception exception) { + // Check if debugFormat is supported by the library + if (DebugSupport.ODATA_DEBUG_JSON.equalsIgnoreCase(debugFormat) + || DebugSupport.ODATA_DEBUG_HTML.equalsIgnoreCase(debugFormat) + || DebugSupport.ODATA_DEBUG_DOWNLOAD.equalsIgnoreCase(debugFormat)) { + return odata.createDebugResponseHelper(debugFormat).createDebugResponse(request, applicationResponse, exception); + } else { + // Debug format is not supported by the library by default so in order to avoid an exception we will just give + // back the original response from the application. + return applicationResponse; + } + } + +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java index 5563f1b64..566086a19 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.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 @@ -40,6 +40,7 @@ import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ODataLibraryException; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.debug.DebugSupport; import org.apache.olingo.server.api.etag.CustomETagSupport; import org.apache.olingo.server.api.processor.Processor; import org.apache.olingo.server.api.serializer.CustomContentTypeSupport; @@ -51,7 +52,8 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { private static final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImpl.class); - private ODataHandler handler; + private final ODataHandler handler; + private DebugSupport debugSupport; private int split = 0; public ODataHttpHandlerImpl(final OData odata, final ServiceMetadata serviceMetadata) { @@ -60,6 +62,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { @Override public void process(final HttpServletRequest request, final HttpServletResponse response) { + Exception exception = null; ODataRequest odRequest = null; ODataResponse odResponse; try { @@ -68,12 +71,27 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { odResponse = handler.process(odRequest); // ALL future methods after process must not throw exceptions! } catch (Exception e) { + exception = e; odResponse = handleException(odRequest, e); } + if (debugSupport != null) { + String debugFormat = getDebugQueryParameter(request); + if (debugFormat != null) { + // TODO: Should we be more careful here with response assignement in order to not loose the original response? + // TODO: How should we react to exceptions here? + odResponse = debugSupport.createDebugResponse(debugFormat, odRequest, odResponse, exception); + } + } + convertToHttp(response, odResponse); } + private String getDebugQueryParameter(HttpServletRequest request) { + // TODO Auto-generated method stub + return ""; + } + @Override public void setSplit(final int split) { this.split = split; @@ -132,7 +150,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { private ODataRequest fillODataRequest(final ODataRequest odRequest, final HttpServletRequest httpRequest, final int split) - throws ODataLibraryException { + throws ODataLibraryException { try { odRequest.setBody(httpRequest.getInputStream()); extractHeaders(odRequest, httpRequest); @@ -243,9 +261,14 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { public void register(final CustomContentTypeSupport customContentTypeSupport) { handler.register(customContentTypeSupport); } - + @Override public void register(final CustomETagSupport customConcurrencyControlSupport) { handler.register(customConcurrencyControlSupport); } + + @Override + public void register(final DebugSupport debugSupport) { + this.debugSupport = debugSupport; + } } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java index b4c414b70..dac1642cd 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java @@ -29,6 +29,7 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataHttpHandler; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.debug.DebugResponseHelper; import org.apache.olingo.server.api.deserializer.DeserializerException; import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer; import org.apache.olingo.server.api.deserializer.ODataDeserializer; @@ -40,6 +41,7 @@ import org.apache.olingo.server.api.serializer.FixedFormatSerializer; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.uri.UriHelper; +import org.apache.olingo.server.core.debug.DebugResponseHelperImpl; import org.apache.olingo.server.core.deserializer.FixedFormatDeserializerImpl; import org.apache.olingo.server.core.deserializer.json.ODataJsonDeserializer; import org.apache.olingo.server.core.etag.ETagHelperImpl; @@ -139,4 +141,11 @@ public class ODataImpl extends OData { return new PreferencesImpl(preferHeaders); } + @Override + public DebugResponseHelper createDebugResponseHelper(String debugFormat) { + //TODO: What should we do with invalid formats? + //TODO: Support more debug formats + return new DebugResponseHelperImpl(); + } + } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java new file mode 100644 index 000000000..ca4d7f388 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java @@ -0,0 +1,33 @@ +/* + * 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.debug; + +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; +import org.apache.olingo.server.api.debug.DebugResponseHelper; + +public class DebugResponseHelperImpl implements DebugResponseHelper { + + @Override + public ODataResponse + createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception) { + return applicationResponse; + } + +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index c1292de16..6bd87131c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -69,7 +69,6 @@ import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; public class ODataJsonSerializer implements ODataSerializer { diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java index 9c1d50286..8b74a88a3 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java @@ -33,6 +33,7 @@ import javax.servlet.http.HttpSession; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataHttpHandler; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.debug.DefaultDebugSupport; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.edmx.EdmxReferenceInclude; import org.apache.olingo.server.tecsvc.data.DataProvider; @@ -79,11 +80,15 @@ public class TechnicalServlet extends HttpServlet { } ODataHttpHandler handler = odata.createHandler(serviceMetadata); + // Register processors handler.register(new TechnicalEntityProcessor(dataProvider, serviceMetadata)); handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider, serviceMetadata)); handler.register(new TechnicalActionProcessor(dataProvider, serviceMetadata)); handler.register(new TechnicalBatchProcessor(dataProvider)); + // Register Helper handler.register(new ETagSupport()); + handler.register(new DefaultDebugSupport()); + // Process the request handler.process(request, response); } catch (final RuntimeException e) { LOG.error("Server Error", e);