[NO ISSUE][OTH] Add Remote Address to IServletRequest

- user model changes: no
- storage format changes: no
- interface changes: yes

Details:
- Add the remote address to IServletRequest.
- Set remote address in request reference.

Change-Id: Iab4a0b4d26e82a4d1b9ce134c0dab2f1ae94d0c6
Reviewed-on: https://asterix-gerrit.ics.uci.edu/3172
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/Receptionist.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/Receptionist.java
index 8d06143..c174c02 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/Receptionist.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/Receptionist.java
@@ -28,6 +28,7 @@
 import org.apache.http.HttpHeaders;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.util.NetworkUtil;
 
 public class Receptionist implements IReceptionist {
 
@@ -42,7 +43,7 @@
         final String uuid = UUID.randomUUID().toString();
         final RequestReference ref = RequestReference.of(uuid, node, System.currentTimeMillis());
         ref.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
-        //TODO set remote address
+        ref.setRemoteAddr(NetworkUtil.toHostPort(request.getRemoteAddress()));
         return ref;
     }
 
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java
index be201df..7dae0b5 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.hyracks.http.api;
 
+import java.net.InetSocketAddress;
 import java.util.Map;
 import java.util.Set;
 
@@ -73,4 +74,11 @@
         String value = getHeader(name);
         return value == null ? defaultValue : value;
     }
+
+    /**
+     * Gets the remote address of this request if its channel is connected. Otherwise null.
+     *
+     * @return the remote address
+     */
+    InetSocketAddress getRemoteAddress();
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java
index 0c633cf..d681d81 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java
@@ -19,6 +19,7 @@
 package org.apache.hyracks.http.server;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -28,21 +29,26 @@
 import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.server.utils.HttpUtil;
 
+import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.http.FullHttpRequest;
 import io.netty.handler.codec.http.QueryStringDecoder;
 
 public class BaseRequest implements IServletRequest {
     protected final FullHttpRequest request;
     protected final Map<String, List<String>> parameters;
+    protected final InetSocketAddress remoteAddress;
 
-    public static IServletRequest create(FullHttpRequest request) throws IOException {
+    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request) throws IOException {
         QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
         Map<String, List<String>> param = decoder.parameters();
-        return new BaseRequest(request, param);
+        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
+        return new BaseRequest(request, remoteAddress, param);
     }
 
-    protected BaseRequest(FullHttpRequest request, Map<String, List<String>> parameters) {
+    protected BaseRequest(FullHttpRequest request, InetSocketAddress remoteAddress,
+            Map<String, List<String>> parameters) {
         this.request = request;
+        this.remoteAddress = remoteAddress;
         this.parameters = parameters;
     }
 
@@ -75,4 +81,9 @@
     public String getHeader(CharSequence name) {
         return request.headers().get(name);
     }
+
+    @Override
+    public InetSocketAddress getRemoteAddress() {
+        return remoteAddress;
+    }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java
index 4609967..08271a6 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java
@@ -19,6 +19,7 @@
 package org.apache.hyracks.http.server;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,6 +31,7 @@
 import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.server.utils.HttpUtil;
 
+import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.http.FullHttpRequest;
 import io.netty.handler.codec.http.QueryStringDecoder;
 import io.netty.handler.codec.http.multipart.Attribute;
@@ -42,7 +44,7 @@
     private final List<String> names;
     private final List<String> values;
 
-    public static IServletRequest create(FullHttpRequest request) throws IOException {
+    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request) throws IOException {
         List<String> names = new ArrayList<>();
         List<String> values = new ArrayList<>();
         HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
@@ -58,12 +60,14 @@
         } finally {
             decoder.destroy();
         }
-        return new FormUrlEncodedRequest(request, new QueryStringDecoder(request.uri()).parameters(), names, values);
+        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
+        return new FormUrlEncodedRequest(request, remoteAddress, new QueryStringDecoder(request.uri()).parameters(),
+                names, values);
     }
 
-    protected FormUrlEncodedRequest(FullHttpRequest request, Map<String, List<String>> parameters, List<String> names,
-            List<String> values) {
-        super(request, parameters);
+    protected FormUrlEncodedRequest(FullHttpRequest request, InetSocketAddress remoteAddress,
+            Map<String, List<String>> parameters, List<String> names, List<String> values) {
+        super(request, remoteAddress, parameters);
         this.names = names;
         this.values = values;
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java
index e3a0d4b..80b33ad 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java
@@ -130,7 +130,7 @@
     private void submit(ChannelHandlerContext ctx, IServlet servlet, FullHttpRequest request) throws IOException {
         IServletRequest servletRequest;
         try {
-            servletRequest = HttpUtil.toServletRequest(request);
+            servletRequest = HttpUtil.toServletRequest(ctx, request);
         } catch (IllegalArgumentException e) {
             LOGGER.log(Level.WARN, "Failure Decoding Request", e);
             respond(ctx, request, HttpResponseStatus.BAD_REQUEST);
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java
index b0249fb..1fd8cd2 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java
@@ -30,6 +30,7 @@
 import org.apache.hyracks.http.server.BaseRequest;
 import org.apache.hyracks.http.server.FormUrlEncodedRequest;
 
+import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.http.DefaultHttpResponse;
 import io.netty.handler.codec.http.FullHttpRequest;
 import io.netty.handler.codec.http.HttpHeaderNames;
@@ -79,9 +80,10 @@
         }
     }
 
-    public static IServletRequest toServletRequest(FullHttpRequest request) throws IOException {
+    public static IServletRequest toServletRequest(ChannelHandlerContext ctx, FullHttpRequest request)
+            throws IOException {
         return ContentType.APPLICATION_X_WWW_FORM_URLENCODED.equals(getContentTypeOnly(request))
-                ? FormUrlEncodedRequest.create(request) : BaseRequest.create(request);
+                ? FormUrlEncodedRequest.create(ctx, request) : BaseRequest.create(ctx, request);
     }
 
     public static String getContentTypeOnly(IServletRequest request) {
diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/NetworkUtil.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/NetworkUtil.java
index d10be8e..763319f 100644
--- a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/NetworkUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/NetworkUtil.java
@@ -80,7 +80,7 @@
     }
 
     public static String toHostPort(InetSocketAddress address) {
-        return toHostPort(address.getHostString(), address.getPort());
+        return address != null ? toHostPort(address.getHostString(), address.getPort()) : null;
     }
 
     public static InetSocketAddress parseInetSocketAddress(String hostPortString) {