You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/07/10 15:18:02 UTC

[11/11] olingo-odata4 git commit: [OLINGO-708] Fixed missing response header and clean up

[OLINGO-708] Fixed missing response header and clean up


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/de7afda1
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/de7afda1
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/de7afda1

Branch: refs/heads/master
Commit: de7afda1ecf1a3e54f6f5fdb441d5f1d988a0449
Parents: 6b6902f
Author: mibo <mi...@apache.org>
Authored: Fri Jul 10 15:10:01 2015 +0200
Committer: mibo <mi...@apache.org>
Committed: Fri Jul 10 15:17:24 2015 +0200

----------------------------------------------------------------------
 .../fit/tecsvc/client/AsyncSupportITCase.java   |  2 +
 .../serializer/AsyncResponseSerializer.java     |  6 +-
 .../serializer/AsyncResponseSerializerTest.java |  7 +-
 .../server/tecsvc/async/AsyncProcessor.java     | 82 ++++++++++++--------
 .../tecsvc/async/TechnicalAsyncService.java     | 19 -----
 5 files changed, 62 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/de7afda1/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
index fd495c4..ad8fcbc 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
@@ -142,6 +142,8 @@ public final class AsyncSupportITCase extends AbstractBaseTestITCase {
     assertNotNull(first.getODataResponse());
     ODataResponse firstResponse = first.getODataResponse();
     assertEquals(200, firstResponse.getStatusCode());
+    assertEquals(2, firstResponse.getHeaderNames().size());
+    assertEquals("4.0", firstResponse.getHeader("OData-Version").iterator().next());
     ResWrap<EntityCollection> firWrap = getClient().getDeserializer(ContentType.APPLICATION_JSON)
         .toEntitySet(firstResponse.getRawResponse());
     EntityCollection firstResponseEntitySet = firWrap.getPayload();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/de7afda1/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializer.java
index 472f073..d5e8588 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializer.java
@@ -34,12 +34,12 @@ import java.nio.channels.WritableByteChannel;
 import java.util.Map;
 
 public class AsyncResponseSerializer {
-  private static final int BUFFER_SIZE = 4096;
+  private static final int BUFFER_SIZE = 8192;
   private static final String COLON = ":";
   private static final String SP = " ";
   private static final String CRLF = "\r\n";
-  public static final String HEADER_CHARSET_NAME = "ISO-8859-1";
-  public static final String HTTP_VERSION = "HTTP/1.1";
+  private static final String HEADER_CHARSET_NAME = "ISO-8859-1";
+  private static final String HTTP_VERSION = "HTTP/1.1";
 
   public InputStream serialize(final ODataResponse response) throws SerializerException {
     try {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/de7afda1/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializerTest.java
index aee42dd..f164b4b 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/AsyncResponseSerializerTest.java
@@ -27,6 +27,7 @@ import org.junit.Test;
 
 import java.io.InputStream;
 import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
 
 import static org.junit.Assert.assertEquals;
 
@@ -38,6 +39,7 @@ public class AsyncResponseSerializerTest {
     ODataResponse response = new ODataResponse();
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.APPLICATION_JSON.toContentTypeString());
+    response.setHeader(HttpHeader.CONTENT_LENGTH, String.valueOf(200));
 
     response.setContent(IOUtils.toInputStream("Walter Winter" + CRLF));
 
@@ -45,6 +47,7 @@ public class AsyncResponseSerializerTest {
     InputStream in = serializer.serialize(response);
     String result = IOUtils.toString(in);
     assertEquals("HTTP/1.1 200 OK" + CRLF +
+        "Content-Length: 200" + CRLF +
         "Content-Type: application/json" + CRLF + CRLF +
         "Walter Winter" + CRLF, result);
   }
@@ -54,6 +57,7 @@ public class AsyncResponseSerializerTest {
     ODataResponse response = new ODataResponse();
     response.setStatusCode(HttpStatusCode.ACCEPTED.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.APPLICATION_JSON.toContentTypeString());
+    response.setHeader(HttpHeader.CONTENT_LENGTH, String.valueOf(0));
 
     String testData = testData(20000);
     response.setContent(IOUtils.toInputStream(testData));
@@ -62,13 +66,14 @@ public class AsyncResponseSerializerTest {
     InputStream in = serializer.serialize(response);
     String result = IOUtils.toString(in);
     assertEquals("HTTP/1.1 202 Accepted" + CRLF +
+        "Content-Length: 0" + CRLF +
         "Content-Type: application/json" + CRLF + CRLF +
         testData, result);
   }
 
   private String testData(int amount) {
     StringBuilder result = new StringBuilder();
-    Random r = new Random();
+    ThreadLocalRandom r = ThreadLocalRandom.current();
     for (int i = 0; i < amount; i++) {
       result.append((char)(r.nextInt(26) + 'a'));
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/de7afda1/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/AsyncProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/AsyncProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/AsyncProcessor.java
index e6d662e..0e65657 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/AsyncProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/AsyncProcessor.java
@@ -18,8 +18,8 @@
  */
 package org.apache.olingo.server.tecsvc.async;
 
+import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.ODataApplicationException;
 import org.apache.olingo.server.api.ODataLibraryException;
 import org.apache.olingo.server.api.ODataRequest;
@@ -40,7 +40,6 @@ import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -63,6 +62,7 @@ public class AsyncProcessor<T extends Processor> {
     private final Object wrappedInstance;
     private Method invokeMethod;
     private Object[] invokeParameters;
+    private ODataRequest processRequest;
     private ODataResponse processResponse;
 
     public ProcessorInvocationHandler(Object wrappedInstance) {
@@ -74,22 +74,33 @@ public class AsyncProcessor<T extends Processor> {
       if (Processor.class.isAssignableFrom(method.getDeclaringClass())) {
         invokeMethod = method;
         invokeParameters = objects;
+      } else {
+        throw new ODataRuntimeException("Invalid class '" + method.getDeclaringClass() +
+            "' can not wrapped for asynchronous processing.");
       }
 
       return null;
     }
 
-    public Object process() throws InvocationTargetException, IllegalAccessException {
-      processResponse = new ODataResponse();
-      replaceInvokeParameter(processResponse);
-      return invokeMethod.invoke(wrappedInstance, invokeParameters);
+    /**
+     * Prepare the handler for the <code>process()</code> call (which is asynchronous and can be at any time in
+     * the future).
+     */
+    void prepareForAsync() {
+      processRequest = copyRequest(getParameter(ODataRequest.class));
+      processResponse = createODataResponse(getParameter(ODataResponse.class));
     }
 
-    public Object[] getInvokeParameters() {
-      return invokeParameters;
+    Object process() throws InvocationTargetException, IllegalAccessException {
+      if(processRequest == null || processResponse == null) {
+        throw new ODataRuntimeException("ProcessInvocationHandler was not correct prepared for async processsing.");
+      }
+      replaceInvokeParameter(processRequest);
+      replaceInvokeParameter(processResponse);
+      return invokeMethod.invoke(wrappedInstance, invokeParameters);
     }
 
-    public <P> void replaceInvokeParameter(P replacement) {
+    <P> void replaceInvokeParameter(P replacement) {
       if (replacement == null) {
         return;
       }
@@ -105,13 +116,28 @@ public class AsyncProcessor<T extends Processor> {
       invokeParameters = copy.toArray();
     }
 
-    public ODataResponse getProcessResponse() {
+    /**
+     * Get the ODataResponse which is used when this ProcessorInvocationHandler
+     * is called (via its <code>process()</code> method)
+     *
+     * @return ODataResponse which is used when this ProcessorInvocationHandler is called
+     */
+    ODataResponse getProcessResponse() {
       return processResponse;
     }
 
     Object getWrappedInstance() {
       return this.wrappedInstance;
     }
+
+    <P> P getParameter(Class<P> parameterClass) {
+      for (Object parameter : invokeParameters) {
+        if (parameter != null && parameterClass == parameter.getClass()) {
+          return parameterClass.cast(parameter);
+        }
+      }
+      return null;
+    }
   }
 
 
@@ -129,26 +155,17 @@ public class AsyncProcessor<T extends Processor> {
   }
 
   public ODataRequest getRequest() {
-    return getParameter(ODataRequest.class);
+    return handler.getParameter(ODataRequest.class);
   }
 
   public ODataResponse getResponse() {
-    return getParameter(ODataResponse.class);
+    return handler.getParameter(ODataResponse.class);
   }
 
   public ODataResponse getProcessResponse() {
     return handler.getProcessResponse();
   }
 
-  private <P> P getParameter(Class<P> parameterClass) {
-    for (Object parameter : handler.getInvokeParameters()) {
-      if (parameter != null && parameterClass == parameter.getClass()) {
-        return parameterClass.cast(parameter);
-      }
-    }
-    return null;
-  }
-
   public String getPreferHeader() {
     return preferHeader;
   }
@@ -170,12 +187,18 @@ public class AsyncProcessor<T extends Processor> {
    */
   public String processAsync() throws ODataApplicationException, ODataLibraryException {
     preferHeader = getRequest().getHeader(HttpHeader.PREFER);
-    ODataRequest request = copyRequest(getRequest());
-    handler.replaceInvokeParameter(request);
-    handler.replaceInvokeParameter(new ODataResponse());
+    handler.prepareForAsync();
     return service.processAsynchronous(this);
   }
 
+  private static ODataResponse createODataResponse(ODataResponse response) {
+    ODataResponse created = new ODataResponse();
+    for (Map.Entry<String, String> header : response.getHeaders().entrySet()) {
+      created.setHeader(header.getKey(), header.getValue());
+    }
+    return created;
+  }
+
   Object process() throws InvocationTargetException, IllegalAccessException {
     return handler.process();
   }
@@ -184,7 +207,7 @@ public class AsyncProcessor<T extends Processor> {
     this.location = loc;
   }
 
-  private ODataRequest copyRequest(ODataRequest request) throws ODataApplicationException {
+  static ODataRequest copyRequest(ODataRequest request) {
     ODataRequest req = new ODataRequest();
     req.setBody(copyRequestBody(request));
     req.setMethod(request.getMethod());
@@ -195,10 +218,8 @@ public class AsyncProcessor<T extends Processor> {
     req.setRawServiceResolutionUri(request.getRawServiceResolutionUri());
 
     for (Map.Entry<String, List<String>> header : request.getAllHeaders().entrySet()) {
-      if (HttpHeader.PREFER.toLowerCase().equals(
+      if (!HttpHeader.PREFER.toLowerCase().equals(
           header.getKey().toLowerCase())) {
-        preferHeader = header.getValue().get(0);
-      } else {
         req.addHeader(header.getKey(), header.getValue());
       }
     }
@@ -206,7 +227,7 @@ public class AsyncProcessor<T extends Processor> {
     return req;
   }
 
-  private InputStream copyRequestBody(ODataRequest request) throws ODataApplicationException {
+  static InputStream copyRequestBody(ODataRequest request) {
     ByteArrayOutputStream buffer = new ByteArrayOutputStream();
     InputStream input = request.getBody();
     if (input != null) {
@@ -221,8 +242,7 @@ public class AsyncProcessor<T extends Processor> {
         }
         return new ByteArrayInputStream(buffer.toByteArray());
       } catch (IOException e) {
-        throw new ODataApplicationException("Error on reading request content",
-            HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
+        throw new ODataRuntimeException("Error on reading request content");
       }
     }
     return null;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/de7afda1/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/TechnicalAsyncService.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/TechnicalAsyncService.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/TechnicalAsyncService.java
index 2d24cd1..f471929 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/TechnicalAsyncService.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/async/TechnicalAsyncService.java
@@ -196,25 +196,6 @@ public class TechnicalAsyncService {
     writeToResponse(response, odResponseStream);
   }
 
-//  static void copy(final InputStream input, final OutputStream output) {
-//    if(output == null || input == null) {
-//      return;
-//    }
-//
-//    try {
-//      byte[] buffer = new byte[1024];
-//      int n;
-//      while (-1 != (n = input.read(buffer))) {
-//        output.write(buffer, 0, n);
-//      }
-//    } catch (IOException e) {
-//      throw new ODataRuntimeException(e);
-//    } finally {
-//      closeStream(output);
-//      closeStream(input);
-//    }
-//  }
-
   static void copy(final InputStream input, final OutputStream output) {
     if (output == null || input == null) {
       return;