Repository: olingo-odata4 Updated Branches: refs/heads/OLINGO-832_StreamSerializerPoC 1a7c28a74 -> a6e0fb1a5
[OLINGO-832] New approach with ODataResponse change Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/2a80ca33 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/2a80ca33 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/2a80ca33 Branch: refs/heads/OLINGO-832_StreamSerializerPoC Commit: 2a80ca3391f51325d82b4c87ec21f55295aabe02 Parents: 1a7c28a Author: mibo <[email protected]> Authored: Sun Feb 7 19:27:55 2016 +0100 Committer: mibo <[email protected]> Committed: Sun Feb 7 19:27:55 2016 +0100 ---------------------------------------------------------------------- .../apache/olingo/server/api/ODataResponse.java | 34 ++++++++-- .../server/api/serializer/SerializerResult.java | 3 + .../server/core/ODataHttpHandlerImpl.java | 20 ++++-- .../serializer/ChannelSerializerResult.java | 9 +++ .../core/serializer/SerializerResultImpl.java | 7 +++ .../core/serializer/StreamSerializerResult.java | 7 +++ .../json/ODataJsonStreamSerializer.java | 1 - .../core/serializer/utils/ResultHelper.java | 65 ++++++++++++++++++++ .../processor/TechnicalEntityProcessor.java | 12 ++-- 9 files changed, 140 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java index a80d1cc..2063c65 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java @@ -18,12 +18,20 @@ */ package org.apache.olingo.server.api; +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channel; +import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; import java.util.List; import java.util.Map; +import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.serializer.SerializerResult; /** * Response object to carry OData-relevant HTTP information (status code, response headers, and content). @@ -133,15 +141,29 @@ public class ODataResponse { return content; } - public void setChannel(final ReadableByteChannel channel) { - this.channel = channel; +// public void setChannel(final ReadableByteChannel channel) { +// this.channel = channel; +// } +// +// public ReadableByteChannel getChannel() { +// return channel; +// } +// +// public boolean isChannelAvailable() { +// return channel != null; +// } + + private SerializerResult serializerResult; + + public void setResult(SerializerResult result) { + serializerResult = result; } - public ReadableByteChannel getChannel() { - return channel; + public boolean isResultAvailable() { + return serializerResult != null; } - public boolean isChannelAvailable() { - return channel != null; + public void write(WritableByteChannel output) { + serializerResult.writeContent(output); } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java index 0e3f97c..e380b97 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java @@ -20,6 +20,7 @@ package org.apache.olingo.server.api.serializer; import java.io.InputStream; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; /** * Result type for {@link ODataSerializer} methods @@ -33,5 +34,7 @@ public interface SerializerResult { ReadableByteChannel getChannel(); + void writeContent(WritableByteChannel channel); + boolean isNioSupported(); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java ---------------------------------------------------------------------- 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 fd480dd..d3275e4 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 @@ -149,22 +149,30 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { } } - if (odResponse.getContent() != null || odResponse.isChannelAvailable()) { + if(odResponse.isResultAvailable()) { + writeContent(odResponse, response); + } else if (odResponse.getContent() != null ) { copyContent(odResponse, response); } } + static void writeContent(final ODataResponse odataResponse, final HttpServletResponse servletResponse) { + try { + if(odataResponse.isResultAvailable()) { + odataResponse.write(Channels.newChannel(servletResponse.getOutputStream())); + } + } catch (IOException e) { + throw new ODataRuntimeException("Error on reading request content", e); + } + } + static void copyContent(final ODataResponse odataResponse, final HttpServletResponse servletResponse) { ReadableByteChannel input = null; WritableByteChannel output = null; try { ByteBuffer inBuffer = ByteBuffer.allocate(COPY_BUFFER_SIZE); output = Channels.newChannel(servletResponse.getOutputStream()); - if(odataResponse.isChannelAvailable()) { - input = odataResponse.getChannel(); - } else { - input = Channels.newChannel(odataResponse.getContent()); - } + input = Channels.newChannel(odataResponse.getContent()); while (input.read(inBuffer) > 0) { inBuffer.flip(); output.write(inBuffer); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java index d692986..a3b6b0c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java @@ -29,6 +29,7 @@ import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.core.serializer.json.ODataJsonStreamSerializer; import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer; +import org.apache.olingo.server.core.serializer.utils.ResultHelper; import java.io.IOException; import java.io.InputStream; @@ -36,6 +37,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; public class ChannelSerializerResult implements SerializerResult { @@ -157,6 +159,13 @@ public class ChannelSerializerResult implements SerializerResult { return true; } + @Override + public void writeContent(WritableByteChannel writeChannel) { + // TODO: mibo: replace with passing 'writeChannel' to json serializer + ResultHelper.copy(this.channel, writeChannel); + } + + private ChannelSerializerResult(ReadableByteChannel channel) { this.channel = channel; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java index d58315d..f314017 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java @@ -19,10 +19,12 @@ package org.apache.olingo.server.core.serializer; import org.apache.olingo.server.api.serializer.SerializerResult; +import org.apache.olingo.server.core.serializer.utils.ResultHelper; import java.io.InputStream; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; public class SerializerResultImpl implements SerializerResult { private InputStream content; @@ -38,6 +40,11 @@ public class SerializerResultImpl implements SerializerResult { } @Override + public void writeContent(WritableByteChannel channel) { + ResultHelper.copy(Channels.newChannel(content), channel); + } + + @Override public boolean isNioSupported() { return false; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java index 19b9f5d..c7cbce4 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java @@ -29,6 +29,7 @@ import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.core.serializer.json.ODataJsonStreamSerializer; import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer; +import org.apache.olingo.server.core.serializer.utils.ResultHelper; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -36,6 +37,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; public class StreamSerializerResult implements SerializerResult { private InputStream content; @@ -129,6 +131,11 @@ public class StreamSerializerResult implements SerializerResult { } @Override + public void writeContent(WritableByteChannel channel) { + ResultHelper.copy(getChannel(), channel); + } + + @Override public boolean isNioSupported() { return true; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java index 406fbe7..4cced29 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java @@ -24,7 +24,6 @@ import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.AbstractEntityCollection; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.EntityIterator; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.format.ContentType; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ResultHelper.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ResultHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ResultHelper.java new file mode 100644 index 0000000..fd57593 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ResultHelper.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.core.serializer.utils; + +import org.apache.olingo.commons.api.ex.ODataRuntimeException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channel; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +public class ResultHelper { + + public static final int COPY_BUFFER_SIZE = 8192; + + public static void copy(InputStream input, OutputStream output) { + copy(Channels.newChannel(input), Channels.newChannel(output)); + } + + public static void copy(ReadableByteChannel input, WritableByteChannel output) { + try { + ByteBuffer inBuffer = ByteBuffer.allocate(COPY_BUFFER_SIZE); + while (input.read(inBuffer) > 0) { + inBuffer.flip(); + output.write(inBuffer); + inBuffer.clear(); + } + } catch (IOException e) { + throw new ODataRuntimeException("Error on reading request content", e); + } finally { + closeStream(input); + closeStream(output); + } + } + + private static void closeStream(final Channel closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (IOException e) { + // ignore + } + } + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2a80ca33/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index dc7f0b7..baacebb 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -536,11 +536,13 @@ public class TechnicalEntityProcessor extends TechnicalProcessor serializeEntityStreamCollectionFixed(request, entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType, expand, select, countOption, id); - if(serializerResult.isNioSupported()) { - response.setChannel(serializerResult.getChannel()); - } else { - response.setContent(serializerResult.getContent()); - } +// if(serializerResult.isNioSupported()) { +// response.setChannel(serializerResult.getChannel()); +// } else { +// response.setContent(serializerResult.getContent()); +// } + response.setResult(serializerResult); + // response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); if (pageSize != null) {
