Implementation of GET for new APIs jmx-rest-api
authorhb
Mon, 25 Dec 2017 20:42:05 +0530
branchjmx-rest-api
changeset 55994 9721e36abeb0
parent 55987 0daf2ad15492
child 55995 a798bdd52997
Implementation of GET for new APIs Implemented paging and filtering for GET
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/GetRequestHandler.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpResponse.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/JmxRestAdapter.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestCollectionFilter.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestConfig.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingException.java
src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingFactory.java
src/java.management.rest/share/classes/javax/management/remote/rest/JmxRestAdapter.java
src/java.management.rest/share/classes/javax/management/remote/rest/JmxRestAdapterImpl.java
src/java.management.rest/share/classes/javax/management/remote/rest/PlatformRestAdapter.java
src/java.management/share/classes/javax/management/MBeanServerFactory.java
src/java.management/share/classes/javax/management/MBeanServerFactoryListener.java
src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java
test/javax/management/remote/rest/DefaultRestAdapter.java
test/javax/management/remote/rest/JsonParserTest.java
test/javax/management/remote/rest/PlatformAdapterTest.java
test/javax/management/remote/rest/PlatformMBeanTest.java
test/javax/management/remote/rest/RestAdapterSSLTest.java
test/javax/management/remote/rest/RunRestAdapter.java
test/javax/management/remote/rest/data/QueueSample.java
test/javax/management/remote/rest/data/QueueSampler.java
test/javax/management/remote/rest/data/QueueSamplerBean.java
test/javax/management/remote/rest/data/QueueSamplerBeanMBean.java
test/javax/management/remote/rest/data/QueueSamplerMXBean.java
test/javax/management/remote/rest/json/JSONTest.java
test/javax/management/remote/rest/management.properties
test/javax/management/remote/rest/management1.properties
test/javax/management/remote/rest/password.properties
test/javax/management/remote/rest/server.cer
test/javax/management/remote/rest/sslconfig
test/jdk/javax/management/remote/rest/DefaultRestAdapter.java
test/jdk/javax/management/remote/rest/JsonParserTest.java
test/jdk/javax/management/remote/rest/PlatformAdapterTest.java
test/jdk/javax/management/remote/rest/PlatformMBeanTest.java
test/jdk/javax/management/remote/rest/RestAdapterSSLTest.java
test/jdk/javax/management/remote/rest/RestAdapterTest.java
test/jdk/javax/management/remote/rest/RunRestAdapter.java
test/jdk/javax/management/remote/rest/data/QueueSample.java
test/jdk/javax/management/remote/rest/data/QueueSampler.java
test/jdk/javax/management/remote/rest/data/QueueSamplerBean.java
test/jdk/javax/management/remote/rest/data/QueueSamplerBeanMBean.java
test/jdk/javax/management/remote/rest/data/QueueSamplerMXBean.java
test/jdk/javax/management/remote/rest/json/JSONTest.java
test/jdk/javax/management/remote/rest/keystoreAgent
test/jdk/javax/management/remote/rest/keystoreClient
test/jdk/javax/management/remote/rest/management.properties
test/jdk/javax/management/remote/rest/management1.properties
test/jdk/javax/management/remote/rest/password.properties
test/jdk/javax/management/remote/rest/server.cer
test/jdk/javax/management/remote/rest/sslconfig
test/jdk/javax/management/remote/rest/truststoreAgent
test/jdk/javax/management/remote/rest/truststoreClient
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/GetRequestHandler.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/GetRequestHandler.java	Mon Dec 25 20:42:05 2017 +0530
@@ -5,17 +5,16 @@
  */
 package com.oracle.jmx.remote.rest.http;
 
-import javax.management.*;
 import com.oracle.jmx.remote.rest.json.JSONArray;
 import com.oracle.jmx.remote.rest.json.JSONObject;
 import com.oracle.jmx.remote.rest.json.JSONPrimitive;
 import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
 import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
+
+import javax.management.*;
 import java.net.HttpURLConnection;
 import java.util.*;
 
-import static javax.management.MBeanOperationInfo.*;
-
 /**
  * @author harsha
  */
@@ -23,6 +22,7 @@
 
     private final MBeanServer mbeanServer;
     private final List<String> allowedMBeans;
+
     public GetRequestHandler(MBeanServer mServer, List<String> allowedMBeans) {
         this.mbeanServer = mServer;
         this.allowedMBeans = allowedMBeans;
@@ -100,8 +100,7 @@
                             // We get MBeanInfo
                             ObjectName mbeanObj = ObjectName.getInstance(tokens[0]);
                             return HttpResponse.getJsonObject(HttpURLConnection.HTTP_OK,
-                                    new JSONPrimitive(resource + (query == null ? "" : query)),
-                                    getMBeanInfo(mbeanServer, mbeanObj));
+                                    new JSONPrimitive(5), new JSONPrimitive(5));
                         }
                         System.out.println("Unrecognized token : " + tokens[0]);
                 }
@@ -125,161 +124,20 @@
                 new JSONPrimitive("Nothing to see here.. move along"));
     }
 
-    private JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean) throws InstanceNotFoundException, IntrospectionException, ReflectionException {
-        JSONObject jobj = new JSONObject();
-        MBeanInfo mBeanInfo = mbeanServer.getMBeanInfo(mbean);
-        if (mBeanInfo == null) {
-            return jobj;
-        }
-        jobj.put("description", mBeanInfo.getDescription());
-
-        // Populate Attribute Info
-        MBeanAttributeInfo[] attributes = mBeanInfo.getAttributes();
-        JSONArray jarr = new JSONArray();
-        for (MBeanAttributeInfo attr : attributes) {
-            String access;
-            if (attr.isReadable()) {
-                if (attr.isWritable()) {
-                    access = "read/write";
-                } else {
-                    access = "read-only";
-                }
-            } else if (attr.isWritable()) {
-                access = "write-only";
-            } else {
-                access = "no-access";
-            }
-            JSONObject jobj1 = new JSONObject();
-            jobj1.put("description", attr.getDescription());
-            jobj1.put("name", attr.getName());
-            jobj1.put("type", attr.getType());
-            jobj1.put("access", access);
-            jobj1.put("descriptor", getDescriptorJSON(attr.getDescriptor()));
-            jarr.add(jobj1);
-        }
-        jobj.put("attributeInfo", jarr);
-
-        // Add constructor Info
-        MBeanConstructorInfo[] constructorInfo = mBeanInfo.getConstructors();
-        jarr = new JSONArray();
-        for (MBeanConstructorInfo constructor : constructorInfo) {
-            JSONObject jobj1 = new JSONObject();
-            jobj1.put("description", constructor.getDescription());
-            jobj1.put("name", constructor.getName());
-            JSONArray jarr1 = new JSONArray();
-            for (MBeanParameterInfo paramInfo : constructor.getSignature()) {
-                jarr1.add(getParamJSON(paramInfo));
-            }
-            jobj1.put("signature", jarr1);
-            if (constructor.getDescriptor().getFieldNames().length > 1) {
-                jobj1.put("descriptor", getDescriptorJSON(constructor.getDescriptor()));
-            }
-            jarr.add(jobj1);
-        }
-        jobj.put("constructorInfo", jarr);
-
-        MBeanOperationInfo[] opInfo = mBeanInfo.getOperations();
-        jarr = new JSONArray();
-
-        for (MBeanOperationInfo op : opInfo) {
-            String impactString;
-            switch (op.getImpact()) {
-                case ACTION:
-                    impactString = "action";
-                    break;
-                case ACTION_INFO:
-                    impactString = "action/info";
-                    break;
-                case INFO:
-                    impactString = "info";
-                    break;
-                case UNKNOWN:
-                    impactString = "unknown";
-                    break;
-                default:
-                    impactString = "(" + op.getImpact() + ")";
-            }
-
-            JSONObject jobj1 = new JSONObject();
-            jobj1.put("description", op.getDescription());
-            jobj1.put("name", op.getName());
-            jobj1.put("returnType", op.getReturnType());
-            JSONArray jarr1 = new JSONArray();
-            for (MBeanParameterInfo paramInfo : op.getSignature()) {
-                jarr1.add(getParamJSON(paramInfo));
-            }
-            jobj1.put("signature", jarr1);
-            jobj1.put("impact", impactString);
-            if (op.getDescriptor().getFieldNames().length > 1) {
-                jobj1.put("descriptor", getDescriptorJSON(op.getDescriptor()));
-            }
-            jarr.add(jobj1);
-        }
-        jobj.put("operationInfo", jarr);
-
-        MBeanNotificationInfo[] notifications = mBeanInfo.getNotifications();
-        jarr = new JSONArray();
-
-        for (MBeanNotificationInfo notification : notifications) {
-
-            JSONObject jobj1 = new JSONObject();
-            jobj1.put("description", notification.getDescription());
-            jobj1.put("name", notification.getName());
-
-            JSONArray jarr1 = new JSONArray();
-            for (String notifType : notification.getNotifTypes()) {
-                jarr1.add(new JSONPrimitive(notifType));
-            }
-            jobj1.put("notifTypes", jarr1);
-            if (notification.getDescriptor().getFieldNames().length > 1) {
-                jobj1.put("descriptor", getDescriptorJSON(notification.getDescriptor()));
-            }
-            jarr.add(jobj1);
-        }
-        jobj.put("notificationInfo", jarr);
-
-        jobj.put("descriptor", getDescriptorJSON(mBeanInfo.getDescriptor()));
-        return jobj;
-    }
-
-    private JSONObject getParamJSON(MBeanParameterInfo mParamInfo) {
-        JSONObject jobj1 = new JSONObject();
-        if (mParamInfo.getDescription() != null && !mParamInfo.getDescription().isEmpty()) {
-            jobj1.put("description", mParamInfo.getDescription());
-        }
-        jobj1.put("name", mParamInfo.getName());
-        jobj1.put("type", mParamInfo.getType());
-        if (mParamInfo.getDescriptor() != null && mParamInfo.getDescriptor().getFieldNames().length > 1) {
-            jobj1.put("descriptor", getDescriptorJSON(mParamInfo.getDescriptor()));
-        }
-        return jobj1;
-    }
-
-    private JSONObject getDescriptorJSON(Descriptor descriptor) {
-        JSONObject jobj2 = new JSONObject();
-        try {
-            String[] descNames = descriptor.getFieldNames();
-            for (String descName : descNames) {
-                Object fieldValue = descriptor.getFieldValue(descName);
-                jobj2.put(descName, fieldValue != null ? fieldValue.toString() : null);
-            }
-        } catch (Throwable t) {
-            t.printStackTrace();
-        }
-        return jobj2;
-    }
-
     private Map<String, Object> readAttributes(MBeanServer mbeanServer,
                                                ObjectName objName, String requestStr)
             throws InstanceNotFoundException, IntrospectionException,
             ReflectionException, MBeanException, AttributeNotFoundException {
         requestStr = requestStr.trim();
         Map<String, Object> result = new HashMap<>();
-        if (requestStr.trim().equalsIgnoreCase("all")) {
-            MBeanInfo mInfo = mbeanServer.getMBeanInfo(objName);
-            String[] attrs = Arrays.stream(mInfo.getAttributes())
-                    .map(MBeanAttributeInfo::getName)
-                    .toArray(String[]::new);
+
+        String[] attrs = Arrays.stream(requestStr.split(Tokens.COMMA))
+                .map(String::trim)
+                .toArray(String[]::new);
+
+        if (attrs.length == 1) {
+            result.put(attrs[0], mbeanServer.getAttribute(objName, attrs[0]));
+        } else {
             AttributeList attrVals = mbeanServer.getAttributes(objName, attrs);
             if (attrVals.size() != attrs.length) {
                 List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
@@ -288,16 +146,6 @@
                     result.put(a.getName(), a.getValue());
                 }
                 for (String attr : missingAttrs) {
-                    try {
-                        Object attribute = mbeanServer.getAttribute(objName, attr);
-                    } catch (RuntimeException ex) {
-                        if (ex.getCause() instanceof UnsupportedOperationException) {
-                            result.put(attr, "< Attribute not supported >");
-                        } else if (ex.getCause() instanceof IllegalArgumentException) {
-                            result.put(attr, "< Invalid attributes >");
-                        }
-                        continue;
-                    }
                     result.put(attr, "< Error: No such attribute >");
                 }
             } else {
@@ -305,31 +153,8 @@
                     result.put(a.getName(), a.getValue());
                 });
             }
-        } else {
-            String[] attrs = Arrays.stream(requestStr.split(Tokens.COMMA))
-                    .map(String::trim)
-                    .toArray(String[]::new);
+        }
 
-            if (attrs.length == 1) {
-                result.put(attrs[0], mbeanServer.getAttribute(objName, attrs[0]));
-            } else {
-                AttributeList attrVals = mbeanServer.getAttributes(objName, attrs);
-                if (attrVals.size() != attrs.length) {
-                    List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
-                    for (Attribute a : attrVals.asList()) {
-                        missingAttrs.remove(a.getName());
-                        result.put(a.getName(), a.getValue());
-                    }
-                    for (String attr : missingAttrs) {
-                        result.put(attr, "< Error: No such attribute >");
-                    }
-                } else {
-                    attrVals.asList().forEach((a) -> {
-                        result.put(a.getName(), a.getValue());
-                    });
-                }
-            }
-        }
         return result;
     }
 
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpResponse.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpResponse.java	Mon Dec 25 20:42:05 2017 +0530
@@ -22,7 +22,50 @@
  */
 public class HttpResponse {
 
-    public static int getHttpErrorCode(Exception ex) {
+    public static final HttpResponse OK = new HttpResponse(HttpURLConnection.HTTP_OK, "Success");
+    public static final HttpResponse SERVER_ERROR = new HttpResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, "Internal server error");
+    public static final HttpResponse METHOD_NOT_ALLOWED = new HttpResponse(HttpURLConnection.HTTP_BAD_METHOD, "Method not allowed");
+    public static final HttpResponse BAD_REQUEST = new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Bad request");
+    public static final HttpResponse REQUEST_NOT_FOUND = new HttpResponse(HttpURLConnection.HTTP_NOT_FOUND, "Request not found");
+
+    private final int code;
+    private final String message;
+    private final String detail;
+
+    public HttpResponse(int code, String message) {
+        this(code, message, "");
+    }
+
+    public HttpResponse(int code, String message, String detail) {
+        this.code = code;
+        this.message = message;
+        this.detail = detail;
+    }
+
+    public HttpResponse(HttpResponse response, String detail) {
+        this.code = response.code;
+        this.message = response.message;
+        this.detail = detail;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getResponse() {
+        if(code != HttpURLConnection.HTTP_OK) {
+            JSONObject jobj = new JSONObject();
+            jobj.put("status",new JSONPrimitive(code));
+            jobj.put("message",new JSONPrimitive(message));
+            if(detail != null && !detail.isEmpty()) {
+                jobj.put("details", new JSONPrimitive(detail));
+            }
+            return jobj.toJsonString();
+        }
+        return message;
+    }
+
+    static int getHttpErrorCode(Exception ex) {
         if (ex instanceof JSONDataException
                 || ex instanceof ParseException || ex instanceof IllegalArgumentException) {
             return HttpURLConnection.HTTP_BAD_REQUEST;
@@ -43,7 +86,7 @@
         return sw.toString();
     }
 
-    public static JSONObject getJsonObject(int code, JSONElement request, JSONElement response) {
+    static JSONObject getJsonObject(int code, JSONElement request, JSONElement response) {
         JSONObject jobj = new JSONObject();
         jobj.put("status", new JSONPrimitive(code));
         jobj.put("request", request);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,206 @@
+package com.oracle.jmx.remote.rest.http;
+
+import com.oracle.jmx.remote.rest.json.JSONObject;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+
+import javax.management.remote.rest.PlatformRestAdapter;
+import java.io.*;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class HttpUtil {
+
+    public static String getRequestCharset(HttpExchange ex) {
+        String charset = null;
+        List<String> contentType = ex.getRequestHeaders().get("Content-type");
+        if (contentType != null) {
+            for (String kv : contentType) {
+                for (String value : kv.split(";")) {
+                    value = value.trim();
+                    if (value.toLowerCase().startsWith("charset=")) {
+                        charset = value.substring("charset=".length());
+                    }
+                }
+            }
+        }
+        return charset;
+    }
+
+    public static String getAcceptCharset(HttpExchange ex) {
+        List<String> acceptCharset = ex.getRequestHeaders().get("Accept-Charset");
+        if (acceptCharset != null && acceptCharset.size() > 0) {
+            return acceptCharset.get(0);
+        }
+        return null;
+    }
+
+    public static String getGetRequestResource(HttpExchange ex) throws UnsupportedEncodingException {
+        String charset = getRequestCharset(ex);
+        String httpHandlerPath = ex.getHttpContext().getPath();
+        String requestURIpath = ex.getRequestURI().getPath();
+        String getRequestPath = requestURIpath.substring(httpHandlerPath.length());
+        if (charset != null) {
+            return URLDecoder.decode(getRequestPath, charset);
+        } else {
+            return getRequestPath;
+        }
+    }
+
+    public static String getGetRequestQuery(HttpExchange ex) throws UnsupportedEncodingException {
+        String charset = getRequestCharset(ex);
+        String query = ex.getRequestURI().getQuery();
+        if (charset != null && query != null) {
+            return URLDecoder.decode(query, charset);
+        } else {
+            return query;
+        }
+    }
+
+    public static Map<String, String> getGetRequestQueryMap(HttpExchange ex)
+            throws UnsupportedEncodingException {
+        String charset = getRequestCharset(ex);
+        String query = ex.getRequestURI().getQuery();
+        if (charset != null && query != null) {
+            query = URLDecoder.decode(query, charset);
+        }
+        Map<String, String> queryParams = new LinkedHashMap<>();
+
+        if (query == null || query.isEmpty()) {
+            return queryParams;
+        }
+        String[] params = query.trim().split("&");
+        for (String param : params) {
+            int idx = param.indexOf('=');
+            queryParams.put(param.substring(0, idx), param.substring(idx + 1));
+        }
+        return queryParams;
+    }
+
+    public static String getCredentials(HttpExchange exchange) {
+        Headers rmap = exchange.getRequestHeaders();
+        String auth = rmap.getFirst("Authorization");
+        if (auth != null && !auth.isEmpty()) {
+            int sp = auth.indexOf(' ');
+            byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1));
+            String authCredentials = new String(b);
+            return authCredentials;
+        }
+        return "";
+    }
+
+    public static String readRequestBody(HttpExchange he) throws IOException {
+        String charset = getRequestCharset(he);
+        StringBuilder stringBuilder = new StringBuilder();
+        InputStreamReader in = charset != null ? new InputStreamReader(he.getRequestBody(), charset) : new InputStreamReader(he.getRequestBody());
+        BufferedReader br = new BufferedReader(in);
+        String line;
+        while ((line = br.readLine()) != null) {
+            String decode = charset != null ? URLDecoder.decode(line, charset) : line;
+            stringBuilder.append(decode);
+        }
+        return stringBuilder.toString();
+    }
+
+    public static void sendResponse(HttpExchange exchange, HttpResponse response) throws IOException {
+        String charset = getRequestCharset(exchange);
+        String acceptCharset = HttpUtil.getAcceptCharset(exchange);
+        if (acceptCharset != null) {
+            charset = acceptCharset;
+        }
+
+        // Set response headers explicitly
+        String msg = charset == null ? response.getResponse() : URLEncoder.encode(response.getResponse(), charset);
+        byte[] bytes = msg.getBytes();
+        Headers resHeaders = exchange.getResponseHeaders();
+        resHeaders.add("Content-Type", "application/json; charset=" + charset);
+
+        exchange.sendResponseHeaders(response.getCode(), bytes.length);
+        try (OutputStream os = exchange.getResponseBody()) {
+            os.write(bytes);
+        }
+    }
+
+    public static <T> List<T> filterByPage(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
+        if (input.size() <= pageSize) {
+            return input;
+        }
+        Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
+        int currPage = 1;
+        if (queryParams != null && !queryParams.isEmpty()) {
+            String pageStr = queryParams.get("page");
+            if (pageStr != null && !pageStr.isEmpty()) {
+                currPage = Integer.parseInt(pageStr);
+                currPage = currPage > 1 ? currPage : 1;
+            }
+        }
+        int start = (currPage - 1) * pageSize;
+        int end = Math.min(input.size(), start + pageSize);
+        if (start < end) {
+            return input.subList(start, end);
+        } else {
+            return null;
+        }
+    }
+
+    public static <T> JSONObject getPaginationLinks(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
+
+        if (pageSize >= input.size()) {
+            return null;
+        }
+
+        Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
+        int currPage = 1;
+        if (queryParams != null && !queryParams.isEmpty()) {
+            String pageStr = queryParams.get("page");
+            if (pageStr != null && !pageStr.isEmpty()) {
+                currPage = Integer.parseInt(pageStr);
+            }
+        }
+        String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath() + "?";
+        Map<String, String> queryMap = getGetRequestQueryMap(exchange);
+        if (queryMap != null) {
+            queryMap.remove("page");
+            if (!queryMap.isEmpty()) {
+                String query = queryMap.keySet().stream()
+                        .map(k -> k + "=" + queryMap.get(k))
+                        .collect(Collectors.joining("&"));
+                path = path + query + "&";
+            }
+        }
+        int totalPages = (input.size() % pageSize == 0) ? input.size() / pageSize : input.size() / pageSize + 1;
+
+        JSONObject jobj = new JSONObject();
+        jobj.put("first", path.replaceAll(".$", ""));
+        if (currPage == 2) {
+            jobj.put("prev", path.replaceAll(".$", ""));
+        } else if (currPage > 2) {
+            jobj.put("prev", path + "page=" + (currPage - 1));
+        }
+        if (currPage < totalPages) {
+            jobj.put("next", path + "page=" + (currPage + 1));
+        }
+        jobj.put("last", path + "page=" + totalPages);
+
+        return jobj;
+    }
+
+    public static String escapeUrl(String input) {
+        try {
+            URL url = new URL(input);
+            URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
+            return uri.toURL().toString();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return null;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/JmxRestAdapter.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,264 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.oracle.jmx.remote.rest.http;
+
+import com.oracle.jmx.remote.rest.json.JSONElement;
+import com.oracle.jmx.remote.rest.mapper.JSONMapper;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
+import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
+import com.sun.jmx.remote.security.SubjectDelegator;
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerDelegateMBean;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.rest.PlatformRestAdapter;
+import javax.security.auth.Subject;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.HttpURLConnection;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author harsha
+ */
+public final class JmxRestAdapter implements RestResource {
+
+    public static final String AUTHENTICATOR
+            = "jmx.remote.authenticator";
+    public static final String LOGIN_CONFIG_PROP
+            = "jmx.remote.x.login.config";
+    public static final String PASSWORD_FILE_PROP
+            = "jmx.remote.x.password.file";
+
+    private final HttpServer httpServer;
+    private final String contextStr;
+    private final Map<String, ?> env;
+    private final MBeanServer mbeanServer;
+
+    private HttpContext httpContext;
+
+    private JMXAuthenticator authenticator = null;
+
+    private final MBeanServerDelegateMBean mBeanServerDelegateMBean;
+    private final Map<String, MBeanServer> authenticatedMBeanServer = new ConcurrentHashMap<>();
+    private final MBeanCollectionResource mbeansResource;
+    private final Map<String, MBeanCollectionResource> authenticatedMBeanCollRes = new ConcurrentHashMap<>();
+    private static int count = 0;
+    private final String alias;
+
+    public JmxRestAdapter(HttpServer hServer, String context, Map<String, ?> env, MBeanServer mbeanServer) {
+        httpServer = hServer;
+        this.env = env;
+        this.mbeanServer = mbeanServer;
+        mBeanServerDelegateMBean = JMX.newMBeanProxy(mbeanServer, MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
+
+        if (context == null || context.isEmpty()) {
+            alias = "server-" + count++;
+            contextStr = alias;
+        } else {
+            contextStr = context;
+            alias = context;
+        }
+
+        if (env.get("jmx.remote.x.authentication") != null) {
+            authenticator = (JMXAuthenticator) env.get(JmxRestAdapter.AUTHENTICATOR);
+            if (authenticator == null) {
+                if (env.get("jmx.remote.x.password.file") != null
+                        || env.get("jmx.remote.x.login.config") != null) {
+                    authenticator = new JMXPluggableAuthenticator(env);
+                } else {
+                    // Throw exception for invalid authentication config
+                }
+            }
+        }
+        mbeansResource = new MBeanCollectionResource(mbeanServer);
+        httpContext = httpServer.createContext("/jmx/servers/" + contextStr, this);
+        if (env.get("jmx.remote.x.authentication") != null) {
+            httpContext.setAuthenticator(new RestAuthenticator("jmx"));
+        }
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    private MBeanServer getMBeanServerProxy(MBeanServer mbeaServer, Subject subject) {
+        return (MBeanServer) Proxy.newProxyInstance(MBeanServer.class.getClassLoader(),
+                new Class<?>[]{MBeanServer.class},
+                new AuthInvocationHandler(mbeaServer, subject));
+    }
+
+    @Override
+    public HttpResponse doGet(HttpExchange exchange) {
+        String selfUrl = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", "");
+        Map<String, String> links = new LinkedHashMap<>();
+        links.put("mbeans", selfUrl + "/mbeans");
+
+        Map<String, Object> mBeanServerInfo = getMBeanServerInfo();
+        mBeanServerInfo.put("_links",links);
+
+        final JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(mBeanServerInfo);
+        if (typeMapper != null) {
+            try {
+                JSONElement jsonElement = typeMapper.toJsonValue(mBeanServerInfo);
+                return new HttpResponse(HttpURLConnection.HTTP_OK, jsonElement.toJsonString());
+            } catch (JSONMappingException e) {
+                return new HttpResponse(500, "Internal error");
+            }
+        }
+        return new HttpResponse(500, "Internal error");
+    }
+
+    @Override
+    public HttpResponse doPut(HttpExchange exchange) {
+        return HttpResponse.METHOD_NOT_ALLOWED;
+    }
+
+    @Override
+    public HttpResponse doPost(HttpExchange exchange) {
+        return HttpResponse.METHOD_NOT_ALLOWED;
+    }
+
+    @Override
+    public HttpResponse doDelete(HttpExchange exchange) {
+        return HttpResponse.METHOD_NOT_ALLOWED;
+    }
+
+    @Override
+    public HttpResponse doHead(HttpExchange exchange) {
+        return HttpResponse.METHOD_NOT_ALLOWED;
+    }
+
+    public String getUrl() {
+        String baseUrl = PlatformRestAdapter.getBaseURL();
+        String path = httpContext.getPath();
+        return baseUrl + path;
+    }
+
+    @Override
+    public void handle(HttpExchange exchange) throws IOException {
+        MBeanCollectionResource mbeansRes = mbeansResource;
+        if (env.get("jmx.remote.x.authentication") != null) {
+            String authCredentials = HttpUtil.getCredentials(exchange);
+            mbeansRes = authenticatedMBeanCollRes.get(authCredentials);
+            if (mbeansRes == null) {
+                throw new IllegalArgumentException("Invalid HTTP request Headers");
+            }
+        }
+
+        String path = exchange.getRequestURI().getPath();
+        // Route request to appropriate resource
+        if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\\\-\\\\.]+\\/?$")) {
+            RestResource.super.handle(exchange);
+        } else if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans.*")) {
+            mbeansRes.handle(exchange);
+//        } else if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/[^\\/]+\\/?$")) {
+//            mbeansRes.handle(exchange);
+        } else {
+            HttpUtil.sendResponse(exchange, new HttpResponse(404, "Not found"));
+        }
+    }
+
+    private class RestAuthenticator extends BasicAuthenticator {
+
+        RestAuthenticator(String realm) {
+            super(realm);
+        }
+
+        @Override
+        public boolean checkCredentials(String username, String password) {
+            String credentials = username + ":" + password;
+            if (authenticatedMBeanServer.containsKey(credentials)) {
+                return true;
+            } else {
+                Subject subject = null;
+                if (authenticator != null) {
+                    String[] credential = new String[]{username, password};
+                    try {
+                        subject = authenticator.authenticate(credential);
+                    } catch (SecurityException e) {
+                        return false;
+                    }
+                }
+                MBeanServer proxy = getMBeanServerProxy(mbeanServer, subject);
+                authenticatedMBeanServer.put(credentials, proxy);
+                authenticatedMBeanCollRes.put(credentials, new MBeanCollectionResource(proxy));
+                return true;
+            }
+        }
+    }
+
+    Map<String, Object> getMBeanServerInfo() {
+        Map<String, Object> result = new LinkedHashMap<>();
+
+        result.put("id", mBeanServerDelegateMBean.getMBeanServerId());
+        result.put("alias", getAlias());
+
+        result.put("defaultDomain", mbeanServer.getDefaultDomain());
+        result.put("mBeanCount", mbeanServer.getMBeanCount());
+        result.put("domains", Arrays.toString(mbeanServer.getDomains()));
+
+        result.put("specName", mBeanServerDelegateMBean.getSpecificationName());
+        result.put("specVersion", mBeanServerDelegateMBean.getSpecificationVersion());
+        result.put("specVendor", mBeanServerDelegateMBean.getSpecificationVendor());
+
+        result.put("implName", mBeanServerDelegateMBean.getImplementationName());
+        result.put("implVersion", mBeanServerDelegateMBean.getImplementationVersion());
+        result.put("implVendor", mBeanServerDelegateMBean.getImplementationVendor());
+
+        return result;
+    }
+
+    private class AuthInvocationHandler implements InvocationHandler {
+
+        private final MBeanServer mbeanServer;
+        private final AccessControlContext acc;
+
+        AuthInvocationHandler(MBeanServer server, Subject subject) {
+            this.mbeanServer = server;
+            if (subject == null) {
+                this.acc = null;
+            } else {
+                if (SubjectDelegator.checkRemoveCallerContext(subject)) {
+                    acc = JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
+                } else {
+                    acc = JMXSubjectDomainCombiner.getContext(subject);
+                }
+            }
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            if (acc == null) {
+                return method.invoke(mbeanServer, args);
+            } else {
+                PrivilegedAction<Object> op = () -> {
+                    try {
+                        return method.invoke(mbeanServer, args);
+                    } catch (Exception ex) {
+                    }
+                    return null;
+                };
+                return AccessController.doPrivileged(op, acc);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,191 @@
+package com.oracle.jmx.remote.rest.http;
+
+import com.oracle.jmx.remote.rest.json.JSONElement;
+import com.oracle.jmx.remote.rest.json.JSONObject;
+import com.oracle.jmx.remote.rest.mapper.JSONMapper;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
+import com.sun.net.httpserver.HttpExchange;
+
+import javax.management.*;
+import javax.management.remote.rest.PlatformRestAdapter;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MBeanCollectionResource implements RestResource, NotificationListener {
+
+    private List<ObjectName> allowedMbeans;
+    private final MBeanServer mBeanServer;
+    private final Map<String, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>();
+    private static final int pageSize = 10;
+
+    private boolean isMBeanAllowed(ObjectName objName) {
+        try {
+            MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName);
+            MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes();
+            for (MBeanAttributeInfo attrInfo : attrsInfo) {
+                String type = attrInfo.getType();
+                if (!JSONMappingFactory.INSTANCE.isTypeMapped(type)) {
+                    return false;
+                }
+            }
+            MBeanOperationInfo[] operations = mInfo.getOperations();
+            for (MBeanOperationInfo opInfo : operations) {
+                MBeanParameterInfo[] signature = opInfo.getSignature();
+                for (MBeanParameterInfo sig : signature) {
+                    if (!JSONMappingFactory.INSTANCE.isTypeMapped(sig.getType())) {
+                        return false;
+                    }
+                }
+                if (!JSONMappingFactory.INSTANCE.isTypeMapped(opInfo.getReturnType())) {
+                    return false;
+                }
+            }
+            return true;
+        } catch (InstanceNotFoundException | IntrospectionException | ReflectionException | ClassNotFoundException ex) {
+            ex.printStackTrace();
+            return false;
+        }
+    }
+
+    private void introspectMBeanTypes(MBeanServer server) {
+        if (allowedMbeans.isEmpty()) {
+            Set<ObjectInstance> allMBeans = server.queryMBeans(null, null); // get all Mbeans
+            allMBeans.stream().filter((objIns) -> (isMBeanAllowed(objIns.getObjectName())))
+                    .forEachOrdered(objIns -> allowedMbeans.add(objIns.getObjectName()));
+        }
+    }
+
+    @Override
+    public void handleNotification(Notification notification, Object handback) {
+        try {
+            MBeanServerNotification mbs = (MBeanServerNotification) notification;
+            if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+                ObjectName mBeanName = mbs.getMBeanName();
+                if (isMBeanAllowed(mBeanName)) {
+                    allowedMbeans.add(mBeanName);
+                }
+            } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+                if (allowedMbeans.contains(mbs.getMBeanName().toString())) {
+                    allowedMbeans.remove(mbs.getMBeanName().toString());
+                }
+            }
+        } catch (Exception e) {
+        }
+    }
+
+    public MBeanCollectionResource(MBeanServer mBeanServer) {
+        this.mBeanServer = mBeanServer;
+        allowedMbeans = new ArrayList<>();
+        introspectMBeanTypes(mBeanServer);
+        allowedMbeans = new CopyOnWriteArrayList<>(allowedMbeans);
+        allowedMbeans.forEach(objectName -> mBeanResourceMap.put(objectName.toString(),
+                new MBeanResource(mBeanServer, objectName)));
+    }
+
+    @Override
+    public void handle(HttpExchange exchange) throws IOException {
+        String path = exchange.getRequestURI().getPath();
+        if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/?$")) {
+            RestResource.super.handle(exchange);
+        } else if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/[^\\/]+\\/?.*")) {
+            // Extract mbean name
+            // Forward the request to its corresponding rest resource
+            Pattern mbeans = Pattern.compile("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/");
+            Matcher matcher = mbeans.matcher(path);
+
+            if (matcher.find()) {
+                String ss = path.substring(matcher.end());
+                String mBeanName = ss;
+                if (ss.indexOf('/') != -1) {
+                    mBeanName = ss.substring(0, ss.indexOf('/'));
+                }
+                MBeanResource mBeanResource = mBeanResourceMap.get(mBeanName);
+                if (mBeanResource == null) {
+                    HttpUtil.sendResponse(exchange, new HttpResponse(404, "Not found"));
+                    return;
+                }
+                mBeanResource.handle(exchange);
+            }
+        }
+    }
+
+    @Override
+    public HttpResponse doGet(HttpExchange exchange) {
+        // add links
+
+        final String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", "");
+        try {
+            List<ObjectName> mbeans = allowedMbeans;
+            Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange);
+            if(queryMap.containsKey("query")) {
+                Set<ObjectName> queryMBeans = mBeanServer.queryNames(new ObjectName(queryMap.get("query")),null);
+                queryMBeans.retainAll(allowedMbeans);
+                mbeans = new ArrayList<>(queryMBeans);
+            }
+
+            JSONObject _links = HttpUtil.getPaginationLinks(exchange, mbeans, pageSize);
+            List<ObjectName> filteredMBeans = HttpUtil.filterByPage(exchange, mbeans, pageSize);
+            List<Map<String, String>> items = new ArrayList<>(filteredMBeans.size());
+            filteredMBeans.forEach(objectName -> {
+                Map<String, String> item = new LinkedHashMap<>(2);
+                item.put("name", objectName.toString());
+                String href = path + "/" + objectName.toString();
+                href = HttpUtil.escapeUrl(href);
+                item.put("href", href);
+                items.add(item);
+            });
+
+            Map<String, String> properties = new HashMap<>();
+
+            properties.put("mbeanCount", Integer.toString(mbeans.size()));
+
+            JSONMapper typeMapper1 = JSONMappingFactory.INSTANCE.getTypeMapper(items);
+            JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties);
+
+            JSONElement linkElem = typeMapper1.toJsonValue(items);
+            JSONElement propElem = typeMapper2.toJsonValue(properties);
+            JSONObject jobj = new JSONObject();
+            if(_links != null && !_links.isEmpty()) {
+                jobj.put("_links",_links);
+            }
+
+            jobj.putAll((JSONObject) propElem);
+            jobj.put("items", linkElem);
+
+            return new HttpResponse(200, jobj.toJsonString());
+        } catch (JSONMappingException e) {
+            return new HttpResponse(500, "Internal server error");
+        } catch (UnsupportedEncodingException e) {
+            return HttpResponse.SERVER_ERROR;
+        } catch (MalformedObjectNameException e) {
+            return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
+        }
+    }
+
+    @Override
+    public HttpResponse doPut(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doPost(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doDelete(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doHead(HttpExchange exchange) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,312 @@
+package com.oracle.jmx.remote.rest.http;
+
+import com.oracle.jmx.remote.rest.json.JSONArray;
+import com.oracle.jmx.remote.rest.json.JSONElement;
+import com.oracle.jmx.remote.rest.json.JSONObject;
+import com.oracle.jmx.remote.rest.json.JSONPrimitive;
+import com.oracle.jmx.remote.rest.mapper.JSONMapper;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
+import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
+import com.sun.net.httpserver.HttpExchange;
+
+import javax.management.*;
+import javax.management.remote.rest.PlatformRestAdapter;
+import java.io.IOException;
+import java.util.*;
+
+import static javax.management.MBeanOperationInfo.*;
+
+public class MBeanResource implements RestResource {
+
+    private final ObjectName objectName;
+    private final MBeanServer mBeanServer;
+
+    public MBeanResource(MBeanServer mBeanServer, ObjectName objectName) {
+        this.mBeanServer = mBeanServer;
+        this.objectName = objectName;
+    }
+
+    private JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean) throws InstanceNotFoundException, IntrospectionException, ReflectionException {
+        JSONObject jobj = new JSONObject();
+        MBeanInfo mBeanInfo = mbeanServer.getMBeanInfo(mbean);
+        if (mBeanInfo == null) {
+            return jobj;
+        }
+        jobj.put("description", mBeanInfo.getDescription());
+
+        // Populate Attribute Info
+        MBeanAttributeInfo[] attributes = mBeanInfo.getAttributes();
+        JSONArray jarr = new JSONArray();
+        for (MBeanAttributeInfo attr : attributes) {
+            String access;
+            if (attr.isReadable()) {
+                if (attr.isWritable()) {
+                    access = "read/write";
+                } else {
+                    access = "read-only";
+                }
+            } else if (attr.isWritable()) {
+                access = "write-only";
+            } else {
+                access = "no-access";
+            }
+            JSONObject jobj1 = new JSONObject();
+            jobj1.put("name", attr.getName());
+            jobj1.put("type", attr.getType());
+            jobj1.put("access", access);
+            jobj1.put("description", attr.getDescription());
+            jobj1.put("descriptor", getDescriptorJSON(attr.getDescriptor()));
+            jarr.add(jobj1);
+        }
+        jobj.put("attributeInfo", jarr);
+
+        // Add constructor Info
+        MBeanConstructorInfo[] constructorInfo = mBeanInfo.getConstructors();
+        jarr = new JSONArray();
+        for (MBeanConstructorInfo constructor : constructorInfo) {
+            JSONObject jobj1 = new JSONObject();
+            jobj1.put("name", constructor.getName());
+            JSONArray jarr1 = new JSONArray();
+            for (MBeanParameterInfo paramInfo : constructor.getSignature()) {
+                jarr1.add(getParamJSON(paramInfo));
+            }
+            jobj1.put("signature", jarr1);
+            jobj1.put("description", constructor.getDescription());
+            if (constructor.getDescriptor().getFieldNames().length > 1) {
+                jobj1.put("descriptor", getDescriptorJSON(constructor.getDescriptor()));
+            }
+            jarr.add(jobj1);
+        }
+        jobj.put("constructorInfo", jarr);
+
+        MBeanOperationInfo[] opInfo = mBeanInfo.getOperations();
+        jarr = new JSONArray();
+
+        for (MBeanOperationInfo op : opInfo) {
+            String impactString;
+            switch (op.getImpact()) {
+                case ACTION:
+                    impactString = "action";
+                    break;
+                case ACTION_INFO:
+                    impactString = "action/info";
+                    break;
+                case INFO:
+                    impactString = "info";
+                    break;
+                case UNKNOWN:
+                    impactString = "unknown";
+                    break;
+                default:
+                    impactString = "(" + op.getImpact() + ")";
+            }
+
+            JSONObject jobj1 = new JSONObject();
+
+            jobj1.put("name", op.getName());
+            JSONArray jarr1 = new JSONArray();
+            for (MBeanParameterInfo paramInfo : op.getSignature()) {
+                jarr1.add(getParamJSON(paramInfo));
+            }
+            jobj1.put("signature", jarr1);
+            jobj1.put("returnType", op.getReturnType());
+            jobj1.put("impact", impactString);
+            jobj1.put("description", op.getDescription());
+            if (op.getDescriptor().getFieldNames().length > 1) {
+                jobj1.put("descriptor", getDescriptorJSON(op.getDescriptor()));
+            }
+            jarr.add(jobj1);
+        }
+        jobj.put("operationInfo", jarr);
+
+        MBeanNotificationInfo[] notifications = mBeanInfo.getNotifications();
+        jarr = new JSONArray();
+
+        for (MBeanNotificationInfo notification : notifications) {
+
+            JSONObject jobj1 = new JSONObject();
+
+            jobj1.put("name", notification.getName());
+            JSONArray jarr1 = new JSONArray();
+            for (String notifType : notification.getNotifTypes()) {
+                jarr1.add(new JSONPrimitive(notifType));
+            }
+            jobj1.put("notifTypes", jarr1);
+            jobj1.put("description", notification.getDescription());
+            if (notification.getDescriptor().getFieldNames().length > 1) {
+                jobj1.put("descriptor", getDescriptorJSON(notification.getDescriptor()));
+            }
+            jarr.add(jobj1);
+        }
+        jobj.put("notificationInfo", jarr);
+
+        jobj.put("descriptor", getDescriptorJSON(mBeanInfo.getDescriptor()));
+        return jobj;
+    }
+
+    private JSONObject getParamJSON(MBeanParameterInfo mParamInfo) {
+        JSONObject jobj1 = new JSONObject();
+        if (mParamInfo.getDescription() != null && !mParamInfo.getDescription().isEmpty()) {
+            jobj1.put("description", mParamInfo.getDescription());
+        }
+        jobj1.put("name", mParamInfo.getName());
+        jobj1.put("type", mParamInfo.getType());
+        if (mParamInfo.getDescriptor() != null && mParamInfo.getDescriptor().getFieldNames().length > 1) {
+            jobj1.put("descriptor", getDescriptorJSON(mParamInfo.getDescriptor()));
+        }
+        return jobj1;
+    }
+
+    private JSONObject getDescriptorJSON(Descriptor descriptor) {
+        JSONObject jobj2 = new JSONObject();
+        try {
+            String[] descNames = descriptor.getFieldNames();
+            for (String descName : descNames) {
+                Object fieldValue = descriptor.getFieldValue(descName);
+                jobj2.put(descName, fieldValue != null ? fieldValue.toString() : null);
+            }
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+        return jobj2;
+    }
+
+    private Map<String, Object> getAllAttributes() throws IntrospectionException,
+            InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
+        Map<String, Object> result = new HashMap<>();
+        MBeanInfo mInfo = mBeanServer.getMBeanInfo(objectName);
+        String[] attrs = Arrays.stream(mInfo.getAttributes())
+                .map(MBeanAttributeInfo::getName)
+                .toArray(String[]::new);
+        AttributeList attrVals = mBeanServer.getAttributes(objectName, attrs);
+        if (attrVals.size() != attrs.length) {
+            List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
+            for (Attribute a : attrVals.asList()) {
+                missingAttrs.remove(a.getName());
+                result.put(a.getName(), a.getValue());
+            }
+            for (String attr : missingAttrs) {
+                try {
+                    Object attribute = mBeanServer.getAttribute(objectName, attr);
+                } catch (RuntimeException ex) {
+                    if (ex.getCause() instanceof UnsupportedOperationException) {
+                        result.put(attr, "< Attribute not supported >");
+                    } else if (ex.getCause() instanceof IllegalArgumentException) {
+                        result.put(attr, "< Invalid attributes >");
+                    }
+                    continue;
+                }
+                result.put(attr, "< Error: No such attribute >");
+            }
+        } else {
+            attrVals.asList().forEach((a) -> {
+                result.put(a.getName(), a.getValue());
+            });
+        }
+        return result;
+    }
+
+    private HttpResponse doMBeanInfo(HttpExchange exchange) {
+        try {
+            JSONObject mBeanInfo = getMBeanInfo(mBeanServer, objectName);
+            return new HttpResponse(200, mBeanInfo.toJsonString());
+        } catch (RuntimeOperationsException | IntrospectionException | ReflectionException e) {
+            return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
+        } catch (InstanceNotFoundException e) {
+            return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
+        } catch (Exception e) {
+            return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
+        }
+    }
+
+    @Override
+    public void handle(HttpExchange exchange) throws IOException {
+        String path = exchange.getRequestURI().getPath();
+        if (path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/[^\\/]+\\/?$") ||
+                path.matches("^\\/?jmx\\/servers\\/[a-zA-Z0-9\\-\\.]+\\/mbeans\\/[^\\/]+\\/info$")) {
+            RestResource.super.handle(exchange);
+        } else {
+            HttpUtil.sendResponse(exchange, new HttpResponse(404, "Not found"));
+        }
+    }
+
+    @Override
+    public HttpResponse doGet(HttpExchange exchange) {
+        if(exchange.getRequestURI().getPath().endsWith("info")) {
+            return doMBeanInfo(exchange);
+        }
+        String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", "");
+        String info = path + "/info";
+
+        try {
+            Map<String, Object> allAttributes = getAllAttributes();
+            Map<String, String> _links = new LinkedHashMap<>();
+            _links.put("info",HttpUtil.escapeUrl(info));
+
+            MBeanOperationInfo[] opInfo = mBeanServer.getMBeanInfo(objectName).getOperations();
+            JSONArray jarr = new JSONArray();
+            for (MBeanOperationInfo op : opInfo) {
+                JSONObject jobj1 = new JSONObject();
+                JSONArray jarr1 = new JSONArray();
+                jobj1.put("name", op.getName());
+                jobj1.put("href", HttpUtil.escapeUrl(path + "/" + op.getName()));
+                jobj1.put("method", "POST");
+                for (MBeanParameterInfo paramInfo : op.getSignature()) {
+                    JSONObject jobj = new JSONObject();
+                    jobj.put("name", paramInfo.getName());
+                    jobj.put("type", paramInfo.getType());
+                    jarr1.add(jobj);
+                }
+                jobj1.put("arguments", jarr1);
+                jobj1.put("returnType", op.getReturnType());
+                jarr.add(jobj1);
+            }
+
+            JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(allAttributes);
+            if(typeMapper != null) {
+                JSONElement jsonElement1 = typeMapper.toJsonValue(allAttributes);
+                JSONElement jsonElement2 = typeMapper.toJsonValue(_links);
+
+                JSONObject jobj = new JSONObject();
+                jobj.put("attributes",jsonElement1);
+                jobj.put("operations",jarr);
+                jobj.put("_links",jsonElement2);
+                return new HttpResponse(200, jobj.toJsonString());
+            } else {
+                return new HttpResponse(HttpResponse.SERVER_ERROR, "Unable to find JSONMapper");
+            }
+        } catch (RuntimeOperationsException | IntrospectionException | ReflectionException | JSONMappingException e) {
+            return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
+        } catch (InstanceNotFoundException e) {
+            return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
+        } catch (AttributeNotFoundException e) {
+            return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified Attribute does not exist");
+        } catch (MBeanException e) {
+            Throwable cause = e.getCause();
+            return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
+        } catch (Exception e) {
+            return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
+        }
+    }
+
+    @Override
+    public HttpResponse doPut(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doPost(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doDelete(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doHead(HttpExchange exchange) {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,85 @@
+package com.oracle.jmx.remote.rest.http;
+
+import com.oracle.jmx.remote.rest.json.JSONArray;
+import com.oracle.jmx.remote.rest.json.JSONObject;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerDelegateMBean;
+import javax.management.remote.rest.PlatformRestAdapter;
+import java.util.List;
+
+public class MBeanServerCollectionResource implements RestResource {
+
+    private final List<JmxRestAdapter> restAdapters;
+    private final int pageSize = 5;
+
+    public MBeanServerCollectionResource(List<JmxRestAdapter> adapters, HttpServer server) {
+        this.restAdapters = adapters;
+        server.createContext("/jmx/servers", this);
+    }
+
+    private String getMBeanServerID(MBeanServer server) {
+        MBeanServerDelegateMBean mbean = JMX.newMBeanProxy(server,
+                MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
+        return mbean.getMBeanServerId();
+    }
+
+    @Override
+    public HttpResponse doGet(HttpExchange exchange) {
+        try {
+            JSONObject _links = HttpUtil.getPaginationLinks(exchange, restAdapters, pageSize);
+            List<JmxRestAdapter> filteredList = HttpUtil.filterByPage(exchange, restAdapters, pageSize);
+            if (filteredList == null) {
+                return new HttpResponse(HttpResponse.BAD_REQUEST, "Invald query parameters");
+            }
+
+            final String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", "");
+
+            JSONObject root = new JSONObject();
+            if(_links != null && !_links.isEmpty()) {
+                root.put("_links",_links);
+            }
+
+            root.put("mBeanServerCount",Integer.toString(restAdapters.size()));
+
+            JSONArray list = new JSONArray();
+            filteredList.stream().map((adapter) -> {
+                JSONObject result = new JSONObject();
+                result.put("name", adapter.getAlias());
+                result.put("href", path +"/" +adapter.getAlias());
+                return result;
+            }).forEachOrdered((result) -> {
+                list.add(result);
+            });
+            root.put("items",list);
+            return new HttpResponse(200, root.toJsonString());
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return new HttpResponse(400, HttpResponse.getErrorMessage(ex));
+        }
+    }
+
+    @Override
+    public HttpResponse doPut(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doPost(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doDelete(HttpExchange exchange) {
+        return null;
+    }
+
+    @Override
+    public HttpResponse doHead(HttpExchange exchange) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestCollectionFilter.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,10 @@
+package com.oracle.jmx.remote.rest.http;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public interface RestCollectionFilter<T> {
+    List<T> filter(List<T> input);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestConfig.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,5 @@
+package com.oracle.jmx.remote.rest.http;
+
+public interface RestConfig {
+    public static final int DEFAULT_PAGE_SIZE = 50;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,45 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.oracle.jmx.remote.rest.http;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import java.io.IOException;
+
+/**
+ *
+ * @author harsha
+ */
+public interface RestResource extends HttpHandler {
+    @Override
+    public default void handle (HttpExchange exchange) throws IOException {
+        HttpResponse httpResponse = HttpResponse.METHOD_NOT_ALLOWED;
+        switch (exchange.getRequestMethod()) {
+            case "GET":
+                httpResponse = doGet(exchange);
+                break;
+            case "POST":
+                httpResponse = doPost(exchange);
+                break;
+            case "PUT":
+                httpResponse = doPut(exchange);
+                break;
+            case "DELETE":
+                httpResponse = doDelete(exchange);
+                break;
+            case "HEAD":
+                httpResponse = doHead(exchange);
+                break;
+        }
+        HttpUtil.sendResponse(exchange,httpResponse);
+    }
+    
+    public HttpResponse doGet(HttpExchange exchange);
+    public HttpResponse doPut(HttpExchange exchange);
+    public HttpResponse doPost(HttpExchange exchange);
+    public HttpResponse doDelete(HttpExchange exchange);
+    public HttpResponse doHead(HttpExchange exchange);
+}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingException.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingException.java	Mon Dec 25 20:42:05 2017 +0530
@@ -12,6 +12,8 @@
 
     private static final long serialVersionUID = -3099452281524742227L;
 
+    public static final JSONMappingException UNABLE_TO_MAP = new JSONMappingException("Unable to map types");
+
     public JSONMappingException() {
         super();
     }
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingFactory.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingFactory.java	Mon Dec 25 20:42:05 2017 +0530
@@ -5,22 +5,21 @@
  */
 package com.oracle.jmx.remote.rest.mapper;
 
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.openmbean.*;
 import com.oracle.jmx.remote.rest.json.JSONArray;
 import com.oracle.jmx.remote.rest.json.JSONElement;
 import com.oracle.jmx.remote.rest.json.JSONObject;
 import com.oracle.jmx.remote.rest.json.JSONPrimitive;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.openmbean.*;
 import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author harsha
@@ -136,25 +135,42 @@
     }
 
     public JSONMapper getTypeMapper(Object object) {
+        if (object == null) return null;
         Object obj = object;
         Class<?> cls = object.getClass();
         if (cls.isArray()) {
             Object arrayElement = getArrayElement(obj);
-            if (arrayElement instanceof CompositeDataSupport) {
-                CompositeDataSupport cds = (CompositeDataSupport) arrayElement;
+            if (arrayElement instanceof CompositeData) {
+                CompositeData cds = (CompositeData) arrayElement;
                 return new OpenArrayTypeMapper(cls, cds.getCompositeType());
-            } else if (arrayElement instanceof TabularDataSupport) {
-                TabularDataSupport tds = (TabularDataSupport) arrayElement;
+            } else if (arrayElement instanceof TabularData) {
+                TabularData tds = (TabularData) arrayElement;
                 return new OpenArrayTypeMapper(cls, tds.getTabularType());
             }
         }
 
-        if (object instanceof CompositeDataSupport) {
-            CompositeDataSupport cds = (CompositeDataSupport) object;
-            return getTypeMapper(cds.getCompositeType());
-        } else if (object instanceof TabularDataSupport) {
-            TabularDataSupport cds = (TabularDataSupport) object;
+        if (object instanceof CompositeData) {
+            CompositeData cd = (CompositeData) object;
+            return getTypeMapper(cd.getCompositeType());
+        } else if (object instanceof TabularData) {
+            TabularData cds = (TabularData) object;
             return getTypeMapper(cds.getTabularType());
+        } else if (object instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) object;
+            boolean unknownMapper = c.stream().anyMatch(k -> (k != null) && (getTypeMapper(k) == null));
+            if (unknownMapper)
+                return null;
+            else
+                return new CollectionMapper();
+        } else if (object instanceof Map<?, ?>) {
+            Map<?, ?> map = (Map<?, ?>) object;
+            boolean unknownMapper = map.keySet().stream().
+                    anyMatch(k -> ((k != null) && (getTypeMapper(k) == null)
+                            || (map.get(k) != null && getTypeMapper(map.get(k)) == null)));
+            if (unknownMapper)
+                return null;
+            else
+                return new MapMapper();
         } else {
             return getTypeMapper(cls);
         }
@@ -165,6 +181,7 @@
     name differ for each classloader
      */
     public JSONMapper getTypeMapper(Class<?> type) {
+        if (type == null) return null;
         if (type.isArray()) {
             Class<?> compType = getArrayComponent(type);
             if (typeMapper.get(compType) != null) {
@@ -194,7 +211,7 @@
                 throw new RuntimeException(ex);
             }
         } else if (type instanceof TabularType) {
-            // TODO
+            return new OpenTabularTypeMapper((TabularType) type);
         }
         return null; //keep compiler happy
     }
@@ -214,12 +231,13 @@
 
     private static class OpenArrayTypeMapper extends GenericArrayMapper {
 
-        public OpenArrayTypeMapper(Class<?> type, OpenType<?> elementOpenType) {
+        OpenArrayTypeMapper(Class<?> type, OpenType<?> elementOpenType) {
             super(type);
             mapper = JSONMappingFactory.INSTANCE.getTypeMapper(elementOpenType);
         }
     }
 
+    // This mapper array type for any java class
     private static class GenericArrayMapper implements JSONMapper {
 
         private final Class<?> type;
@@ -280,6 +298,10 @@
         }
     }
 
+    /*
+    Mapper for compositeType. CompositeData cannot be mapped without it's associated
+    OpenType
+     */
     private static class OpenCompositeTypeMapper implements JSONMapper {
 
         private final CompositeType type;
@@ -310,7 +332,7 @@
 
         @Override
         public JSONElement toJsonValue(Object d) throws JSONMappingException {
-            CompositeDataSupport data = (CompositeDataSupport) d;
+            CompositeData data = (CompositeData) d;
             if (data == null) {
                 return new JSONPrimitive();
             }
@@ -381,7 +403,19 @@
 
         @Override
         public JSONElement toJsonValue(Object data) throws JSONMappingException {
-            throw new UnsupportedOperationException();
+            if (data == null) {
+                return new JSONPrimitive();
+            }
+            TabularDataSupport tds = (TabularDataSupport) data;
+            JSONArray jsonArray = new JSONArray();
+            for (Map.Entry<Object, Object> a : tds.entrySet()) {
+                CompositeData cds = (CompositeData) a.getValue();
+                JSONMapper cdsMapper = JSONMappingFactory.INSTANCE.getTypeMapper(cds);
+                if(cdsMapper != null) {
+                    jsonArray.add(cdsMapper.toJsonValue(cds));
+                }
+            }
+            return jsonArray;
         }
     }
 
@@ -635,4 +669,112 @@
             return new JSONPrimitive(df.format((Date) data));
         }
     }
+
+    private static final class MapMapper implements JSONMapper {
+
+        @Override
+        public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
+            if (jsonValue instanceof JSONObject) {
+                JSONObject obj = (JSONObject) jsonValue;
+                Map<String, Object> result = new HashMap<>(obj.size());
+                for (String k : result.keySet()) {
+                    JSONElement elem = obj.get(k);
+                    if (elem instanceof JSONPrimitive) {
+                        result.put(k, ((JSONPrimitive) elem).getValue());
+                    } else {
+                        JSONMapper mapper;
+                        if (elem instanceof JSONObject) {
+                            mapper = new MapMapper();
+                            result.put(k, mapper.toJavaObject(elem));
+                        } else if (elem instanceof JSONArray) {
+                            mapper = new CollectionMapper();
+                            result.put(k, mapper.toJavaObject(elem));
+                        } else {
+                            throw new JSONDataException("Unable to map : " + elem.getClass());
+                        }
+                    }
+                }
+                return result;
+            }
+            throw new JSONDataException("Inalid input");
+        }
+
+        @Override
+        public JSONElement toJsonValue(Object data) throws JSONMappingException {
+            if (data instanceof Map) {
+                JSONObject jobj = new JSONObject();
+                Map<?, ?> input = (Map<?, ?>) data;
+                for (Object k : input.keySet()) {
+                    String key = k.toString();
+                    final Object value = input.get(k);
+                    if (value == null) {
+                        jobj.put(key, new JSONPrimitive());
+                    } else {
+                        JSONMapper mapper = JSONMappingFactory.INSTANCE.getTypeMapper(value);
+                        if (mapper == null) {
+                            throw new JSONMappingException("Unable to map : " + value);
+                        }
+                        jobj.put(key, mapper.toJsonValue(value));
+                    }
+                }
+                return jobj;
+            } else {
+                throw new JSONMappingException("Invalid Input");
+            }
+        }
+    }
+
+    private static final class CollectionMapper implements JSONMapper {
+
+        public CollectionMapper() {
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
+            if (jsonValue instanceof JSONArray) {
+                JSONArray jarr = (JSONArray) jsonValue;
+                List<Object> result = new ArrayList<>(jarr.size());
+                for (JSONElement elem : jarr) {
+                    if (elem instanceof JSONPrimitive) {
+                        result.add(((JSONPrimitive) elem).getValue());
+                    } else {
+                        JSONMapper mapper;
+                        if (elem instanceof JSONObject) {
+                            mapper = new MapMapper();
+                            result.add(mapper.toJavaObject(elem));
+                        } else if (elem instanceof JSONArray) {
+                            mapper = new CollectionMapper();
+                            result.add(mapper.toJavaObject(elem));
+                        } else {
+                            throw new JSONDataException("Unable to map : " + elem.getClass());
+                        }
+                    }
+                }
+                return result;
+            }
+            throw new JSONDataException("Inalid input");
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public JSONElement toJsonValue(Object data) throws JSONMappingException {
+            if (data instanceof Collection) {
+                JSONArray jarr = new JSONArray();
+                Collection<Object> c = (Collection<Object>) data;
+                Iterator<Object> itr = c.iterator();
+                while (itr.hasNext()) {
+                    Object next = itr.next();
+                    JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(next);
+                    if (typeMapper == null) {
+                        throw JSONMappingException.UNABLE_TO_MAP;
+                    }
+                    jarr.add(typeMapper.toJsonValue(next));
+                }
+                return jarr;
+            } else {
+                throw new JSONMappingException("Invalid Input");
+            }
+        }
+    }
 }
--- a/src/java.management.rest/share/classes/javax/management/remote/rest/JmxRestAdapter.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package javax.management.remote.rest;
-
-import javax.management.MBeanServer;
-
-/**
- * @author harsha
- */
-public interface JmxRestAdapter {
-
-    public static final String AUTHENTICATOR
-            = "jmx.remote.authenticator";
-    public static final String LOGIN_CONFIG_PROP
-            = "jmx.remote.x.login.config";
-    public static final String PASSWORD_FILE_PROP
-            = "jmx.remote.x.password.file";
-
-    public void start();
-
-    public void stop();
-
-    public String getBaseUrl();
-
-    public MBeanServer getMBeanServer();
-}
--- a/src/java.management.rest/share/classes/javax/management/remote/rest/JmxRestAdapterImpl.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package javax.management.remote.rest;
-
-import com.oracle.jmx.remote.rest.http.PostRequestHandler;
-import com.oracle.jmx.remote.rest.http.GetRequestHandler;
-import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
-import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
-import com.sun.jmx.remote.security.SubjectDelegator;
-import com.sun.net.httpserver.*;
-
-import javax.management.*;
-import javax.management.relation.MBeanServerNotificationFilter;
-import javax.management.remote.JMXAuthenticator;
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
-import javax.security.auth.Subject;
-import java.io.*;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.*;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.*;
-import com.sun.net.httpserver.Authenticator;
-
-/**
- * @author harsha
- */
-public final class JmxRestAdapterImpl implements JmxRestAdapter, NotificationListener {
-
-    // TODO: These should be wrapped in ReadWriteLock
-    private static final Map<String, MBeanServer> authMBeanServer = new HashMap<>();
-    final List<String> allowedMbeans = new ArrayList<>();
-    private final HttpServer httpServer;
-    private final String contextStr;
-    private final Map<String, ?> env;
-    private final MBeanServer mbeanServer;
-    private final String realm = "";
-    private final GetRequestHandler getHandler;
-    private final PostRequestHandler postHandler;
-    private HttpContext httpContext;
-    private JMXAuthenticator authenticator = null;
-    private boolean started = false;
-
-    JmxRestAdapterImpl(HttpServer hServer, String context, Map<String, ?> env, MBeanServer mbeanServer) {
-        httpServer = hServer;
-        this.contextStr = context;
-        this.env = env;
-        this.mbeanServer = mbeanServer;
-        if (env.get("jmx.remote.x.authentication") != null) {
-            authenticator = (JMXAuthenticator) env.get(JmxRestAdapterImpl.AUTHENTICATOR);
-            if (authenticator == null) {
-                if (env.get("jmx.remote.x.password.file") != null
-                        || env.get("jmx.remote.x.login.config") != null) {
-                    authenticator = new JMXPluggableAuthenticator(env);
-                } else {
-                    // Throw exception for invalid authentication config
-                }
-            }
-        }
-        introspectMBeanTypes(mbeanServer);
-        MBeanServerNotificationFilter filter = new MBeanServerNotificationFilter();
-        filter.enableAllObjectNames();
-        try {
-            mbeanServer.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, this, filter, null);
-        } catch (InstanceNotFoundException ex) {
-        }
-        getHandler = new GetRequestHandler(mbeanServer, allowedMbeans);
-        postHandler = new PostRequestHandler(mbeanServer, allowedMbeans);
-    }
-
-    @Override
-    public synchronized void start() {
-        if (!started) {
-            httpContext = httpServer.createContext("/jmx/" + contextStr + "/", new DefaultHTTPHandler());
-            if (env.get("jmx.remote.x.authentication") != null) {
-                httpContext.setAuthenticator(new BasicAuthenticator());
-            }
-            started = true;
-        }
-    }
-
-    @Override
-    public synchronized void stop() {
-        if (!started) {
-            throw new IllegalStateException("Rest Adapter not started yet");
-        }
-        httpServer.removeContext(httpContext);
-        started = false;
-    }
-
-    @Override
-    public String getBaseUrl() {
-        if (!started) {
-            throw new IllegalStateException("Adapter not started");
-        }
-        try {
-            if (httpServer instanceof HttpsServer) {
-                return "https://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort() + "/jmx/" + contextStr + "/";
-            }
-            return "http://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort() + "/jmx/" + contextStr + "/";
-        } catch (UnknownHostException ex) {
-            return "http://localhost" + ":" + httpServer.getAddress().getPort() + "/jmx/" + contextStr + "/";
-        }
-    }
-
-    @Override
-    public MBeanServer getMBeanServer() {
-        return mbeanServer;
-    }
-
-    private boolean isMBeanAllowed(ObjectName objName) {
-        try {
-            MBeanInfo mInfo = mbeanServer.getMBeanInfo(objName);
-            MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes();
-            for (MBeanAttributeInfo attrInfo : attrsInfo) {
-                String type = attrInfo.getType();
-                if (!JSONMappingFactory.INSTANCE.isTypeMapped(type)) {
-                    return false;
-                }
-            }
-            MBeanOperationInfo[] operations = mInfo.getOperations();
-            for (MBeanOperationInfo opInfo : operations) {
-                MBeanParameterInfo[] signature = opInfo.getSignature();
-                for (MBeanParameterInfo sig : signature) {
-                    if (!JSONMappingFactory.INSTANCE.isTypeMapped(sig.getType())) {
-                        return false;
-                    }
-                }
-                if (!JSONMappingFactory.INSTANCE.isTypeMapped(opInfo.getReturnType())) {
-                    return false;
-                }
-            }
-            return true;
-        } catch (InstanceNotFoundException | IntrospectionException | ReflectionException | ClassNotFoundException ex) {
-            ex.printStackTrace();
-            return false;
-        }
-    }
-
-    private void introspectMBeanTypes(MBeanServer server) {
-        if (allowedMbeans.isEmpty()) {
-            Set<ObjectInstance> allMBeans = server.queryMBeans(null, null); // get all Mbeans
-            allMBeans.stream().filter((objIns) -> (isMBeanAllowed(objIns.getObjectName())))
-                    .forEachOrdered(objIns -> allowedMbeans.add(objIns.getObjectName().toString()));
-        }
-    }
-
-    @Override
-    public void handleNotification(Notification notification, Object handback) {
-        try {
-            MBeanServerNotification mbs = (MBeanServerNotification) notification;
-            if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
-                ObjectName mBeanName = mbs.getMBeanName();
-                if (isMBeanAllowed(mBeanName)) {
-                    allowedMbeans.add(mBeanName.toString());
-                }
-            } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
-                if (allowedMbeans.contains(mbs.getMBeanName().toString())) {
-                    allowedMbeans.remove(mbs.getMBeanName().toString());
-                }
-            }
-        } catch (Exception e) {
-        }
-    }
-
-    private MBeanServer getMBeanServerProxy(MBeanServer mbeaServer, Subject subject) {
-        return (MBeanServer) Proxy.newProxyInstance(MBeanServer.class.getClassLoader(),
-                new Class<?>[]{MBeanServer.class},
-                new AuthInvocationHandler(mbeaServer, subject));
-    }
-
-    private static class HttpUtil {
-
-        public static String getRequestCharset(HttpExchange ex) {
-            String charset = null;
-            List<String> contentType = ex.getRequestHeaders().get("Content-type");
-            if (contentType != null) {
-                for (String kv : contentType) {
-                    for (String value : kv.split(";")) {
-                        value = value.trim();
-                        if (value.toLowerCase().startsWith("charset=")) {
-                            charset = value.substring("charset=".length());
-                        }
-                    }
-                }
-            }
-            return charset;
-        }
-
-        public static String getAcceptCharset(HttpExchange ex) {
-            List<String> acceptCharset = ex.getRequestHeaders().get("Accept-Charset");
-            if (acceptCharset != null && acceptCharset.size() > 0) {
-                return acceptCharset.get(0);
-            }
-            return null;
-        }
-
-        public static String getGetRequestResource(HttpExchange ex, String charset) throws UnsupportedEncodingException {
-            String httpHandlerPath = ex.getHttpContext().getPath();
-            String requestURIpath = ex.getRequestURI().getPath();
-            String getRequestPath = requestURIpath.substring(httpHandlerPath.length());
-            if (charset != null) {
-                return URLDecoder.decode(getRequestPath, charset);
-            } else {
-                return getRequestPath;
-            }
-        }
-
-        public static String getGetRequestQuery(HttpExchange ex, String charset) throws UnsupportedEncodingException {
-            String query = ex.getRequestURI().getQuery();
-            if (charset != null && query != null) {
-                return URLDecoder.decode(query, charset);
-            } else {
-                return query;
-            }
-        }
-    }
-
-    private class BasicAuthenticator extends Authenticator {
-
-        @Override
-        public Authenticator.Result authenticate(HttpExchange he) {
-            Headers rmap = he.getRequestHeaders();
-            String auth = rmap.getFirst("Authorization");
-            if (auth == null) {
-                Headers map = he.getResponseHeaders();
-                map.set("WWW-Authenticate", "Basic realm=" + realm);
-                return new Authenticator.Retry(401);
-            }
-            int sp = auth.indexOf(' ');
-            if (sp == -1 || !auth.substring(0, sp).equals("Basic")) {
-                return new Authenticator.Failure(401);
-            }
-            byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1));
-            String credentials = new String(b);
-            int colon = credentials.indexOf(':');
-            String uname = credentials.substring(0, colon);
-            String pass = credentials.substring(colon + 1);
-
-            if (authMBeanServer.containsKey(credentials)) {
-                return new Authenticator.Success(new HttpPrincipal(uname, realm));
-            } else {
-                Subject subject = null;
-                if (authenticator != null) {
-                    String[] credential = new String[]{uname, pass};
-                    try {
-                        subject = authenticator.authenticate(credential);
-                    } catch (SecurityException e) {
-                        return new Authenticator.Failure(400);
-                    }
-                }
-                MBeanServer proxy = getMBeanServerProxy(mbeanServer, subject);
-                authMBeanServer.put(credentials, proxy);
-                return new Authenticator.Success(new HttpPrincipal(uname, realm));
-            }
-        }
-    }
-
-    private class AuthInvocationHandler implements InvocationHandler {
-
-        private final MBeanServer mbeanServer;
-        private final AccessControlContext acc;
-
-        public AuthInvocationHandler(MBeanServer server, Subject subject) {
-            this.mbeanServer = server;
-            if (subject == null) {
-                this.acc = null;
-            } else {
-                if (SubjectDelegator.checkRemoveCallerContext(subject)) {
-                    acc = JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
-                } else {
-                    acc = JMXSubjectDomainCombiner.getContext(subject);
-                }
-            }
-        }
-
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            if (acc == null) {
-                return method.invoke(mbeanServer, args);
-            } else {
-                PrivilegedAction<Object> op = () -> {
-                    try {
-                        return method.invoke(mbeanServer, args);
-                    } catch (Exception ex) {
-                    }
-                    return null;
-                };
-                return AccessController.doPrivileged(op, acc);
-            }
-        }
-    }
-
-    private class DefaultHTTPHandler implements HttpHandler {
-
-        Map<String, List<String>> allowedMbeans = new HashMap<>();
-
-        DefaultHTTPHandler() {
-        }
-
-        @Override
-        public void handle(HttpExchange he) throws IOException {
-            MBeanServer server = mbeanServer;
-            if (env.get("jmx.remote.x.authentication") != null) {
-                Headers rmap = he.getRequestHeaders();
-                String auth = rmap.getFirst("Authorization");
-                int sp = auth.indexOf(' ');
-                byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1));
-                String authCredentials = new String(b);
-                server = authMBeanServer.get(authCredentials);
-                if (server == null) {
-                    throw new IllegalArgumentException("Invalid HTTP request Headers");
-                }
-            }
-
-            String charset = HttpUtil.getRequestCharset(he);
-            try {
-                switch (he.getRequestMethod()) {
-                    case "GET":
-                        JSONObject resp = getHandler.handle(HttpUtil.getGetRequestResource(he, charset),
-                                HttpUtil.getGetRequestQuery(he, charset));
-                        sendResponse(he, resp.toJsonString(), ((Long) (((JSONPrimitive) resp.get("status")).getValue())).intValue(), charset);
-                        break;
-                    case "POST":
-                        String requestBody = readRequestBody(he, charset);
-                        List<JSONObject> responses = postHandler.handle(requestBody);
-                        if (responses.size() == 1) {
-                            JSONObject jobj = responses.get(0);
-                            sendResponse(he, jobj.toJsonString(), ((Long) (((JSONPrimitive) responses.get(0).get("status")).getValue())).intValue(), charset);
-                        } else {
-                            int finalCode = HttpURLConnection.HTTP_OK;
-                            boolean isHttpOkPresent = responses.stream()
-                                    .filter(r -> ((Long) (((JSONPrimitive) responses.get(0).get("status")).getValue())).intValue() == HttpURLConnection.HTTP_OK)
-                                    .findFirst().isPresent();
-                            if (!isHttpOkPresent) {
-                                finalCode = ((Long) (((JSONPrimitive) responses.get(0).get("status")).getValue())).intValue();
-                            }
-
-                            JSONArray jarr = new JSONArray();
-                            responses.forEach(r -> jarr.add(r));
-                            JSONObject jobj = new JSONObject();
-                            jobj.put("status", new JSONPrimitive(finalCode));
-                            jobj.put("result", jarr);
-                            String finalResult = jobj.toJsonString();
-                            sendResponse(he, finalResult, finalCode, charset);
-                        }
-                        break;
-                    default:
-                        sendResponse(he, "Not supported", HttpURLConnection.HTTP_BAD_METHOD, charset);
-                        break;
-                }
-            } catch (Throwable t) {
-                t.printStackTrace();
-            }
-        }
-
-        private String readRequestBody(HttpExchange he, String charset) throws IOException {
-            StringBuilder stringBuilder = new StringBuilder();
-            InputStreamReader in = charset != null ? new InputStreamReader(he.getRequestBody(), charset) : new InputStreamReader(he.getRequestBody());
-            BufferedReader br = new BufferedReader(in);
-            String line;
-            while ((line = br.readLine()) != null) {
-                String decode = charset != null ? URLDecoder.decode(line, charset) : line;
-                stringBuilder.append(decode);
-            }
-            return stringBuilder.toString();
-        }
-
-        private void sendResponse(HttpExchange exchange, String response, int code, String charset) throws IOException {
-            String acceptCharset = HttpUtil.getAcceptCharset(exchange);
-            if (acceptCharset != null) {
-                charset = acceptCharset;
-            }
-
-            // Set response headers explicitly
-            String msg = charset == null ? response : URLEncoder.encode(response, charset);
-            byte[] bytes = msg.getBytes();
-            Headers resHeaders = exchange.getResponseHeaders();
-            resHeaders.add("Content-Type", "application/json; charset=" + charset);
-
-            exchange.sendResponseHeaders(code, bytes.length);
-            try (OutputStream os = exchange.getResponseBody()) {
-                os.write(bytes);
-            }
-        }
-    }
-}
--- a/src/java.management.rest/share/classes/javax/management/remote/rest/PlatformRestAdapter.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management.rest/share/classes/javax/management/remote/rest/PlatformRestAdapter.java	Mon Dec 25 20:42:05 2017 +0530
@@ -5,6 +5,10 @@
  */
 package javax.management.remote.rest;
 
+import javax.management.MBeanServerFactoryListener;
+
+import com.oracle.jmx.remote.rest.http.JmxRestAdapter;
+import com.oracle.jmx.remote.rest.http.MBeanServerCollectionResource;
 import com.sun.net.httpserver.HttpServer;
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsServer;
@@ -17,28 +21,38 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
 import java.security.KeyStore;
 import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
 
 /**
  * @author harsha
  */
-public class PlatformRestAdapter {
+public class PlatformRestAdapter implements MBeanServerFactoryListener {
 
-    private static final Set<String> contextList = new HashSet<>();
     /*
      * Initializes HTTPServer with settings from config file
      * acts as container for platform rest adapter
      */
     private static HttpServer httpServer = null;
-    private static JmxRestAdapter instance = null;
+    private static List<JmxRestAdapter> restAdapters = new CopyOnWriteArrayList<>();
+    private static Map<String, Object> env;
+
+    private static String portStr;
+    private static Properties props;
 
     private PlatformRestAdapter() {
     }
 
     public static synchronized void init(String portStr, Properties props) throws IOException {
-        if (instance == null) {
+        PlatformRestAdapter.portStr = portStr;
+        PlatformRestAdapter.props = props;
+
+        if (httpServer == null) {
             final int port;
             try {
                 port = Integer.parseInt(portStr);
@@ -55,18 +69,18 @@
                         = props.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);
                 SSLContext ctx = getSSlContext(sslConfigFileName);
                 if (ctx != null) {
-                    HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 0);
+                    HttpsServer server = HttpsServer.create(new InetSocketAddress("0.0.0.0", port), 0);
                     server.setHttpsConfigurator(new HttpsConfigurator(ctx));
                     httpServer = server;
                 } else {
-                    httpServer = HttpServer.create(new InetSocketAddress(port), 0);
+                    httpServer = HttpServer.create(new InetSocketAddress("0.0.0.0", port), 0);
                 }
             } else {
-                httpServer = HttpServer.create(new InetSocketAddress(port), 0);
+                httpServer = HttpServer.create(new InetSocketAddress("0.0.0.0", port), 0);
             }
 
             // Initialize rest adapter
-            Map<String, Object> env = new HashMap<>();
+			env = new HashMap<>();
             // Do we use authentication?
             final String useAuthenticationStr
                     = props.getProperty(PropertyNames.USE_AUTHENTICATION,
@@ -92,22 +106,65 @@
                 }
             }
 
-            instance = new JmxRestAdapterImpl(httpServer, "default", env, ManagementFactory.getPlatformMBeanServer());
+            restAdapters.add(new JmxRestAdapter(httpServer, "platform", env, ManagementFactory.getPlatformMBeanServer()));
+            new MBeanServerCollectionResource(restAdapters, httpServer);
+            httpServer.setExecutor(Executors.newCachedThreadPool());
             httpServer.start();
         }
     }
 
-    public static void stop() {
-        if (instance != null) {
-            instance.stop();
-            instance = null;
-        }
+    public synchronized static void stop() {
         if (httpServer != null) {
             httpServer.stop(0);
             httpServer = null;
         }
     }
 
+    public synchronized static void start() throws IOException {
+        if(httpServer == null) {
+            PlatformRestAdapter.init(portStr,props);
+        }
+    }
+
+    @Override
+    public void onMBeanServerCreated(MBeanServer mBeanServer) {
+        JmxRestAdapter restAdapter = new JmxRestAdapter(httpServer, "", env, mBeanServer);
+        restAdapters.add(restAdapter);
+    }
+
+    @Override
+    public void onMBeanServerRemoved(MBeanServer mBeanServer) {
+
+    }
+
+    public static synchronized String getAuthority() {
+        if(httpServer == null) {
+            throw new IllegalStateException("Platform rest adapter not initialized");
+        }
+        try {
+            if (httpServer instanceof HttpsServer) {
+                return "https://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort();
+            }
+            return "http://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort();
+        } catch (UnknownHostException ex) {
+            return "http://localhost" + ":" + httpServer.getAddress().getPort();
+        }
+    }
+
+    public static synchronized String getBaseURL() {
+        if(httpServer == null) {
+            throw new IllegalStateException("Platform rest adapter not initialized");
+        }
+        try {
+            if (httpServer instanceof HttpsServer) {
+                return "https://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort() + "/jmx/servers";
+            }
+            return "http://" + InetAddress.getLocalHost().getHostName() + ":" + httpServer.getAddress().getPort() + "/jmx/servers";
+        } catch (UnknownHostException ex) {
+            return "http://localhost" + ":" + httpServer.getAddress().getPort() + "/jmx/servers";
+        }
+    }
+
     private static SSLContext getSSlContext(String sslConfigFileName) {
         final String keyStore, keyStorePassword, trustStore, trustStorePassword;
 
@@ -166,21 +223,6 @@
         return null;
     }
 
-    public static JmxRestAdapter getInstance() {
-        if (instance == null) {
-            throw new IllegalStateException("PlatformRestAdapter not initialized");
-        }
-        return instance;
-    }
-
-    public static synchronized JmxRestAdapter newRestAdapter(String context, Map<String, ?> env, MBeanServer mbeanServer) {
-        if (!contextList.contains(context)) {
-            contextList.add(context);
-            return new JmxRestAdapterImpl(httpServer, context, env, mbeanServer);
-        }
-        throw new IllegalArgumentException(context + " is already taken");
-    }
-
     /**
      * Default values for JMX configuration properties.
      */
@@ -202,7 +244,7 @@
      */
     public static interface PropertyNames {
 
-        public static final String PORT
+        String PORT
                 = "com.sun.management.jmxremote.rest.port";
         public static final String HOST
                 = "com.sun.management.jmxremote.host";
--- a/src/java.management/share/classes/javax/management/MBeanServerFactory.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/java.management/share/classes/javax/management/MBeanServerFactory.java	Mon Dec 25 20:42:05 2017 +0530
@@ -33,7 +33,10 @@
 import java.security.Permission;
 import java.util.ArrayList;
 import java.lang.System.Logger.Level;
+import java.util.LinkedList;
+import java.util.List;
 import javax.management.loading.ClassLoaderRepository;
+
 import sun.reflect.misc.ReflectUtil;
 
 
@@ -332,6 +335,7 @@
                         "MBeanServerBuilder.newMBeanServer() returned null";
                 throw new JMRuntimeException(msg);
             }
+            notifyListenersCreated(mbeanServer);
             return mbeanServer;
         }
     }
@@ -425,6 +429,7 @@
                     "MBeanServer was not in list!");
             throw new IllegalArgumentException("MBeanServer was not in list!");
         }
+        notifyListenersRemoved(mbs);
     }
 
     private static final ArrayList<MBeanServer> mBeanServerList =
@@ -536,4 +541,30 @@
         return builder;
     }
 
+    private static final List<MBeanServerFactoryListener> listeners = new LinkedList<>();
+
+    /**
+     * Add listener
+     * @param listener the listener object
+     */
+    public static void addListener(MBeanServerFactoryListener listener) {
+        if(!listeners.contains(listener))
+            listeners.add(listener);
+    }
+
+    /**
+     * remove listener
+     * @param listener the listener object
+     */
+    public static void removeListener(MBeanServerFactoryListener listener) {
+        listeners.remove(listener);
+    }
+
+    private static void notifyListenersCreated(MBeanServer server) {
+        listeners.forEach(l -> l.onMBeanServerCreated(server));
+    }
+
+    private static void notifyListenersRemoved(MBeanServer server) {
+        listeners.forEach(l -> l.onMBeanServerRemoved(server));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management/share/classes/javax/management/MBeanServerFactoryListener.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,19 @@
+package javax.management;
+
+/**
+ * Listener interface to get notified when MBeanServer
+ * is created/released
+ */
+public interface MBeanServerFactoryListener {
+    /**
+     * When MbeanServer is added
+     * @param mBeanServer the mBeanServer
+     */
+    public void onMBeanServerCreated(MBeanServer mBeanServer);
+
+    /**
+     * When MBeanServer is released
+     * @param mBeanServer the mBeanServer
+     */
+    public void onMBeanServerRemoved(MBeanServer mBeanServer);
+}
--- a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java	Fri Sep 01 14:36:28 2017 +0530
+++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java	Mon Dec 25 20:42:05 2017 +0530
@@ -550,7 +550,6 @@
         try {
             if (props.get(REST_PORT) != null) {
                 PlatformRestAdapter.init((String) props.get(REST_PORT), props);
-                PlatformRestAdapter.getInstance().start();
             }
         } catch (Throwable ex) {
             ex.printStackTrace();
--- a/test/javax/management/remote/rest/DefaultRestAdapter.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- /*
- * @test
- * @run main/othervm -Dcom.sun.management.jmxremote.rest.port=8686 -Dcom.sun.management.config.file=/home/harsha/work/jdk10_rest/jdk/test/javax/management/remote/rest/mgmt1.properties DefaultRestAdapter
- */
-import java.io.IOException;
-import java.util.Arrays;
-
-public class DefaultRestAdapter {
-
-    public static void main(String[] args) throws IOException, Exception {
-        Arrays.asList(args).stream().forEach(System.out::println);
-        Thread.sleep(1000000);
-    }
-}
-
-
-
--- a/test/javax/management/remote/rest/JsonParserTest.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-
-
-
-import javax.management.remote.rest.json.JSONElement;
-import javax.management.remote.rest.json.parser.JSONParser;
-import javax.management.remote.rest.json.parser.ParseException;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- *
- * @author harsha
- */
-public class JsonParserTest {
-    
-    public JsonParserTest() {
-    }
-
-    // TODO add test methods here.
-    // The methods must be annotated with annotation @Test. For example:
-    //
-    // @Test
-    // public void hello() {}
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-
-    @BeforeMethod
-    public void setUpMethod() throws Exception {
-    }
-
-    @AfterMethod
-    public void tearDownMethod() throws Exception {
-    }
-    
-    @DataProvider
-    public Object[][] getJsonString() {
-        Object[][] data = new Object[2][1];
-        data[0][0] = "{organisms:[\n" +
-"        {\n" +
-"        id:10929,\n" +
-"        name:\"Bovine Rotavirus\"\n" +
-"        },\n" +
-"        {\n" +
-"        id:9606,\n" +
-"        name:\"Homo Sapiens\"\n" +
-"        }\n" +
-"        ],\n" +
-"proteins:[\n" +
-"        {\n" +
-"        label:\"NSP3\",\n" +
-"        description:\"Rotavirus Non Structural Protein 3\",\n" +
-"        organism-id: 10929,\n" +
-"        acc: \"ACB38353\"\n" +
-"        },\n" +
-"        {\n" +
-"        label:\"EIF4G\",\n" +
-"        description:\"eukaryotic translation initiation factor 4 gamma\",\n" +
-"        organism-id: 9606,\n" +
-"        boolflag: true,\n" +
-"        longFloat: 12351123.1235123e-10,\n" +                
-"        singleQuote: \'asd\',\n" +                                
-"        acc:\"AAI40897\"\n" +
-"        }\n" +
-"        ],\n" +
-"interactions:[\n" +
-"        {\n" +
-"        label:\"NSP3 interacts with EIF4G1\",\n" +
-"        pubmed-id:[77120248,38201627],\n" +
-"        proteins:[\"ACB38353\",\"AAI40897\"]\n" +
-"        }\n" +
-"        ]}";
-        
-        data[1][0] = "{\"name\":\"com.example:type=QueueSampler\",\"exec\":\"testMethod1\",\"params\":[[1,2,3],\"abc\",5,[\"asd\",\"3\",\"67\",\"778\"],[{date:\"2016-3-2\",size:3,head:\"head\"}],[{date:\"2016-3-2\",size:3,head:\"head\"}]]}";
-        return data;
-    }
-    
-    @Test (dataProvider = "getJsonString")
-    public void parserTest(String input) throws ParseException {
-        JSONParser jsonParser = new JSONParser(input);
-        JSONElement parse = jsonParser.parse();
-        String output = parse.toJsonString();
-        System.out.println("\t: " + input);
-        System.out.println("\t: " + output);
-//        Assert.assertEquals(input, output);
-    }
-}
--- a/test/javax/management/remote/rest/PlatformAdapterTest.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.security.KeyStore;
-import java.security.cert.Certificate;
-import java.util.Base64;
-import java.util.Properties;
-import javax.management.remote.rest.JmxRestAdapter;
-import javax.management.remote.rest.PlatformRestAdapter;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.TrustManagerFactory;
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeClass;
-
-/**
- * @test 
- * @modules java.management.rest
- * @run testng/othervm PlatformAdapterTest
- */
-@Test
-public class PlatformAdapterTest {
-
-    private static final String MBEANS = "mbeans";
-    private static String sslAgentConfig;
-    private static String sslClientConfig;
-    private static String passwordFile;
-    
-
-    @BeforeClass
-    public void setup() throws IOException {
-        String testSrcRoot = System.getProperty("test.src") + File.separator;
-        sslAgentConfig = testSrcRoot + "sslConfigAgent";
-        sslClientConfig = testSrcRoot + "sslConfigClient";
-        passwordFile = testSrcRoot + "password.properties";
-        createAgentSslConfigFile(sslAgentConfig);
-        createClientSslConfigFile(sslClientConfig);
-    }
-    
-    @Test
-    public void testHttpNoAuth() throws Exception {
-        Properties props = new Properties();
-        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
-        props.setProperty("com.sun.management.jmxremote.ssl", "false");
-        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        adapter.start();
-        URL url = new URL(adapter.getBaseUrl() + MBEANS);
-        HttpURLConnection con = (HttpURLConnection) url.openConnection();
-        con.setDoOutput(false);
-        print_content(con);
-        PlatformRestAdapter.stop();
-    }
-
-    @Test
-    public void testHttpAuth() throws Exception {
-        Properties props = new Properties();
-        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
-        props.setProperty("com.sun.management.jmxremote.ssl", "false");
-        props.setProperty("com.sun.management.jmxremote.authenticate", "true");
-        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        adapter.start();
-        URL url = new URL(adapter.getBaseUrl() + MBEANS);
-        HttpURLConnection con = (HttpURLConnection) url.openConnection();
-        con.setDoOutput(false);
-
-        String userCredentials = "username1:password1";
-
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        con.setRequestProperty("Authorization", basicAuth);
-        print_content(con);
-
-        PlatformRestAdapter.stop();
-    }
-
-    private void createAgentSslConfigFile(String fileName) throws IOException {
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
-        props.setProperty("javax.net.ssl.trustStorePassword","glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void createClientSslConfigFile(String fileName) throws IOException {
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
-        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    @Test
-    public void testHttpsNoAuth() throws Exception {
-        Properties props = new Properties();
-        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
-        props.setProperty("com.sun.management.jmxremote.ssl", "true");
-        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
-        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        adapter.start();
-        SSLContext ctx = getSSlContext(sslClientConfig);
-        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
-
-        URL url = new URL(adapter.getBaseUrl() + MBEANS);
-        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-        con.setDoOutput(false);
-        print_https_cert(con);
-        print_content(con);
-        PlatformRestAdapter.stop();
-    }
-
-    @Test
-    public void testHttpsAuth() throws Exception {
-        Properties props = new Properties();
-        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
-        props.setProperty("com.sun.management.jmxremote.ssl", "true");
-        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
-        props.setProperty("com.sun.management.jmxremote.authenticate", "true");
-        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        adapter.start();
-        SSLContext ctx = getSSlContext(sslClientConfig);
-        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
-
-        URL url = new URL(adapter.getBaseUrl() + MBEANS);
-        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-        con.setDoOutput(false);
-
-        String userCredentials = "username1:password1";
-
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        con.setRequestProperty("Authorization", basicAuth);
-        print_https_cert(con);
-        print_content(con);
-        PlatformRestAdapter.stop();
-    }
-
-    private void print_content(HttpURLConnection con) {
-        if (con != null) {
-            try {
-                System.out.println("****** Content of the URL ********");
-                int status = con.getResponseCode();
-                System.out.println("Status = " + status);
-                BufferedReader br
-                        = new BufferedReader(
-                                new InputStreamReader(con.getInputStream()));
-                String input;
-                while ((input = br.readLine()) != null) {
-                    System.out.println(input);
-                }
-                br.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private void print_https_cert(HttpsURLConnection con) {
-        if (con != null) {
-            try {
-                System.out.println("Response Code : " + con.getResponseCode());
-                System.out.println("Cipher Suite : " + con.getCipherSuite());
-                System.out.println("\n");
-
-                Certificate[] certs = con.getServerCertificates();
-                for (Certificate cert : certs) {
-                    System.out.println("Cert Type : " + cert.getType());
-                    System.out.println("Cert Hash Code : " + cert.hashCode());
-                    System.out.println("Cert Public Key Algorithm : "
-                            + cert.getPublicKey().getAlgorithm());
-                    System.out.println("Cert Public Key Format : "
-                            + cert.getPublicKey().getFormat());
-                    System.out.println("\n");
-                }
-
-            } catch (SSLPeerUnverifiedException e) {
-                e.printStackTrace();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private static SSLContext getSSlContext(String sslConfigFileName) {
-        String keyStore, keyStorePassword, trustStore, trustStorePassword;
-        System.out.println("SSL Config file : " + sslConfigFileName);
-
-        try {
-            Properties p = new Properties();
-            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
-            p.load(bin);
-            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
-            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
-            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
-            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
-
-            char[] keyStorePasswd = null;
-            if (keyStorePassword.length() != 0) {
-                keyStorePasswd = keyStorePassword.toCharArray();
-            }
-
-            char[] trustStorePasswd = null;
-            if (trustStorePassword.length() != 0) {
-                trustStorePasswd = trustStorePassword.toCharArray();
-            }
-
-            KeyStore ks = null;
-            if (keyStore != null) {
-                ks = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream ksfis = new FileInputStream(keyStore);
-                ks.load(ksfis, keyStorePasswd);
-
-            }
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
-                    KeyManagerFactory.getDefaultAlgorithm());
-            kmf.init(ks, keyStorePasswd);
-
-            KeyStore ts = null;
-            if (trustStore != null) {
-                ts = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream tsfis = new FileInputStream(trustStore);
-                ts.load(tsfis, trustStorePasswd);
-            }
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-                    TrustManagerFactory.getDefaultAlgorithm());
-            tmf.init(ts);
-
-            SSLContext ctx = SSLContext.getInstance("SSL");
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            return ctx;
-        } catch (Exception ex) {
-        }
-        return null;
-    }
-}
--- a/test/javax/management/remote/rest/PlatformMBeanTest.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package javax.management.remote.rest.test;
-
-import javax.management.remote.rest.JmxRestAdapter;
-import javax.management.remote.rest.PlatformRestAdapter;
-import javax.management.remote.rest.json.JSONArray;
-import javax.management.remote.rest.json.JSONElement;
-import javax.management.remote.rest.json.JSONObject;
-import javax.management.remote.rest.json.JSONPrimitive;
-import javax.management.remote.rest.json.parser.JSONParser;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.security.KeyStore;
-import java.util.Base64;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.management.remote.rest.JmxRestAdapter;
-import javax.management.remote.rest.PlatformRestAdapter;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-/**
- *
- * @author harsha
- */
-public class PlatformMBeanTest {
-
-    private static SSLContext getSSlContext(String sslConfigFileName) {
-        final String keyStore, keyStorePassword, trustStore, trustStorePassword;
-
-        try {
-            Properties p = new Properties();
-            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
-            p.load(bin);
-            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
-            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
-            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
-            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
-
-            char[] keyStorePasswd = null;
-            if (keyStorePassword.length() != 0) {
-                keyStorePasswd = keyStorePassword.toCharArray();
-            }
-
-            char[] trustStorePasswd = null;
-            if (trustStorePassword.length() != 0) {
-                trustStorePasswd = trustStorePassword.toCharArray();
-            }
-
-            KeyStore ks = null;
-            if (keyStore != null) {
-                ks = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream ksfis = new FileInputStream(keyStore);
-                ks.load(ksfis, keyStorePasswd);
-
-            }
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
-                    KeyManagerFactory.getDefaultAlgorithm());
-            kmf.init(ks, keyStorePasswd);
-
-            KeyStore ts = null;
-            if (trustStore != null) {
-                ts = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream tsfis = new FileInputStream(trustStore);
-                ts.load(tsfis, trustStorePasswd);
-            }
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-                    TrustManagerFactory.getDefaultAlgorithm());
-            tmf.init(ts);
-
-            SSLContext ctx = SSLContext.getInstance("SSL");
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            return ctx;
-        } catch (Exception ex) {
-            Logger.getLogger(PlatformRestAdapter.class.getName()).log(Level.SEVERE, null, ex);
-        }
-        return null;
-    }
-
-    private static final String CHARSET = "UTF-8";
-
-    private String getFilePath(String filename) {
-        return System.getProperty("user.dir") + File.separator + filename;
-    }
-
-    @BeforeClass
-    public void setupAdapter() throws Exception {
-        File file = new File(getFilePath("management.properties"));
-        Properties props = new Properties();
-        props.load(new FileInputStream(file));
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-        PlatformRestAdapter.getInstance().start();
-        SSLContext ctx = getSSlContext(getFilePath("sslconfigClient"));
-        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
-    }
-
-    @AfterClass
-    public void tearDown() {
-        PlatformRestAdapter.stop();
-    }
-
-    private String executeHttpGetRequest(String inputUrl) throws MalformedURLException, IOException {
-        if (inputUrl != null && !inputUrl.isEmpty()) {
-            JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-            URL url = new URL(adapter.getBaseUrl() + inputUrl);
-            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-            con.setDoOutput(false);
-            String userCredentials = "username1:password1";
-            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-            con.setRequestProperty("Authorization", basicAuth);
-            try {
-                int status = con.getResponseCode();
-                if (status == 200) {
-
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(con.getInputStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(URLDecoder.decode(input, CHARSET));
-                        }
-                    }
-                    return sbuf.toString();
-                } else {
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(con.getErrorStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(URLDecoder.decode(input, CHARSET));
-                        }
-                    }
-                    return sbuf.toString();
-                }
-            } catch (IOException e) {
-            }
-        }
-        return null;
-    }
-
-    private String executeHttpPostRequest(String postBody) throws MalformedURLException, IOException {
-        if (postBody != null && !postBody.isEmpty()) {
-            JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-            URL url = new URL(adapter.getBaseUrl());
-            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
-            connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
-            connection.setDoOutput(true);
-            connection.setRequestMethod("POST");
-            String userCredentials = "username1:password1";
-            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-            connection.setRequestProperty("Authorization", basicAuth);
-            try (OutputStreamWriter out = new OutputStreamWriter(
-                    connection.getOutputStream(), CHARSET)) {
-                out.write(URLEncoder.encode(postBody, CHARSET));
-                out.flush();
-            }
-            try {
-                int status = connection.getResponseCode();
-                if (status == 200) {
-
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(connection.getInputStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(URLDecoder.decode(input, CHARSET));
-                        }
-                    }
-                    return sbuf.toString();
-                } else {
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(connection.getErrorStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(URLDecoder.decode(input, CHARSET));
-                        }
-                    }
-                    return sbuf.toString();
-                }
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        return null;
-    }
-
-    @Test
-    public void testOperatingSystemMbean() throws Exception {
-        //  Get MBeanInfo
-        String osMbeanInfo = executeHttpGetRequest("java.lang:type=OperatingSystem");
-        System.out.println(osMbeanInfo);
-
-        // Read all attributes
-        JSONParser parser = new JSONParser(osMbeanInfo);
-        JSONObject docRoot = (JSONObject) parser.parse();
-        JSONArray attrJson = (JSONArray) ((JSONObject) docRoot.get("response")).get("attributeInfo");
-        for (JSONElement elem : attrJson) {
-            JSONObject attrElem = (JSONObject) elem;
-            JSONPrimitive a = (JSONPrimitive) attrElem.get("name");
-            JSONPrimitive access = (JSONPrimitive) attrElem.get("access");
-            String attrResponse = executeHttpGetRequest("java.lang:type=OperatingSystem/" + a.getValue());
-            parser = new JSONParser(attrResponse);
-            docRoot = (JSONObject) parser.parse();
-            JSONPrimitive result = (JSONPrimitive) ((JSONObject) docRoot.get("response")).get(a.getValue());
-            System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - " + result.getValue());
-        }
-    }
-
-    @Test
-    public void testHotSpotDiagMBean() throws Exception {
-        String mbeanName = "com.sun.management:type=HotSpotDiagnostic";
-        String osMbeanInfo = executeHttpGetRequest(mbeanName);
-        System.out.println(osMbeanInfo);
-
-        // Read all attributes
-        JSONParser parser = new JSONParser(osMbeanInfo);
-        JSONObject docRoot = (JSONObject) parser.parse();
-        JSONArray attrJson = (JSONArray) ((JSONObject) docRoot.get("response")).get("attributeInfo");
-        if (attrJson != null) {
-            for (JSONElement elem : attrJson) {
-                JSONObject attrElem = (JSONObject) elem;
-                JSONPrimitive a = (JSONPrimitive) attrElem.get("name");
-                JSONPrimitive access = (JSONPrimitive) attrElem.get("access");
-                String attrResponse = executeHttpGetRequest(mbeanName + "/" + a.getValue());
-                parser = new JSONParser(attrResponse);
-                docRoot = (JSONObject) parser.parse();
-                JSONObject response = (JSONObject) docRoot.get("response");
-                if (response != null) {
-                    JSONElement get = response.get(a.getValue());
-                    System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - " + get.toJsonString());
-                } else {
-                    System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - null");
-                }
-            }
-        }
-
-        String dumpHeap = "{\n"
-                + "  \"name\": \"com.sun.management:type=HotSpotDiagnostic\",\n"
-                + "  \"exec\": \"dumpHeap\",\n"
-                + "  \"arguments\": [\n"
-                + "			\"heapdump.hprof\",\n"
-                + "			false\n"
-                + "		]\n"
-                + "}";
-
-        String responseJson = executeHttpPostRequest(dumpHeap);
-        parser = new JSONParser(responseJson);
-        docRoot = (JSONObject) parser.parse();
-        JSONElement response = docRoot.get("response");
-        System.out.println(" DumpHeap op - " + (response != null ? response.toJsonString() : null));
-
-        String getVmOption = "{\n"
-                + "  \"name\": \"com.sun.management:type=HotSpotDiagnostic\",\n"
-                + "  \"exec\": \"getVMOption\",\n"
-                + "  \"arguments\": [\n"
-                + "	\"PrintGCDetails\"\n"
-                + "	]\n"
-                + "}";
-        responseJson = executeHttpPostRequest(getVmOption);
-        parser = new JSONParser(responseJson);
-        docRoot = (JSONObject) parser.parse();
-        response = docRoot.get("response");
-        System.out.println(" DumpHeap op - " + (response != null ? response.toJsonString() : null));
-    }
-}
--- a/test/javax/management/remote/rest/RestAdapterSSLTest.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,484 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.security.KeyStore;
-import java.security.cert.Certificate;
-import java.util.Base64;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.remote.rest.JmxRestAdapter;
-import javax.management.remote.rest.PlatformRestAdapter;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.TrustManagerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * @test
- * @modules java.logging
- *          java.management
- *          java.management.rest
- * @run testng/othervm RestAdapterSSLTest
- * 
- */
-@Test
-public class RestAdapterSSLTest {
-
-    private static final String CHARSET = "UTF-8";
-    private static String sslAgentConfig;
-    private static String sslClientConfig;
-    private static String passwordFile;
-    private static String configFile;
-
-    private void createAgentSslConfigFile(String fileName) throws IOException {
-        File f = new File(fileName);
-        if (f.exists()) {
-            return;
-        }
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
-        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void createClientSslConfigFile(String fileName) throws IOException {
-        File f = new File(fileName);
-        if (f.exists()) {
-            return;
-        }
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
-        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void setupMgmtConfig(String fileName) throws IOException {
-        Properties props = new Properties();
-        
-        props.setProperty("com.sun.management.jmxremote.ssl", "true");
-        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
-        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
-        props.setProperty("com.sun.management.jmxremote.rest.port", "0");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void setupConfig() throws Exception {
-        String testSrcRoot = System.getProperty("test.src") + File.separator;
-        sslAgentConfig = testSrcRoot + "sslConfigAgent";
-        sslClientConfig = testSrcRoot + "sslConfigClient";
-        passwordFile = testSrcRoot + "password.properties";
-        configFile = testSrcRoot + "mgmt.properties";
-        createAgentSslConfigFile(sslAgentConfig);
-        createClientSslConfigFile(sslClientConfig);
-        setupMgmtConfig(configFile);
-    }
-
-    @BeforeClass
-    public void setupAdapter() throws Exception {
-        setupConfig();
-        File file = new File(configFile);
-        Properties props = new Properties();
-        props.load(new FileInputStream(file));
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-        PlatformRestAdapter.getInstance().start();
-        SSLContext ctx = getSSlContext(sslClientConfig);
-        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
-        setupMbean();
-    }
-
-    @AfterClass
-    public void tearDown() {
-        PlatformRestAdapter.stop();
-    }
-
-    @DataProvider
-    public Object[][] getUrlList() {
-        Object[][] data = new Object[7][1];
-        data[0][0] = "?domain=default";
-        data[1][0] = "mbeans";
-        data[2][0] = "domains";
-        data[3][0] = "java.lang:type=Memory";
-        data[4][0] = "java.lang:type=Memory/HeapMemoryUsage";
-        data[5][0] = "java.lang:type=Memory/?attributes=HeapMemoryUsage,ObjectPendingFinalizationCount,NonHeapMemoryUsage";
-        data[6][0] = "java.lang:type=Memory/?attributes=all";
-        return data;
-    }
-
-    @DataProvider
-    public Object[][] getMalformedUrlList() {
-        Object[][] data = new Object[1][1];
-        data[0][0] = "com.example:type=QueueSamplerMBean";
-        return data;
-    }
-
-    private String executeHttpRequest(String inputUrl) throws IOException {
-        return executeHttpRequest(inputUrl, null);
-    }
-
-    private String executeHttpRequest(String inputUrl, String charset) throws IOException {
-        if (inputUrl != null && !inputUrl.isEmpty()) {
-            JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-            URL url = new URL(adapter.getBaseUrl() + (charset != null ? URLEncoder.encode(inputUrl, charset) : inputUrl));
-            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-            con.setDoOutput(false);
-            String userCredentials = "username1:password1";
-            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-            con.setRequestProperty("Authorization", basicAuth);
-            if (charset != null && !charset.isEmpty()) {
-                con.setRequestProperty("Content-Type", "application/json; charset=" + charset);
-            }
-            try {
-                int status = con.getResponseCode();
-                if (status == 200) {
-
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(con.getInputStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
-                        }
-                    }
-                    return sbuf.toString();
-                } else {
-                    StringBuilder sbuf;
-                    try (BufferedReader br = new BufferedReader(
-                            new InputStreamReader(con.getErrorStream()))) {
-                        sbuf = new StringBuilder();
-                        String input;
-                        while ((input = br.readLine()) != null) {
-                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
-                        }
-                    }
-                    return sbuf.toString();
-                }
-            } catch (IOException e) {
-            }
-        }
-        return null;
-    }
-
-    @Test
-    public void testMisc() throws IOException, ParseException {
-        String mBeanInfo = executeHttpRequest("com.sun.management:type=DiagnosticCommand");
-        System.out.println(mBeanInfo);
-        JSONParser parser = new JSONParser(mBeanInfo);
-        JSONObject response = (JSONObject) parser.parse();
-        long status = (Long) ((JSONPrimitive) response.get("status")).getValue();
-        Assert.assertEquals(status, 200);
-    }
-
-    @Test(enabled = false)
-    public void testCharset() throws IOException {
-        String result1 = executeHttpRequest("?domain=default");
-        String result2 = executeHttpRequest("?domain=default", CHARSET);
-        Assert.assertEquals(result1, result2);
-    }
-
-    @Test
-    public void testPostMisc() throws IOException {
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        URL url = new URL(adapter.getBaseUrl());
-        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
-        connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
-        connection.setDoOutput(true);
-        connection.setRequestMethod("POST");
-        String userCredentials = "username1:password1";
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        connection.setRequestProperty("Authorization", basicAuth);
-
-        String req = "{\n"
-                + "    \"name\":\"java.lang:type=Memory\"\n"
-                + "    \"write\":\"Verbose\"\n"
-                + "    \"arguments\" : [true]\n"
-                + "}";
-        try (OutputStreamWriter out = new OutputStreamWriter(
-                connection.getOutputStream(), CHARSET)) {
-            out.write(URLEncoder.encode(req, CHARSET));
-            out.flush();
-        }
-
-        print_content(connection);
-    }
-
-    @Test
-    public void testBasicHttps() throws Exception {
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        URL url = new URL(adapter.getBaseUrl());
-        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-        con.setDoOutput(false);
-
-        String userCredentials = "username1:password1";
-
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        con.setRequestProperty("Authorization", basicAuth);
-        print_https_cert(con);
-        print_content(con);
-    }
-
-    @Test(dataProvider = "getUrlList")
-    public void testGetRequests(String urlStr) throws Exception {
-        String input = executeHttpRequest(urlStr);
-        System.out.println("URL : [" + urlStr + "] ----> " + input);
-        System.out.println(input);
-        JSONParser parser = new JSONParser(input);
-        JSONElement parse = parser.parse();
-        JSONElement jstatus = ((JSONObject) parse).get("status");
-        long status = (Long) ((JSONPrimitive) jstatus).getValue();
-        Assert.assertEquals(status, 200);
-    }
-
-    @Test
-    public void testAllGetMBeanInfo() throws Exception {
-        String input = executeHttpRequest("mbeans");
-        JSONParser parser = new JSONParser(input);
-        JSONElement jsonObj = parser.parse();
-        if (jsonObj instanceof JSONObject) {
-            JSONElement jelem = ((JSONObject) jsonObj).get("response");
-            if (jelem instanceof JSONArray) {
-                for (JSONElement elem : ((JSONArray) jelem)) {
-                    String objName = (String) ((JSONPrimitive) elem).getValue();
-                    String mBeanInfo = executeHttpRequest(objName);
-                    System.out.println(mBeanInfo);
-                    parser = new JSONParser(mBeanInfo);
-                    JSONObject response = (JSONObject) parser.parse();
-                    long status = (Long) ((JSONPrimitive) response.get("status")).getValue();
-                    Assert.assertEquals(status, 200);
-                }
-            }
-        }
-    }
-
-    @Test(enabled = false, dataProvider = "getMalformedUrlList")
-    public void negTestGetRequests(String urlStr) throws Exception {
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        URL url = new URL(adapter.getBaseUrl() + urlStr);
-        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
-        con.setDoOutput(false);
-        String userCredentials = "username1:password1";
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        con.setRequestProperty("Authorization", basicAuth);
-        print_content(con);
-    }
-
-    @Test
-    public void testPost() throws Exception {
-        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
-        URL url = new URL(adapter.getBaseUrl());
-        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
-        connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
-        connection.setDoOutput(true);
-        connection.setRequestMethod("POST");
-        String userCredentials = "username1:password1";
-        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
-        connection.setRequestProperty("Authorization", basicAuth);
-
-        String postReq = "{\"name\":\"com.example:type=QueueSampler\",\"exec\":\"testMethod1\",\"arguments\":[[1,2,3],\"abc\",5,[\"asd\",\"3\",\"67\",\"778\"],[{date:\"2016-03-02\",size:3,head:\"head\"}],[{date:\"2016-03-02\",size:3,head:\"head\"}]]}";
-        JSONArray jarr = new JSONArray();
-
-        JSONObject jobject = new JSONObject();
-        jobject.put("name", "com.example:type=QueueSampler");
-        jobject.put("write", "QueueName");
-        JSONArray jarr1 = new JSONArray();
-        jarr1.add(new JSONPrimitive("Dequeue"));
-        jobject.put("arguments", jarr1);
-        jarr.add(jobject);
-
-        jobject = new JSONObject();
-        jobject.put("name", "com.example:type=QueueSampler");
-        jobject.put("read", "QueueName");
-        jarr.add(jobject);
-
-        jarr.add(new JSONParser(postReq).parse());
-
-        try (OutputStreamWriter out = new OutputStreamWriter(
-                connection.getOutputStream(), CHARSET)) {
-            out.write(URLEncoder.encode(jarr.toJsonString(), CHARSET));
-            out.flush();
-        }
-        print_content(connection);
-    }
-
-    @Test(enabled = false)
-    public void testMBeanFilter() throws MalformedObjectNameException {
-        // Add non-compliant MBean to platform mbean server
-        ObjectName mbeanName = new ObjectName("com.example:type=QueueSamplerMBean");
-    }
-
-    private void setupMbean() throws Exception {
-        // Get the Platform MBean Server
-//        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-//
-//        // Construct the ObjectName for the QueueSampler MXBean we will register
-//        ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler");
-//        ObjectName mbeanName = new ObjectName("com.example:type=QueueSamplerMBean");
-//
-//        // Create the Queue Sampler MXBean
-//        Queue<String> queue = new ArrayBlockingQueue<>(10);
-//        queue.add("Request-1");
-//        queue.add("Request-2");
-//        queue.add("Request-3");
-//        QueueSampler mxbean = new QueueSampler(queue);
-//        QueueSamplerBean mbean = new QueueSamplerBean(queue);
-//
-//        // Register the Queue Sampler MXBean
-//        mbs.registerMBean(mxbean, mxbeanName);
-//        mbs.registerMBean(mbean, mbeanName);
-    }
-
-    private void print_content(HttpURLConnection con) {
-        if (con != null) {
-            try {
-                System.out.println("****** Content of the URL ********");
-                int status = con.getResponseCode();
-
-                System.out.println("Status = " + status);
-                InputStream is;
-                if (status == HttpURLConnection.HTTP_OK) {
-                    is = con.getInputStream();
-                } else {
-                    is = con.getErrorStream();
-                }
-                BufferedReader br
-                        = new BufferedReader(new InputStreamReader(is));
-                String input;
-                while ((input = br.readLine()) != null) {
-                    System.out.println(URLDecoder.decode(input, CHARSET));
-                }
-                br.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private void print_https_cert(HttpsURLConnection con) {
-        if (con != null) {
-            try {
-                System.out.println("Response Code : " + con.getResponseCode());
-                System.out.println("Cipher Suite : " + con.getCipherSuite());
-                System.out.println("\n");
-
-                Certificate[] certs = con.getServerCertificates();
-                for (Certificate cert : certs) {
-                    System.out.println("Cert Type : " + cert.getType());
-                    System.out.println("Cert Hash Code : " + cert.hashCode());
-                    System.out.println("Cert Public Key Algorithm : "
-                            + cert.getPublicKey().getAlgorithm());
-                    System.out.println("Cert Public Key Format : "
-                            + cert.getPublicKey().getFormat());
-                    System.out.println("\n");
-                }
-
-            } catch (SSLPeerUnverifiedException e) {
-                e.printStackTrace();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private static SSLContext getSSlContext(String sslConfigFileName) {
-        final String keyStore, keyStorePassword, trustStore, trustStorePassword;
-
-        try {
-            Properties p = new Properties();
-            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
-            p.load(bin);
-            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
-            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
-            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
-            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
-
-            char[] keyStorePasswd = null;
-            if (keyStorePassword.length() != 0) {
-                keyStorePasswd = keyStorePassword.toCharArray();
-            }
-
-            char[] trustStorePasswd = null;
-            if (trustStorePassword.length() != 0) {
-                trustStorePasswd = trustStorePassword.toCharArray();
-            }
-
-            KeyStore ks = null;
-            if (keyStore != null) {
-                ks = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream ksfis = new FileInputStream(keyStore);
-                ks.load(ksfis, keyStorePasswd);
-
-            }
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
-                    KeyManagerFactory.getDefaultAlgorithm());
-            kmf.init(ks, keyStorePasswd);
-
-            KeyStore ts = null;
-            if (trustStore != null) {
-                ts = KeyStore.getInstance(KeyStore.getDefaultType());
-                FileInputStream tsfis = new FileInputStream(trustStore);
-                ts.load(tsfis, trustStorePasswd);
-            }
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-                    TrustManagerFactory.getDefaultAlgorithm());
-            tmf.init(ts);
-
-            SSLContext ctx = SSLContext.getInstance("SSL");
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            return ctx;
-        } catch (Exception ex) {
-            Logger.getLogger(PlatformRestAdapter.class.getName()).log(Level.SEVERE, null, ex);
-        }
-        return null;
-    }
-}
--- a/test/javax/management/remote/rest/RunRestAdapter.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Properties;
-import javax.management.remote.rest.PlatformRestAdapter;
-
-
-/**
- * @test
- * @modules java.logging
- *          java.management.rest
- * @run main RunRestAdapter
- */
-public class RunRestAdapter {
-
-    private static String sslAgentConfig;
-    private static String sslClientConfig;
-    private static String configFile;
-
-    public static void main(String[] args) throws Exception {
-        RunRestAdapter rr = new RunRestAdapter();
-        rr.run();
-    }
-
-    private void createAgentSslConfigFile(String fileName) throws IOException {
-        File f = new File(fileName);
-        if (f.exists()) {
-            return;
-        }
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
-        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void createClientSslConfigFile(String fileName) throws IOException {
-        File f = new File(fileName);
-        if (f.exists()) {
-            return;
-        }
-        Properties props = new Properties();
-        String testDir = System.getProperty("test.src");
-        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
-        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
-        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
-        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void setupMgmtConfig(String fileName) throws IOException {
-        Properties props = new Properties();
-        props.setProperty("com.sun.management.jmxremote.ssl", "true");
-        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
-        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
-        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
-
-        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
-            props.store(writer, "");
-        }
-    }
-
-    private void setupConfig() throws Exception {
-        String testSrcRoot = System.getProperty("test.src") + File.separator;
-        sslAgentConfig = testSrcRoot + "sslConfigAgent";
-        sslClientConfig = testSrcRoot + "sslConfigClient";
-
-        configFile = testSrcRoot + "mgmt1.properties";
-        createAgentSslConfigFile(sslAgentConfig);
-        createClientSslConfigFile(sslClientConfig);
-        setupMgmtConfig(configFile);
-    }
-
-    public void run() throws Exception {
-        setupConfig();
-        File file = new File(configFile);
-        Properties props = new Properties();
-        props.load(new FileInputStream(file));
-        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
-            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
-        }
-        PlatformRestAdapter.getInstance().start();
-        Thread.sleep(1000000);
-    }
-}
--- a/test/javax/management/remote/rest/data/QueueSample.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-package javax.management.remote.rest.test.data;
-
-/*
- * QueueSample.java - Java type representing a snapshot of a given queue.
- * It bundles together the instant time the snapshot was taken, the queue
- * size and the queue head.
- */
-
-
-
-import java.beans.ConstructorProperties;
-import java.util.Date;
-
-public class QueueSample {
-    
-    private final Date date;
-    private final int size;
-    private final String head;
-
-    @ConstructorProperties({"date", "size", "head"})
-    public QueueSample(Date date, int size, String head) {
-        this.date = date;
-        this.size = size;
-        this.head = head;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public int getSize() {
-        return size;
-    }
-
-    public String getHead() {
-        return head;
-    }
-}
--- a/test/javax/management/remote/rest/data/QueueSampler.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-package javax.management.remote.rest.test.data;
-
-/*
- * QueueSampler.java - MXBean implementation for the QueueSampler MXBean.
- * This class must implement all the Java methods declared in the
- * QueueSamplerMXBean interface, with the appropriate behavior for each one.
- */
-
-
-import java.util.Date;
-import java.util.List;
-import java.util.Queue;
-
-public class QueueSampler implements QueueSamplerMXBean {
-
-    private Queue<String> queue;
-    private QueueSample sample;
-    private String name;
-
-    public QueueSampler(Queue<String> queue) {
-        this.queue = queue;
-        synchronized (queue) {
-            sample = new QueueSample(new Date(), queue.size(), queue.peek());
-        }
-        name = "BoogeyMan";
-    }
-
-    public QueueSample getQueueSample() {
-        return sample;
-    }
-    
-    public void clearQueue() {
-        synchronized (queue) {
-            queue.clear();
-        }
-    }
-
-    @Override
-    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5) {
-        System.out.println("########## Invoke TestMethod1");
-        return new String[]{"1","2","3","4","5"};
-    }
-
-    @Override
-    public void setQueueSample(QueueSample sample) {
-        this.sample = sample;
-    }
-
-    @Override
-    public String getQueueName() {
-        return name;
-    }
-
-    @Override
-    public void setQueueName(String name) {
-        this.name = name;
-    }
-}
--- a/test/javax/management/remote/rest/data/QueueSamplerBean.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package javax.management.remote.rest.test.data;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Queue;
-
-/**
- *
- * @author harsha
- */
-public class QueueSamplerBean implements QueueSamplerBeanMBean {
-
-    private Queue<String> queue;
-    private QueueSample sample;
-    private String name;
-
-    public QueueSamplerBean(Queue<String> queue) {
-        this.queue = queue;
-        synchronized (queue) {
-            sample = new QueueSample(new Date(), queue.size(), queue.peek());
-        }
-        name = "BoogeyMan";
-    }
-
-    public QueueSample getQueueSample() {
-        return sample;
-    }
-    
-    public void clearQueue() {
-        synchronized (queue) {
-            queue.clear();
-        }
-    }
-
-    @Override
-    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5) {
-        return new String[]{"1","2","3","4","5"};
-    }
-
-    @Override
-    public void setQueueSample(QueueSample sample) {
-        this.sample = sample;
-    }
-
-    @Override
-    public String getQueueName() {
-        return name;
-    }
-
-    @Override
-    public void setQueueName(String name) {
-        this.name = name;
-    }    
-}
--- a/test/javax/management/remote/rest/data/QueueSamplerBeanMBean.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package javax.management.remote.rest.test.data;
-
-import java.util.List;
-
-/**
- *
- * @author harsha
- */
-public interface QueueSamplerBeanMBean {
-        public QueueSample getQueueSample();
-    
-    public void setQueueSample(QueueSample sample);
-
-    public String getQueueName();
-    
-    public void setQueueName(String name);
-    
-    public void clearQueue();
-
-    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5);
-}
--- a/test/javax/management/remote/rest/data/QueueSamplerMXBean.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-package javax.management.remote.rest.test.data;
-
-
-import java.util.List;
-
-public interface QueueSamplerMXBean {
-    
-    public QueueSample getQueueSample();
-    
-    public void setQueueSample(QueueSample sample);
-
-    public String getQueueName();
-    
-    public void setQueueName(String name);
-    
-    public void clearQueue();
-
-    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5);
-}
--- a/test/javax/management/remote/rest/json/JSONTest.java	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * @test @modules java.management.rest
- * @run main JSONTest
- */
-public class JSONTest {
-
-    public static void main(String[] args) throws ParseException {
-        JSONGraphGenerator graphGen = new JSONGraphGenerator(50);
-        JSONElement jElem = graphGen.generateJsonGraph(20000);
-        System.out.println("Graph Generated");
-        String str = jElem.toJsonString();
-        System.out.println(str);
-
-        JSONParser parser = new JSONParser(str);
-
-        com.oracle.jmx.remote.rest.json.JSONElement parse = parser.parse();
-        String resultJson = parse.toJsonString();
-        System.out.println(resultJson);
-    }
-}
-
-interface JSONElement {
-
-    String toJsonString();
-}
-
-interface Visitable {
-
-    public void accept(NodeVisitor visitor);
-}
-
-interface NodeVisitor {
-
-    public void visit(Node node);
-
-    //visit other concrete items
-    public void visit(Digit19 digit12);
-
-    public void visit(Digits dvd);
-}
-
-class Node implements Visitable {
-
-    final private String label;
-
-    public Node(String label) {
-        children = new LinkedList<>();
-        this.label = label;
-    }
-
-    public Node() {
-        this("");
-    }
-
-    public void add(Node node) {
-        if (!children.contains(node)) {
-            children.add(node);
-        }
-    }
-
-    public String getLabel() {
-        return label;
-    }
-    List<Node> children;
-
-    @Override
-    public void accept(NodeVisitor visitor) {
-        visitor.visit(this);
-    }
-}
-
-class Digit19 extends Node {
-
-    Random rnd = new Random();
-
-    public Digit19() {
-        super();
-    }
-
-    @Override
-    public String getLabel() {
-        return "" + (rnd.nextInt(9) + 1);
-    }
-}
-
-class Digits extends Node {
-
-    Random rnd = new Random();
-
-    public Digits() {
-        super();
-    }
-
-    @Override
-    public String getLabel() {
-        return "" + (rnd.nextInt(10));
-    }
-}
-
-class JSONNumberGenerator {
-
-    private final static Node root;
-    Number num;
-
-    static {
-        root = new Node("R");
-        Node minus1 = new Node("-");
-        Node zero = new Node("0");
-        Node digit19 = new Digit19();
-        Node digits1 = new Digits();
-        Node dot = new Node(".");
-        Node digits2 = new Digits();
-        Node e = new Node("e");
-        Node E = new Node("E");
-        Node plus = new Node("+");
-        Node minus2 = new Node("-");
-        Node digits3 = new Digits();
-        Node terminal = new Node("T");
-
-        root.add(zero);
-        root.add(minus1);
-        root.add(digit19);
-
-        minus1.add(zero);
-        minus1.add(digit19);
-
-        zero.add(dot);
-//        zero.add(e);
-//        zero.add(E);
-        zero.add(terminal);
-
-        digit19.add(dot);
-        digit19.add(digits1);
-//        digit19.add(e);
-//        digit19.add(E);
-        digit19.add(terminal);
-
-        digits1.add(dot);
-        digits1.add(digits1);
-//        digits1.add(e);
-//        digits1.add(E);
-        digits1.add(terminal);
-
-        dot.add(digits2);
-
-        digits2.add(digits2);
-        digits2.add(e);
-        digits2.add(E);
-        digits2.add(terminal);
-
-        e.add(plus);
-        e.add(minus2);
-        e.add(digits3);
-
-        E.add(plus);
-        E.add(minus2);
-        E.add(digits3);
-
-        plus.add(digits3);
-        minus2.add(digits3);
-
-        digits3.add(digits3);
-        digits3.add(terminal);
-    }
-
-    private static class NumberNodeVisitor implements NodeVisitor {
-
-        private final StringBuilder sbuf = new StringBuilder();
-        Random rnd = new Random();
-
-        public NumberNodeVisitor() {
-        }
-
-        @Override
-        public void visit(Node node) {
-            if (!node.getLabel().equals("R")) {
-                sbuf.append(node.getLabel());
-            }
-            if (node.children.size() > 0) {
-                Node child = node.children.get(rnd.nextInt(node.children.size()));
-                if (!child.getLabel().equals("T")) {
-                    visit(child);
-                }
-            } else {
-                System.out.println("Found node " + node.getLabel() + " with children : " + node.children.size());
-            }
-        }
-
-        @Override
-        public void visit(Digit19 digit12) {
-            sbuf.append(digit12.getLabel());
-            Node child = digit12.children.get(rnd.nextInt(digit12.children.size()));
-            if (!child.getLabel().equals("T")) {
-                visit(child);
-            }
-        }
-
-        @Override
-        public void visit(Digits digits) {
-            sbuf.append(digits.getLabel());
-            Node child = digits.children.get(rnd.nextInt(digits.children.size()));
-            if (!child.getLabel().equals("T")) {
-                visit(child);
-            }
-        }
-
-        public String getNumber() {
-            return sbuf.toString();
-        }
-
-    }
-
-    public String generate() {
-        NumberNodeVisitor visitor = new NumberNodeVisitor();
-        visitor.visit(root);
-        // System.out.println(visitor.getNumber());
-//        Double.parseDouble(visitor.getNumber());
-        return visitor.getNumber();
-    }
-}
-
-class TestJsonObject extends LinkedHashMap<String, JSONElement> implements JSONElement {
-
-    @Override
-    public String toJsonString() {
-        if (isEmpty()) {
-            return null;
-        }
-
-        StringBuilder sbuild = new StringBuilder();
-        sbuild.append("{");
-        keySet().forEach((elem) -> {
-            sbuild.append(elem).append(": ").
-                    append((get(elem) != null) ? get(elem).toJsonString() : "null").append(",");
-        });
-
-        sbuild.deleteCharAt(sbuild.lastIndexOf(","));
-        sbuild.append("}");
-        return sbuild.toString();
-    }
-}
-
-class TestJsonArray extends ArrayList<JSONElement> implements JSONElement {
-
-    @Override
-    public String toJsonString() {
-        if (isEmpty()) {
-            return null;
-        }
-        StringBuilder sbuild = new StringBuilder();
-        sbuild.append("[");
-        Iterator<JSONElement> itr = iterator();
-        while (itr.hasNext()) {
-            JSONElement val = itr.next();
-            if (val != null) {
-                sbuild.append(val.toJsonString()).append(", ");
-            } else {
-                sbuild.append("null").append(", ");
-            }
-        }
-
-        sbuild.deleteCharAt(sbuild.lastIndexOf(","));
-        sbuild.append("]");
-        return sbuild.toString();
-    }
-}
-
-class TestJsonPrimitive implements JSONElement {
-
-    private final String s;
-
-    public TestJsonPrimitive(String s) {
-        this.s = s;
-    }
-
-    @Override
-    public String toJsonString() {
-        return s;
-    }
-}
-
-class JSONStringGenerator {
-
-    private static final int minStringLength = 0;
-    private static final int maxStringLength = 10;
-
-    private final Random rnd = new Random(System.currentTimeMillis());
-
-    private static final String specials = "\b" + "\f" + "\n" + "\r" + "\t" + "\\" + "\"";    // TODO: Special characters '/', '\', '"', "\\uxxxx"
-    private static final String alphanums = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-    public String generate() {
-        char ch;
-        StringBuilder sbuf = new StringBuilder();
-        int len = minStringLength + rnd.nextInt(maxStringLength - minStringLength + 1);
-        sbuf.append("\"");
-        for (int i = 0; i < len; i++) {
-            if (rnd.nextInt(10) == 1) { // 1/10 chances of a control character
-                ch = specials.charAt(rnd.nextInt(specials.length()));
-            } else {
-//                ch = alphanums.charAt(rnd.nextInt(alphanums.length()));
-                ch = (char) rnd.nextInt(Character.MAX_VALUE + 1);
-            }
-            switch (ch) {
-                case '\"':
-                case '\\':
-                    sbuf.append('\\');
-            }
-            sbuf.append(ch);
-        }
-        sbuf.append("\"");
-        return sbuf.toString();
-    }
-}
-
-class JSONGraphGenerator {
-
-    JSONStringGenerator stringGen;
-    JSONNumberGenerator numGen;
-    private final int maxChildPerNode;
-    static Random rnd = new Random(System.currentTimeMillis());
-
-    public JSONGraphGenerator(int maxChildPerNode) {
-        this.maxChildPerNode = maxChildPerNode;
-        stringGen = new JSONStringGenerator();
-        numGen = new JSONNumberGenerator();
-    }
-
-    private TestJsonPrimitive generatePrimitiveData() {
-        int primitiveTypre = rnd.nextInt(10) + 1;
-        switch (primitiveTypre) {
-            case 1:
-            case 2:
-            case 3:
-            case 4:
-                return new TestJsonPrimitive(stringGen.generate());
-            case 5:
-            case 6:
-            case 7:
-            case 8:
-                return new TestJsonPrimitive(numGen.generate());
-            case 9:
-                return new TestJsonPrimitive(Boolean.toString(rnd.nextBoolean()));
-            case 10:
-                return null;
-        }
-        return null;
-    }
-
-    public TestJsonObject generateJsonObject(int size) {
-        TestJsonObject jobj = new TestJsonObject();
-        if (size <= maxChildPerNode) {
-            for (int i = 0; i < size; i++) {
-                jobj.put(stringGen.generate(), generatePrimitiveData());
-            }
-        } else {
-            int newSize = size;
-            do {
-                int childSize = rnd.nextInt(newSize);
-                jobj.put(stringGen.generate(), generateJsonGraph(childSize));
-                newSize = newSize - childSize;
-            } while (newSize > maxChildPerNode);
-            jobj.put(stringGen.generate(), generateJsonGraph(newSize));
-        }
-        return jobj;
-    }
-
-    public TestJsonArray generateJsonArray(int size) {
-        TestJsonArray array = new TestJsonArray();
-        if (size <= maxChildPerNode) {
-            for (int i = 0; i < size; i++) {
-                array.add(generatePrimitiveData());
-            }
-        } else if (size >= maxChildPerNode) {
-            int newSize = size;
-            do {
-                int childSize = rnd.nextInt(newSize);
-                array.add(generateJsonGraph(childSize));
-                newSize = newSize - childSize;
-            } while (newSize > maxChildPerNode);
-            array.add(generateJsonGraph(newSize));
-        }
-        return array;
-    }
-
-    public JSONElement generateJsonGraph(int size) {
-        if (rnd.nextBoolean()) {
-            return generateJsonArray(size);
-        } else {
-            return generateJsonObject(size);
-        }
-    }
-}
--- a/test/javax/management/remote/rest/management.properties	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-com.sun.management.jmxremote.ssl=true
-com.sun.management.jmxremote.ssl.config.file=sslconfig
-# com.sun.management.jmxremote.login.config=<config-name>
-com.sun.management.jmxremote.password.file=password.properties
-# com.sun.management.jmxremote.host=<host-or-interface-name>
-com.sun.management.jmxremote.rest.port=8686
--- a/test/javax/management/remote/rest/management1.properties	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-com.sun.management.jmxremote.ssl=true
-com.sun.management.jmxremote.ssl.config.file=/home/harsha/work/jdk10_rest/jdk/test/sun/management/jmxremote/rest/sslconfig
-# com.sun.management.jmxremote.login.config=<config-name>
-com.sun.management.jmxremote.authenticate=false
-com.sun.management.jmxremote.password.file=/home/harsha/work/jdk10_rest/jdk/test/sun/management/jmxremote/rest/password.properties
-# com.sun.management.jmxremote.host=<host-or-interface-name>
-com.sun.management.jmxremote.rest.port=8686
--- a/test/javax/management/remote/rest/password.properties	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-# Password file for default SQE username.
-SQE_username SQE_password
-
-# Functional authorization tests
-username1 password1
-username2 password2
-username3 password3
-username4 password4
-username5 password5
-username6 password6
-
-usernameFileLoginModule passwordFileLoginModule
--- a/test/javax/management/remote/rest/server.cer	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICKDCCAZECBEDtdcwwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCRlIxDjAM
-BgNVBAgTBUlzZXJlMREwDwYDVQQHEwhHcmVub2JsZTEMMAoGA1UEChMDU3VuMQ0w
-CwYDVQQLEwRKMlNFMQwwCgYDVQQDEwNKTVgwHhcNMDQwNzA4MTYyNjUyWhcNMzkw
-NjMwMTYyNjUyWjBbMQswCQYDVQQGEwJGUjEOMAwGA1UECBMFSXNlcmUxETAPBgNV
-BAcTCEdyZW5vYmxlMQwwCgYDVQQKEwNTdW4xDTALBgNVBAsTBEoyU0UxDDAKBgNV
-BAMTA0pNWDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnbqRH7+SCpPA2z06
-DCwDwVaJmkc5mg1nX1j8lebEnDY0OrwlZBikirt3m/cIUnRWLepIgaoFd6HfAIaP
-Lx7AyGqwEv0LqHjTo/hgehmi+oK9oJsMaDqCdIQ+Lb53Lo9ECHDHP84gkCgmQqy6
-EvKR16wiI46d9D8BDe7huIJaUGkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQARo5Fr
-4lFOzLDwUn9lH/3We+4wCbpzvHFOZBKUizv+rTk5oeZHQc+0yXHZMuzTUYShlTvK
-sYLXGUF9BahM2YFvLp40lnIfEYPlNptbJWceN5K2a41A0JoxmuoS2dhegzY6p4ED
-EpoEySMQZS3ZW2AsOQsozGW02E3GaJB7TI93gg==
------END CERTIFICATE-----
--- a/test/javax/management/remote/rest/sslconfig	Fri Sep 01 14:36:28 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-javax.net.ssl.keyStore=keystoreAgent
-javax.net.ssl.keyStorePassword=glopglop
-javax.net.ssl.trustStore=truststoreAgent
-javax.net.ssl.trustStorePassword=glopglop
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/DefaultRestAdapter.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+ /*
+ * @test
+ * @run main/othervm -Dcom.sun.management.jmxremote.rest.port=8686 -Dcom.sun.management.config.file=/home/harsha/work/jdk10_rest/jdk/test/javax/management/remote/rest/mgmt1.properties DefaultRestAdapter
+ */
+import java.io.IOException;
+import java.util.Arrays;
+
+public class DefaultRestAdapter {
+
+    public static void main(String[] args) throws IOException, Exception {
+        Arrays.asList(args).stream().forEach(System.out::println);
+        Thread.sleep(1000000);
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/JsonParserTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,97 @@
+
+
+
+import javax.management.remote.rest.json.JSONElement;
+import javax.management.remote.rest.json.parser.JSONParser;
+import javax.management.remote.rest.json.parser.ParseException;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author harsha
+ */
+public class JsonParserTest {
+    
+    public JsonParserTest() {
+    }
+
+    // TODO add test methods here.
+    // The methods must be annotated with annotation @Test. For example:
+    //
+    // @Test
+    // public void hello() {}
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+    }
+
+    @AfterMethod
+    public void tearDownMethod() throws Exception {
+    }
+    
+    @DataProvider
+    public Object[][] getJsonString() {
+        Object[][] data = new Object[2][1];
+        data[0][0] = "{organisms:[\n" +
+"        {\n" +
+"        id:10929,\n" +
+"        name:\"Bovine Rotavirus\"\n" +
+"        },\n" +
+"        {\n" +
+"        id:9606,\n" +
+"        name:\"Homo Sapiens\"\n" +
+"        }\n" +
+"        ],\n" +
+"proteins:[\n" +
+"        {\n" +
+"        label:\"NSP3\",\n" +
+"        description:\"Rotavirus Non Structural Protein 3\",\n" +
+"        organism-id: 10929,\n" +
+"        acc: \"ACB38353\"\n" +
+"        },\n" +
+"        {\n" +
+"        label:\"EIF4G\",\n" +
+"        description:\"eukaryotic translation initiation factor 4 gamma\",\n" +
+"        organism-id: 9606,\n" +
+"        boolflag: true,\n" +
+"        longFloat: 12351123.1235123e-10,\n" +                
+"        singleQuote: \'asd\',\n" +                                
+"        acc:\"AAI40897\"\n" +
+"        }\n" +
+"        ],\n" +
+"interactions:[\n" +
+"        {\n" +
+"        label:\"NSP3 interacts with EIF4G1\",\n" +
+"        pubmed-id:[77120248,38201627],\n" +
+"        proteins:[\"ACB38353\",\"AAI40897\"]\n" +
+"        }\n" +
+"        ]}";
+        
+        data[1][0] = "{\"name\":\"com.example:type=QueueSampler\",\"exec\":\"testMethod1\",\"params\":[[1,2,3],\"abc\",5,[\"asd\",\"3\",\"67\",\"778\"],[{date:\"2016-3-2\",size:3,head:\"head\"}],[{date:\"2016-3-2\",size:3,head:\"head\"}]]}";
+        return data;
+    }
+    
+    @Test (dataProvider = "getJsonString")
+    public void parserTest(String input) throws ParseException {
+        JSONParser jsonParser = new JSONParser(input);
+        JSONElement parse = jsonParser.parse();
+        String output = parse.toJsonString();
+        System.out.println("\t: " + input);
+        System.out.println("\t: " + output);
+//        Assert.assertEquals(input, output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/PlatformAdapterTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,275 @@
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.util.Base64;
+import java.util.Properties;
+import javax.management.remote.rest.JmxRestAdapter;
+import javax.management.remote.rest.PlatformRestAdapter;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.TrustManagerFactory;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+
+/**
+ * @test 
+ * @modules java.management.rest
+ * @run testng/othervm PlatformAdapterTest
+ */
+@Test
+public class PlatformAdapterTest {
+
+    private static final String MBEANS = "mbeans";
+    private static String sslAgentConfig;
+    private static String sslClientConfig;
+    private static String passwordFile;
+    
+
+    @BeforeClass
+    public void setup() throws IOException {
+        String testSrcRoot = System.getProperty("test.src") + File.separator;
+        sslAgentConfig = testSrcRoot + "sslConfigAgent";
+        sslClientConfig = testSrcRoot + "sslConfigClient";
+        passwordFile = testSrcRoot + "password.properties";
+        createAgentSslConfigFile(sslAgentConfig);
+        createClientSslConfigFile(sslClientConfig);
+    }
+    
+    @Test
+    public void testHttpNoAuth() throws Exception {
+        Properties props = new Properties();
+        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
+        props.setProperty("com.sun.management.jmxremote.ssl", "false");
+        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+
+        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+        adapter.start();
+        URL url = new URL(adapter.getBaseUrl() + MBEANS);
+        HttpURLConnection con = (HttpURLConnection) url.openConnection();
+        con.setDoOutput(false);
+        print_content(con);
+        PlatformRestAdapter.stop();
+    }
+
+    @Test
+    public void testHttpAuth() throws Exception {
+        Properties props = new Properties();
+        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
+        props.setProperty("com.sun.management.jmxremote.ssl", "false");
+        props.setProperty("com.sun.management.jmxremote.authenticate", "true");
+        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+
+        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+        adapter.start();
+        URL url = new URL(adapter.getBaseUrl() + MBEANS);
+        HttpURLConnection con = (HttpURLConnection) url.openConnection();
+        con.setDoOutput(false);
+
+        String userCredentials = "username1:password1";
+
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        con.setRequestProperty("Authorization", basicAuth);
+        print_content(con);
+
+        PlatformRestAdapter.stop();
+    }
+
+    private void createAgentSslConfigFile(String fileName) throws IOException {
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
+        props.setProperty("javax.net.ssl.trustStorePassword","glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void createClientSslConfigFile(String fileName) throws IOException {
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    @Test
+    public void testHttpsNoAuth() throws Exception {
+        Properties props = new Properties();
+        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
+        props.setProperty("com.sun.management.jmxremote.ssl", "true");
+        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
+        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+        adapter.start();
+        SSLContext ctx = getSSlContext(sslClientConfig);
+        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+        HttpsURLConnection.setDefaultHostnameVerifier(
+                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
+
+        URL url = new URL(adapter.getBaseUrl() + MBEANS);
+        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+        con.setDoOutput(false);
+        print_https_cert(con);
+        print_content(con);
+        PlatformRestAdapter.stop();
+    }
+
+    @Test
+    public void testHttpsAuth() throws Exception {
+        Properties props = new Properties();
+        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
+        props.setProperty("com.sun.management.jmxremote.ssl", "true");
+        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
+        props.setProperty("com.sun.management.jmxremote.authenticate", "true");
+        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+
+        JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+        adapter.start();
+        SSLContext ctx = getSSlContext(sslClientConfig);
+        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+        HttpsURLConnection.setDefaultHostnameVerifier(
+                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
+
+        URL url = new URL(adapter.getBaseUrl() + MBEANS);
+        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+        con.setDoOutput(false);
+
+        String userCredentials = "username1:password1";
+
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        con.setRequestProperty("Authorization", basicAuth);
+        print_https_cert(con);
+        print_content(con);
+        PlatformRestAdapter.stop();
+    }
+
+    private void print_content(HttpURLConnection con) {
+        if (con != null) {
+            try {
+                System.out.println("****** Content of the URL ********");
+                int status = con.getResponseCode();
+                System.out.println("Status = " + status);
+                BufferedReader br
+                        = new BufferedReader(
+                                new InputStreamReader(con.getInputStream()));
+                String input;
+                while ((input = br.readLine()) != null) {
+                    System.out.println(input);
+                }
+                br.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void print_https_cert(HttpsURLConnection con) {
+        if (con != null) {
+            try {
+                System.out.println("Response Code : " + con.getResponseCode());
+                System.out.println("Cipher Suite : " + con.getCipherSuite());
+                System.out.println("\n");
+
+                Certificate[] certs = con.getServerCertificates();
+                for (Certificate cert : certs) {
+                    System.out.println("Cert Type : " + cert.getType());
+                    System.out.println("Cert Hash Code : " + cert.hashCode());
+                    System.out.println("Cert Public Key Algorithm : "
+                            + cert.getPublicKey().getAlgorithm());
+                    System.out.println("Cert Public Key Format : "
+                            + cert.getPublicKey().getFormat());
+                    System.out.println("\n");
+                }
+
+            } catch (SSLPeerUnverifiedException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static SSLContext getSSlContext(String sslConfigFileName) {
+        String keyStore, keyStorePassword, trustStore, trustStorePassword;
+        System.out.println("SSL Config file : " + sslConfigFileName);
+
+        try {
+            Properties p = new Properties();
+            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
+            p.load(bin);
+            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
+            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
+            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
+            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+
+            char[] keyStorePasswd = null;
+            if (keyStorePassword.length() != 0) {
+                keyStorePasswd = keyStorePassword.toCharArray();
+            }
+
+            char[] trustStorePasswd = null;
+            if (trustStorePassword.length() != 0) {
+                trustStorePasswd = trustStorePassword.toCharArray();
+            }
+
+            KeyStore ks = null;
+            if (keyStore != null) {
+                ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream ksfis = new FileInputStream(keyStore);
+                ks.load(ksfis, keyStorePasswd);
+
+            }
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, keyStorePasswd);
+
+            KeyStore ts = null;
+            if (trustStore != null) {
+                ts = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream tsfis = new FileInputStream(trustStore);
+                ts.load(tsfis, trustStorePasswd);
+            }
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                    TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ts);
+
+            SSLContext ctx = SSLContext.getInstance("SSL");
+            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+            return ctx;
+        } catch (Exception ex) {
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/PlatformMBeanTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,291 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package javax.management.remote.rest.test;
+
+import javax.management.remote.rest.JmxRestAdapter;
+import javax.management.remote.rest.PlatformRestAdapter;
+import javax.management.remote.rest.json.JSONArray;
+import javax.management.remote.rest.json.JSONElement;
+import javax.management.remote.rest.json.JSONObject;
+import javax.management.remote.rest.json.JSONPrimitive;
+import javax.management.remote.rest.json.parser.JSONParser;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.KeyStore;
+import java.util.Base64;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author harsha
+ */
+public class PlatformMBeanTest {
+
+    private static SSLContext getSSlContext(String sslConfigFileName) {
+        final String keyStore, keyStorePassword, trustStore, trustStorePassword;
+
+        try {
+            Properties p = new Properties();
+            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
+            p.load(bin);
+            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
+            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
+            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
+            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+
+            char[] keyStorePasswd = null;
+            if (keyStorePassword.length() != 0) {
+                keyStorePasswd = keyStorePassword.toCharArray();
+            }
+
+            char[] trustStorePasswd = null;
+            if (trustStorePassword.length() != 0) {
+                trustStorePasswd = trustStorePassword.toCharArray();
+            }
+
+            KeyStore ks = null;
+            if (keyStore != null) {
+                ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream ksfis = new FileInputStream(keyStore);
+                ks.load(ksfis, keyStorePasswd);
+
+            }
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, keyStorePasswd);
+
+            KeyStore ts = null;
+            if (trustStore != null) {
+                ts = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream tsfis = new FileInputStream(trustStore);
+                ts.load(tsfis, trustStorePasswd);
+            }
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                    TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ts);
+
+            SSLContext ctx = SSLContext.getInstance("SSL");
+            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+            return ctx;
+        } catch (Exception ex) {
+            Logger.getLogger(PlatformRestAdapter.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return null;
+    }
+
+    private static final String CHARSET = "UTF-8";
+
+    private String getFilePath(String filename) {
+        return System.getProperty("user.dir") + File.separator + filename;
+    }
+
+    @BeforeClass
+    public void setupAdapter() throws Exception {
+        File file = new File(getFilePath("management.properties"));
+        Properties props = new Properties();
+        props.load(new FileInputStream(file));
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+        PlatformRestAdapter.getInstance().start();
+        SSLContext ctx = getSSlContext(getFilePath("sslconfigClient"));
+        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+        HttpsURLConnection.setDefaultHostnameVerifier(
+                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
+    }
+
+    @AfterClass
+    public void tearDown() {
+        PlatformRestAdapter.stop();
+    }
+
+    private String executeHttpGetRequest(String inputUrl) throws MalformedURLException, IOException {
+        if (inputUrl != null && !inputUrl.isEmpty()) {
+            JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+            URL url = new URL(adapter.getBaseUrl() + inputUrl);
+            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+            con.setDoOutput(false);
+            String userCredentials = "username1:password1";
+            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+            con.setRequestProperty("Authorization", basicAuth);
+            try {
+                int status = con.getResponseCode();
+                if (status == 200) {
+
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getInputStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(URLDecoder.decode(input, CHARSET));
+                        }
+                    }
+                    return sbuf.toString();
+                } else {
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getErrorStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(URLDecoder.decode(input, CHARSET));
+                        }
+                    }
+                    return sbuf.toString();
+                }
+            } catch (IOException e) {
+            }
+        }
+        return null;
+    }
+
+    private String executeHttpPostRequest(String postBody) throws MalformedURLException, IOException {
+        if (postBody != null && !postBody.isEmpty()) {
+            JmxRestAdapter adapter = PlatformRestAdapter.getInstance();
+            URL url = new URL(adapter.getBaseUrl());
+            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+            connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
+            connection.setDoOutput(true);
+            connection.setRequestMethod("POST");
+            String userCredentials = "username1:password1";
+            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+            connection.setRequestProperty("Authorization", basicAuth);
+            try (OutputStreamWriter out = new OutputStreamWriter(
+                    connection.getOutputStream(), CHARSET)) {
+                out.write(URLEncoder.encode(postBody, CHARSET));
+                out.flush();
+            }
+            try {
+                int status = connection.getResponseCode();
+                if (status == 200) {
+
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(connection.getInputStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(URLDecoder.decode(input, CHARSET));
+                        }
+                    }
+                    return sbuf.toString();
+                } else {
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(connection.getErrorStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(URLDecoder.decode(input, CHARSET));
+                        }
+                    }
+                    return sbuf.toString();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void testOperatingSystemMbean() throws Exception {
+        //  Get MBeanInfo
+        String osMbeanInfo = executeHttpGetRequest("java.lang:type=OperatingSystem");
+        System.out.println(osMbeanInfo);
+
+        // Read all attributes
+        JSONParser parser = new JSONParser(osMbeanInfo);
+        JSONObject docRoot = (JSONObject) parser.parse();
+        JSONArray attrJson = (JSONArray) ((JSONObject) docRoot.get("response")).get("attributeInfo");
+        for (JSONElement elem : attrJson) {
+            JSONObject attrElem = (JSONObject) elem;
+            JSONPrimitive a = (JSONPrimitive) attrElem.get("name");
+            JSONPrimitive access = (JSONPrimitive) attrElem.get("access");
+            String attrResponse = executeHttpGetRequest("java.lang:type=OperatingSystem/" + a.getValue());
+            parser = new JSONParser(attrResponse);
+            docRoot = (JSONObject) parser.parse();
+            JSONPrimitive result = (JSONPrimitive) ((JSONObject) docRoot.get("response")).get(a.getValue());
+            System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - " + result.getValue());
+        }
+    }
+
+    @Test
+    public void testHotSpotDiagMBean() throws Exception {
+        String mbeanName = "com.sun.management:type=HotSpotDiagnostic";
+        String osMbeanInfo = executeHttpGetRequest(mbeanName);
+        System.out.println(osMbeanInfo);
+
+        // Read all attributes
+        JSONParser parser = new JSONParser(osMbeanInfo);
+        JSONObject docRoot = (JSONObject) parser.parse();
+        JSONArray attrJson = (JSONArray) ((JSONObject) docRoot.get("response")).get("attributeInfo");
+        if (attrJson != null) {
+            for (JSONElement elem : attrJson) {
+                JSONObject attrElem = (JSONObject) elem;
+                JSONPrimitive a = (JSONPrimitive) attrElem.get("name");
+                JSONPrimitive access = (JSONPrimitive) attrElem.get("access");
+                String attrResponse = executeHttpGetRequest(mbeanName + "/" + a.getValue());
+                parser = new JSONParser(attrResponse);
+                docRoot = (JSONObject) parser.parse();
+                JSONObject response = (JSONObject) docRoot.get("response");
+                if (response != null) {
+                    JSONElement get = response.get(a.getValue());
+                    System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - " + get.toJsonString());
+                } else {
+                    System.out.println("Attribute : " + a.getValue() + "(" + access.getValue() + ")" + " - null");
+                }
+            }
+        }
+
+        String dumpHeap = "{\n"
+                + "  \"name\": \"com.sun.management:type=HotSpotDiagnostic\",\n"
+                + "  \"exec\": \"dumpHeap\",\n"
+                + "  \"arguments\": [\n"
+                + "			\"heapdump.hprof\",\n"
+                + "			false\n"
+                + "		]\n"
+                + "}";
+
+        String responseJson = executeHttpPostRequest(dumpHeap);
+        parser = new JSONParser(responseJson);
+        docRoot = (JSONObject) parser.parse();
+        JSONElement response = docRoot.get("response");
+        System.out.println(" DumpHeap op - " + (response != null ? response.toJsonString() : null));
+
+        String getVmOption = "{\n"
+                + "  \"name\": \"com.sun.management:type=HotSpotDiagnostic\",\n"
+                + "  \"exec\": \"getVMOption\",\n"
+                + "  \"arguments\": [\n"
+                + "	\"PrintGCDetails\"\n"
+                + "	]\n"
+                + "}";
+        responseJson = executeHttpPostRequest(getVmOption);
+        parser = new JSONParser(responseJson);
+        docRoot = (JSONObject) parser.parse();
+        response = docRoot.get("response");
+        System.out.println(" DumpHeap op - " + (response != null ? response.toJsonString() : null));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/RestAdapterSSLTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,477 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+import com.oracle.jmx.remote.rest.json.JSONArray;
+import com.oracle.jmx.remote.rest.json.JSONElement;
+import com.oracle.jmx.remote.rest.json.JSONObject;
+import com.oracle.jmx.remote.rest.json.JSONPrimitive;
+import com.oracle.jmx.remote.rest.json.parser.JSONParser;
+import com.oracle.jmx.remote.rest.json.parser.ParseException;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.util.Base64;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.remote.rest.PlatformRestAdapter;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.TrustManagerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @modules java.logging
+ *          java.management
+ *          java.management.rest
+ * @run testng/othervm RestAdapterSSLTest
+ * 
+ */
+@Test
+public class RestAdapterSSLTest {
+
+    private static final String CHARSET = "UTF-8";
+    private static String sslAgentConfig;
+    private static String sslClientConfig;
+    private static String passwordFile;
+    private static String configFile;
+
+    private void createAgentSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void createClientSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupMgmtConfig(String fileName) throws IOException {
+        Properties props = new Properties();
+        
+        props.setProperty("com.sun.management.jmxremote.ssl", "true");
+        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
+        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
+        props.setProperty("com.sun.management.jmxremote.rest.port", "0");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupConfig() throws Exception {
+        String testSrcRoot = System.getProperty("test.src") + File.separator;
+        sslAgentConfig = testSrcRoot + "sslConfigAgent";
+        sslClientConfig = testSrcRoot + "sslConfigClient";
+        passwordFile = testSrcRoot + "password.properties";
+        configFile = testSrcRoot + "mgmt.properties";
+        createAgentSslConfigFile(sslAgentConfig);
+        createClientSslConfigFile(sslClientConfig);
+        setupMgmtConfig(configFile);
+    }
+
+    @BeforeClass
+    public void setupAdapter() throws Exception {
+        setupConfig();
+        File file = new File(configFile);
+        Properties props = new Properties();
+        props.load(new FileInputStream(file));
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+        SSLContext ctx = getSSlContext(sslClientConfig);
+        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+        HttpsURLConnection.setDefaultHostnameVerifier(
+                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
+        setupMbean();
+    }
+
+    @AfterClass
+    public void tearDown() {
+        PlatformRestAdapter.stop();
+    }
+
+    @DataProvider
+    public Object[][] getUrlList() {
+        Object[][] data = new Object[7][1];
+        data[0][0] = "?domain=default";
+        data[1][0] = "mbeans";
+        data[2][0] = "domains";
+        data[3][0] = "java.lang:type=Memory";
+        data[4][0] = "java.lang:type=Memory/HeapMemoryUsage";
+        data[5][0] = "java.lang:type=Memory/?attributes=HeapMemoryUsage,ObjectPendingFinalizationCount,NonHeapMemoryUsage";
+        data[6][0] = "java.lang:type=Memory/?attributes=all";
+        return data;
+    }
+
+    @DataProvider
+    public Object[][] getMalformedUrlList() {
+        Object[][] data = new Object[1][1];
+        data[0][0] = "com.example:type=QueueSamplerMBean";
+        return data;
+    }
+
+    private String executeHttpRequest(String inputUrl) throws IOException {
+        return executeHttpRequest(inputUrl, null);
+    }
+
+    private String executeHttpRequest(String inputUrl, String charset) throws IOException {
+        if (inputUrl != null && !inputUrl.isEmpty()) {
+            URL url = new URL(PlatformRestAdapter.getBaseURL() + (charset != null ? URLEncoder.encode(inputUrl, charset) : inputUrl));
+            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+            con.setDoOutput(false);
+            String userCredentials = "username1:password1";
+            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+            con.setRequestProperty("Authorization", basicAuth);
+            if (charset != null && !charset.isEmpty()) {
+                con.setRequestProperty("Content-Type", "application/json; charset=" + charset);
+            }
+            try {
+                int status = con.getResponseCode();
+                if (status == 200) {
+
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getInputStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
+                        }
+                    }
+                    return sbuf.toString();
+                } else {
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getErrorStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
+                        }
+                    }
+                    return sbuf.toString();
+                }
+            } catch (IOException e) {
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void testMisc() throws IOException, ParseException {
+        String mBeanInfo = executeHttpRequest("com.sun.management:type=DiagnosticCommand");
+        System.out.println(mBeanInfo);
+        JSONParser parser = new JSONParser(mBeanInfo);
+        JSONObject response = (JSONObject) parser.parse();
+        long status = (Long) ((JSONPrimitive) response.get("status")).getValue();
+        Assert.assertEquals(status, 200);
+    }
+
+    @Test(enabled = false)
+    public void testCharset() throws IOException {
+        String result1 = executeHttpRequest("?domain=default");
+        String result2 = executeHttpRequest("?domain=default", CHARSET);
+        Assert.assertEquals(result1, result2);
+    }
+
+    @Test
+    public void testPostMisc() throws IOException {
+        URL url = new URL(PlatformRestAdapter.getBaseURL());
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
+        connection.setDoOutput(true);
+        connection.setRequestMethod("POST");
+        String userCredentials = "username1:password1";
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        connection.setRequestProperty("Authorization", basicAuth);
+
+        String req = "{\n"
+                + "    \"name\":\"java.lang:type=Memory\"\n"
+                + "    \"write\":\"Verbose\"\n"
+                + "    \"arguments\" : [true]\n"
+                + "}";
+        try (OutputStreamWriter out = new OutputStreamWriter(
+                connection.getOutputStream(), CHARSET)) {
+            out.write(URLEncoder.encode(req, CHARSET));
+            out.flush();
+        }
+
+        print_content(connection);
+    }
+
+    @Test
+    public void testBasicHttps() throws Exception {
+        URL url = new URL(PlatformRestAdapter.getBaseURL());
+        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+        con.setDoOutput(false);
+
+        String userCredentials = "username1:password1";
+
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        con.setRequestProperty("Authorization", basicAuth);
+        print_https_cert(con);
+        print_content(con);
+    }
+
+    @Test(dataProvider = "getUrlList")
+    public void testGetRequests(String urlStr) throws Exception {
+        String input = executeHttpRequest(urlStr);
+        System.out.println("URL : [" + urlStr + "] ----> " + input);
+        System.out.println(input);
+        JSONParser parser = new JSONParser(input);
+        JSONElement parse = parser.parse();
+        JSONElement jstatus = ((JSONObject) parse).get("status");
+        long status = (Long) ((JSONPrimitive) jstatus).getValue();
+        Assert.assertEquals(status, 200);
+    }
+
+    @Test
+    public void testAllGetMBeanInfo() throws Exception {
+        String input = executeHttpRequest("mbeans");
+        JSONParser parser = new JSONParser(input);
+        JSONElement jsonObj = parser.parse();
+        if (jsonObj instanceof JSONObject) {
+            JSONElement jelem = ((JSONObject) jsonObj).get("response");
+            if (jelem instanceof JSONArray) {
+                for (JSONElement elem : ((JSONArray) jelem)) {
+                    String objName = (String) ((JSONPrimitive) elem).getValue();
+                    String mBeanInfo = executeHttpRequest(objName);
+                    System.out.println(mBeanInfo);
+                    parser = new JSONParser(mBeanInfo);
+                    JSONObject response = (JSONObject) parser.parse();
+                    long status = (Long) ((JSONPrimitive) response.get("status")).getValue();
+                    Assert.assertEquals(status, 200);
+                }
+            }
+        }
+    }
+
+    @Test(enabled = false, dataProvider = "getMalformedUrlList")
+    public void negTestGetRequests(String urlStr) throws Exception {
+        URL url = new URL(PlatformRestAdapter.getBaseURL() + urlStr);
+        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+        con.setDoOutput(false);
+        String userCredentials = "username1:password1";
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        con.setRequestProperty("Authorization", basicAuth);
+        print_content(con);
+    }
+
+    @Test
+    public void testPost() throws Exception {
+        URL url = new URL(PlatformRestAdapter.getBaseURL());
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        connection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
+        connection.setDoOutput(true);
+        connection.setRequestMethod("POST");
+        String userCredentials = "username1:password1";
+        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+        connection.setRequestProperty("Authorization", basicAuth);
+
+        String postReq = "{\"name\":\"com.example:type=QueueSampler\",\"exec\":\"testMethod1\",\"arguments\":[[1,2,3],\"abc\",5,[\"asd\",\"3\",\"67\",\"778\"],[{date:\"2016-03-02\",size:3,head:\"head\"}],[{date:\"2016-03-02\",size:3,head:\"head\"}]]}";
+        JSONArray jarr = new JSONArray();
+
+        JSONObject jobject = new JSONObject();
+        jobject.put("name", "com.example:type=QueueSampler");
+        jobject.put("write", "QueueName");
+        JSONArray jarr1 = new JSONArray();
+        jarr1.add(new JSONPrimitive("Dequeue"));
+        jobject.put("arguments", jarr1);
+        jarr.add(jobject);
+
+        jobject = new JSONObject();
+        jobject.put("name", "com.example:type=QueueSampler");
+        jobject.put("read", "QueueName");
+        jarr.add(jobject);
+
+        jarr.add(new JSONParser(postReq).parse());
+
+        try (OutputStreamWriter out = new OutputStreamWriter(
+                connection.getOutputStream(), CHARSET)) {
+            out.write(URLEncoder.encode(jarr.toJsonString(), CHARSET));
+            out.flush();
+        }
+        print_content(connection);
+    }
+
+    @Test(enabled = false)
+    public void testMBeanFilter() throws MalformedObjectNameException {
+        // Add non-compliant MBean to platform mbean server
+        ObjectName mbeanName = new ObjectName("com.example:type=QueueSamplerMBean");
+    }
+
+    private void setupMbean() throws Exception {
+        // Get the Platform MBean Server
+//        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+//
+//        // Construct the ObjectName for the QueueSampler MXBean we will register
+//        ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler");
+//        ObjectName mbeanName = new ObjectName("com.example:type=QueueSamplerMBean");
+//
+//        // Create the Queue Sampler MXBean
+//        Queue<String> queue = new ArrayBlockingQueue<>(10);
+//        queue.add("Request-1");
+//        queue.add("Request-2");
+//        queue.add("Request-3");
+//        QueueSampler mxbean = new QueueSampler(queue);
+//        QueueSamplerBean mbean = new QueueSamplerBean(queue);
+//
+//        // Register the Queue Sampler MXBean
+//        mbs.registerMBean(mxbean, mxbeanName);
+//        mbs.registerMBean(mbean, mbeanName);
+    }
+
+    private void print_content(HttpURLConnection con) {
+        if (con != null) {
+            try {
+                System.out.println("****** Content of the URL ********");
+                int status = con.getResponseCode();
+
+                System.out.println("Status = " + status);
+                InputStream is;
+                if (status == HttpURLConnection.HTTP_OK) {
+                    is = con.getInputStream();
+                } else {
+                    is = con.getErrorStream();
+                }
+                BufferedReader br
+                        = new BufferedReader(new InputStreamReader(is));
+                String input;
+                while ((input = br.readLine()) != null) {
+                    System.out.println(URLDecoder.decode(input, CHARSET));
+                }
+                br.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void print_https_cert(HttpsURLConnection con) {
+        if (con != null) {
+            try {
+                System.out.println("Response Code : " + con.getResponseCode());
+                System.out.println("Cipher Suite : " + con.getCipherSuite());
+                System.out.println("\n");
+
+                Certificate[] certs = con.getServerCertificates();
+                for (Certificate cert : certs) {
+                    System.out.println("Cert Type : " + cert.getType());
+                    System.out.println("Cert Hash Code : " + cert.hashCode());
+                    System.out.println("Cert Public Key Algorithm : "
+                            + cert.getPublicKey().getAlgorithm());
+                    System.out.println("Cert Public Key Format : "
+                            + cert.getPublicKey().getFormat());
+                    System.out.println("\n");
+                }
+
+            } catch (SSLPeerUnverifiedException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static SSLContext getSSlContext(String sslConfigFileName) {
+        final String keyStore, keyStorePassword, trustStore, trustStorePassword;
+
+        try {
+            Properties p = new Properties();
+            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
+            p.load(bin);
+            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
+            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
+            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
+            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+
+            char[] keyStorePasswd = null;
+            if (keyStorePassword.length() != 0) {
+                keyStorePasswd = keyStorePassword.toCharArray();
+            }
+
+            char[] trustStorePasswd = null;
+            if (trustStorePassword.length() != 0) {
+                trustStorePasswd = trustStorePassword.toCharArray();
+            }
+
+            KeyStore ks = null;
+            if (keyStore != null) {
+                ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream ksfis = new FileInputStream(keyStore);
+                ks.load(ksfis, keyStorePasswd);
+
+            }
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, keyStorePasswd);
+
+            KeyStore ts = null;
+            if (trustStore != null) {
+                ts = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream tsfis = new FileInputStream(trustStore);
+                ts.load(tsfis, trustStorePasswd);
+            }
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                    TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ts);
+
+            SSLContext ctx = SSLContext.getInstance("SSL");
+            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+            return ctx;
+        } catch (Exception ex) {
+            Logger.getLogger(PlatformRestAdapter.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/RestAdapterTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,221 @@
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.KeyStore;
+import java.util.Base64;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.remote.rest.PlatformRestAdapter;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @test @modules java.logging java.management java.management.rest
+ * @run testng/othervm RestAdapterTest
+ *
+ */
+@Test
+public class RestAdapterTest {
+
+    private static final String CHARSET = "UTF-8";
+    private static String sslAgentConfig;
+    private static String sslClientConfig;
+    private static String passwordFile;
+    private static String configFile;
+
+    private void createAgentSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void createClientSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupMgmtConfig(String fileName) throws IOException {
+        Properties props = new Properties();
+
+        props.setProperty("com.sun.management.jmxremote.ssl", "true");
+        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
+        props.setProperty("com.sun.management.jmxremote.password.file", passwordFile);
+        props.setProperty("com.sun.management.jmxremote.rest.port", "0");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupConfig() throws Exception {
+        String testSrcRoot = System.getProperty("test.src") + File.separator;
+        sslAgentConfig = testSrcRoot + "sslConfigAgent";
+        sslClientConfig = testSrcRoot + "sslConfigClient";
+        passwordFile = testSrcRoot + "password.properties";
+        configFile = testSrcRoot + "mgmt.properties";
+        createAgentSslConfigFile(sslAgentConfig);
+        createClientSslConfigFile(sslClientConfig);
+        setupMgmtConfig(configFile);
+    }
+
+    @BeforeClass
+    public void setupAdapter() throws Exception {
+        setupConfig();
+        File file = new File(configFile);
+        Properties props = new Properties();
+        props.load(new FileInputStream(file));
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+        SSLContext ctx = getSSlContext(sslClientConfig);
+        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+        HttpsURLConnection.setDefaultHostnameVerifier(
+                (String hostname, javax.net.ssl.SSLSession sslSession) -> hostname.equals("Harsha-Wardhana-B"));
+    }
+
+    @AfterClass
+    public void tearDown() {
+        PlatformRestAdapter.stop();
+    }
+
+    private static SSLContext getSSlContext(String sslConfigFileName) {
+        final String keyStore, keyStorePassword, trustStore, trustStorePassword;
+
+        try {
+            Properties p = new Properties();
+            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
+            p.load(bin);
+            keyStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_FILE);
+            keyStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_KEYSTORE_PASSWORD);
+            trustStore = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_FILE);
+            trustStorePassword = p.getProperty(PlatformRestAdapter.PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+
+            char[] keyStorePasswd = null;
+            if (keyStorePassword.length() != 0) {
+                keyStorePasswd = keyStorePassword.toCharArray();
+            }
+
+            char[] trustStorePasswd = null;
+            if (trustStorePassword.length() != 0) {
+                trustStorePasswd = trustStorePassword.toCharArray();
+            }
+
+            KeyStore ks = null;
+            if (keyStore != null) {
+                ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream ksfis = new FileInputStream(keyStore);
+                ks.load(ksfis, keyStorePasswd);
+            }
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, keyStorePasswd);
+
+            KeyStore ts = null;
+            if (trustStore != null) {
+                ts = KeyStore.getInstance(KeyStore.getDefaultType());
+                FileInputStream tsfis = new FileInputStream(trustStore);
+                ts.load(tsfis, trustStorePasswd);
+            }
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                    TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ts);
+
+            SSLContext ctx = SSLContext.getInstance("SSL");
+            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+            return ctx;
+        } catch (Exception ex) {
+            Logger.getLogger(PlatformRestAdapter.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return null;
+    }
+
+    private String executeHttpRequest(String inputUrl, String charset) throws IOException {
+        if (inputUrl != null) {
+            URL url = new URL(PlatformRestAdapter.getBaseURL() + (charset != null ? URLEncoder.encode(inputUrl, charset) : inputUrl));
+            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+            con.setDoOutput(false);
+            String userCredentials = "username1:password1";
+            String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
+            con.setRequestProperty("Authorization", basicAuth);
+            if (charset != null && !charset.isEmpty()) {
+                con.setRequestProperty("Content-Type", "application/json; charset=" + charset);
+            }
+            try {
+                int status = con.getResponseCode();
+                if (status == 200) {
+
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getInputStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
+                        }
+                    }
+                    return sbuf.toString();
+                } else {
+                    StringBuilder sbuf;
+                    try (BufferedReader br = new BufferedReader(
+                            new InputStreamReader(con.getErrorStream()))) {
+                        sbuf = new StringBuilder();
+                        String input;
+                        while ((input = br.readLine()) != null) {
+                            sbuf.append(charset != null ? URLDecoder.decode(input, charset) : input);
+                        }
+                    }
+                    return sbuf.toString();
+                }
+            } catch (IOException e) {
+            }
+        }
+        return null;
+    }
+    
+    @Test
+    public void testMBeanServerCollection() throws IOException {
+        System.out.println(executeHttpRequest("/platform/mbeans/java.lang:type=Runtime",null));
+//        System.out.println(executeHttpRequest("/platform/mbeans/java.lang:name=CodeHeap%20'non-nmethods',type=MemoryPool/info", null));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/RunRestAdapter.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,99 @@
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Scanner;
+import javax.management.remote.rest.PlatformRestAdapter;
+
+
+/**
+ * @test
+ * @modules java.logging
+ *          java.management.rest
+ * @run main RunRestAdapter
+ */
+public class RunRestAdapter {
+
+    private static String sslAgentConfig;
+    private static String sslClientConfig;
+    private static String configFile;
+
+    public static void main(String[] args) throws Exception {
+        RunRestAdapter rr = new RunRestAdapter();
+        rr.run();
+        while (true)
+        {
+            Thread.sleep(1000);
+        }
+    }
+
+    private void createAgentSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreAgent");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreAgent");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void createClientSslConfigFile(String fileName) throws IOException {
+        File f = new File(fileName);
+        if (f.exists()) {
+            return;
+        }
+        Properties props = new Properties();
+        String testDir = System.getProperty("test.src");
+        props.setProperty("javax.net.ssl.keyStore", testDir + File.separator + "keystoreClient");
+        props.setProperty("javax.net.ssl.keyStorePassword", "glopglop");
+        props.setProperty("javax.net.ssl.trustStore", testDir + File.separator + "truststoreClient");
+        props.setProperty("javax.net.ssl.trustStorePassword", "glopglop");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupMgmtConfig(String fileName) throws IOException {
+        Properties props = new Properties();
+        props.setProperty("com.sun.management.jmxremote.ssl", "true");
+        props.setProperty("com.sun.management.jmxremote.ssl.config.file", sslAgentConfig);
+        props.setProperty("com.sun.management.jmxremote.authenticate", "false");
+        props.setProperty("com.sun.management.jmxremote.rest.port", "8686");
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+            props.store(writer, "");
+        }
+    }
+
+    private void setupConfig() throws Exception {
+        String testSrcRoot = System.getProperty("test.src") + File.separator;
+        sslAgentConfig = testSrcRoot + "sslConfigAgent";
+        sslClientConfig = testSrcRoot + "sslConfigClient";
+
+        configFile = testSrcRoot + "mgmt1.properties";
+        createAgentSslConfigFile(sslAgentConfig);
+        createClientSslConfigFile(sslClientConfig);
+        setupMgmtConfig(configFile);
+    }
+
+    public void run() throws Exception {
+        setupConfig();
+        File file = new File(configFile);
+        Properties props = new Properties();
+        props.load(new FileInputStream(file));
+        if (props.get("com.sun.management.jmxremote.rest.port") != null) {
+            PlatformRestAdapter.init((String) props.get("com.sun.management.jmxremote.rest.port"), props);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/data/QueueSample.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,38 @@
+package javax.management.remote.rest.test.data;
+
+/*
+ * QueueSample.java - Java type representing a snapshot of a given queue.
+ * It bundles together the instant time the snapshot was taken, the queue
+ * size and the queue head.
+ */
+
+
+
+import java.beans.ConstructorProperties;
+import java.util.Date;
+
+public class QueueSample {
+    
+    private final Date date;
+    private final int size;
+    private final String head;
+
+    @ConstructorProperties({"date", "size", "head"})
+    public QueueSample(Date date, int size, String head) {
+        this.date = date;
+        this.size = size;
+        this.head = head;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public String getHead() {
+        return head;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/data/QueueSampler.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,58 @@
+package javax.management.remote.rest.test.data;
+
+/*
+ * QueueSampler.java - MXBean implementation for the QueueSampler MXBean.
+ * This class must implement all the Java methods declared in the
+ * QueueSamplerMXBean interface, with the appropriate behavior for each one.
+ */
+
+
+import java.util.Date;
+import java.util.List;
+import java.util.Queue;
+
+public class QueueSampler implements QueueSamplerMXBean {
+
+    private Queue<String> queue;
+    private QueueSample sample;
+    private String name;
+
+    public QueueSampler(Queue<String> queue) {
+        this.queue = queue;
+        synchronized (queue) {
+            sample = new QueueSample(new Date(), queue.size(), queue.peek());
+        }
+        name = "BoogeyMan";
+    }
+
+    public QueueSample getQueueSample() {
+        return sample;
+    }
+    
+    public void clearQueue() {
+        synchronized (queue) {
+            queue.clear();
+        }
+    }
+
+    @Override
+    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5) {
+        System.out.println("########## Invoke TestMethod1");
+        return new String[]{"1","2","3","4","5"};
+    }
+
+    @Override
+    public void setQueueSample(QueueSample sample) {
+        this.sample = sample;
+    }
+
+    @Override
+    public String getQueueName() {
+        return name;
+    }
+
+    @Override
+    public void setQueueName(String name) {
+        this.name = name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/data/QueueSamplerBean.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,59 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package javax.management.remote.rest.test.data;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ *
+ * @author harsha
+ */
+public class QueueSamplerBean implements QueueSamplerBeanMBean {
+
+    private Queue<String> queue;
+    private QueueSample sample;
+    private String name;
+
+    public QueueSamplerBean(Queue<String> queue) {
+        this.queue = queue;
+        synchronized (queue) {
+            sample = new QueueSample(new Date(), queue.size(), queue.peek());
+        }
+        name = "BoogeyMan";
+    }
+
+    public QueueSample getQueueSample() {
+        return sample;
+    }
+    
+    public void clearQueue() {
+        synchronized (queue) {
+            queue.clear();
+        }
+    }
+
+    @Override
+    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5) {
+        return new String[]{"1","2","3","4","5"};
+    }
+
+    @Override
+    public void setQueueSample(QueueSample sample) {
+        this.sample = sample;
+    }
+
+    @Override
+    public String getQueueName() {
+        return name;
+    }
+
+    @Override
+    public void setQueueName(String name) {
+        this.name = name;
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/data/QueueSamplerBeanMBean.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,26 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package javax.management.remote.rest.test.data;
+
+import java.util.List;
+
+/**
+ *
+ * @author harsha
+ */
+public interface QueueSamplerBeanMBean {
+        public QueueSample getQueueSample();
+    
+    public void setQueueSample(QueueSample sample);
+
+    public String getQueueName();
+    
+    public void setQueueName(String name);
+    
+    public void clearQueue();
+
+    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/data/QueueSamplerMXBean.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,19 @@
+package javax.management.remote.rest.test.data;
+
+
+import java.util.List;
+
+public interface QueueSamplerMXBean {
+    
+    public QueueSample getQueueSample();
+    
+    public void setQueueSample(QueueSample sample);
+
+    public String getQueueName();
+    
+    public void setQueueName(String name);
+    
+    public void clearQueue();
+
+    public String[] testMethod1(int[] param2, String param1, int sd34, String[] param3, QueueSample[] param4, List<QueueSample> param5);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/json/JSONTest.java	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,408 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+import com.oracle.jmx.remote.rest.json.parser.JSONParser;
+import com.oracle.jmx.remote.rest.json.parser.ParseException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * @test @modules java.management.rest
+ * @run main JSONTest
+ */
+public class JSONTest {
+
+    public static void main(String[] args) throws ParseException {
+        JSONGraphGenerator graphGen = new JSONGraphGenerator(50);
+        JSONElement jElem = graphGen.generateJsonGraph(20000);
+        System.out.println("Graph Generated");
+        String str = jElem.toJsonString();
+        System.out.println(str);
+
+        JSONParser parser = new JSONParser(str);
+
+        com.oracle.jmx.remote.rest.json.JSONElement parse = parser.parse();
+        String resultJson = parse.toJsonString();
+        System.out.println(resultJson);
+    }
+}
+
+interface JSONElement {
+
+    String toJsonString();
+}
+
+interface Visitable {
+
+    public void accept(NodeVisitor visitor);
+}
+
+interface NodeVisitor {
+
+    public void visit(Node node);
+
+    //visit other concrete items
+    public void visit(Digit19 digit12);
+
+    public void visit(Digits dvd);
+}
+
+class Node implements Visitable {
+
+    final private String label;
+
+    public Node(String label) {
+        children = new LinkedList<>();
+        this.label = label;
+    }
+
+    public Node() {
+        this("");
+    }
+
+    public void add(Node node) {
+        if (!children.contains(node)) {
+            children.add(node);
+        }
+    }
+
+    public String getLabel() {
+        return label;
+    }
+    List<Node> children;
+
+    @Override
+    public void accept(NodeVisitor visitor) {
+        visitor.visit(this);
+    }
+}
+
+class Digit19 extends Node {
+
+    Random rnd = new Random();
+
+    public Digit19() {
+        super();
+    }
+
+    @Override
+    public String getLabel() {
+        return "" + (rnd.nextInt(9) + 1);
+    }
+}
+
+class Digits extends Node {
+
+    Random rnd = new Random();
+
+    public Digits() {
+        super();
+    }
+
+    @Override
+    public String getLabel() {
+        return "" + (rnd.nextInt(10));
+    }
+}
+
+class JSONNumberGenerator {
+
+    private final static Node root;
+    Number num;
+
+    static {
+        root = new Node("R");
+        Node minus1 = new Node("-");
+        Node zero = new Node("0");
+        Node digit19 = new Digit19();
+        Node digits1 = new Digits();
+        Node dot = new Node(".");
+        Node digits2 = new Digits();
+        Node e = new Node("e");
+        Node E = new Node("E");
+        Node plus = new Node("+");
+        Node minus2 = new Node("-");
+        Node digits3 = new Digits();
+        Node terminal = new Node("T");
+
+        root.add(zero);
+        root.add(minus1);
+        root.add(digit19);
+
+        minus1.add(zero);
+        minus1.add(digit19);
+
+        zero.add(dot);
+//        zero.add(e);
+//        zero.add(E);
+        zero.add(terminal);
+
+        digit19.add(dot);
+        digit19.add(digits1);
+//        digit19.add(e);
+//        digit19.add(E);
+        digit19.add(terminal);
+
+        digits1.add(dot);
+        digits1.add(digits1);
+//        digits1.add(e);
+//        digits1.add(E);
+        digits1.add(terminal);
+
+        dot.add(digits2);
+
+        digits2.add(digits2);
+        digits2.add(e);
+        digits2.add(E);
+        digits2.add(terminal);
+
+        e.add(plus);
+        e.add(minus2);
+        e.add(digits3);
+
+        E.add(plus);
+        E.add(minus2);
+        E.add(digits3);
+
+        plus.add(digits3);
+        minus2.add(digits3);
+
+        digits3.add(digits3);
+        digits3.add(terminal);
+    }
+
+    private static class NumberNodeVisitor implements NodeVisitor {
+
+        private final StringBuilder sbuf = new StringBuilder();
+        Random rnd = new Random();
+
+        public NumberNodeVisitor() {
+        }
+
+        @Override
+        public void visit(Node node) {
+            if (!node.getLabel().equals("R")) {
+                sbuf.append(node.getLabel());
+            }
+            if (node.children.size() > 0) {
+                Node child = node.children.get(rnd.nextInt(node.children.size()));
+                if (!child.getLabel().equals("T")) {
+                    visit(child);
+                }
+            } else {
+                System.out.println("Found node " + node.getLabel() + " with children : " + node.children.size());
+            }
+        }
+
+        @Override
+        public void visit(Digit19 digit12) {
+            sbuf.append(digit12.getLabel());
+            Node child = digit12.children.get(rnd.nextInt(digit12.children.size()));
+            if (!child.getLabel().equals("T")) {
+                visit(child);
+            }
+        }
+
+        @Override
+        public void visit(Digits digits) {
+            sbuf.append(digits.getLabel());
+            Node child = digits.children.get(rnd.nextInt(digits.children.size()));
+            if (!child.getLabel().equals("T")) {
+                visit(child);
+            }
+        }
+
+        public String getNumber() {
+            return sbuf.toString();
+        }
+
+    }
+
+    public String generate() {
+        NumberNodeVisitor visitor = new NumberNodeVisitor();
+        visitor.visit(root);
+        // System.out.println(visitor.getNumber());
+//        Double.parseDouble(visitor.getNumber());
+        return visitor.getNumber();
+    }
+}
+
+class TestJsonObject extends LinkedHashMap<String, JSONElement> implements JSONElement {
+
+    @Override
+    public String toJsonString() {
+        if (isEmpty()) {
+            return null;
+        }
+
+        StringBuilder sbuild = new StringBuilder();
+        sbuild.append("{");
+        keySet().forEach((elem) -> {
+            sbuild.append(elem).append(": ").
+                    append((get(elem) != null) ? get(elem).toJsonString() : "null").append(",");
+        });
+
+        sbuild.deleteCharAt(sbuild.lastIndexOf(","));
+        sbuild.append("}");
+        return sbuild.toString();
+    }
+}
+
+class TestJsonArray extends ArrayList<JSONElement> implements JSONElement {
+
+    @Override
+    public String toJsonString() {
+        if (isEmpty()) {
+            return null;
+        }
+        StringBuilder sbuild = new StringBuilder();
+        sbuild.append("[");
+        Iterator<JSONElement> itr = iterator();
+        while (itr.hasNext()) {
+            JSONElement val = itr.next();
+            if (val != null) {
+                sbuild.append(val.toJsonString()).append(", ");
+            } else {
+                sbuild.append("null").append(", ");
+            }
+        }
+
+        sbuild.deleteCharAt(sbuild.lastIndexOf(","));
+        sbuild.append("]");
+        return sbuild.toString();
+    }
+}
+
+class TestJsonPrimitive implements JSONElement {
+
+    private final String s;
+
+    public TestJsonPrimitive(String s) {
+        this.s = s;
+    }
+
+    @Override
+    public String toJsonString() {
+        return s;
+    }
+}
+
+class JSONStringGenerator {
+
+    private static final int minStringLength = 0;
+    private static final int maxStringLength = 10;
+
+    private final Random rnd = new Random(System.currentTimeMillis());
+
+    private static final String specials = "\b" + "\f" + "\n" + "\r" + "\t" + "\\" + "\"";    // TODO: Special characters '/', '\', '"', "\\uxxxx"
+    private static final String alphanums = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+    public String generate() {
+        char ch;
+        StringBuilder sbuf = new StringBuilder();
+        int len = minStringLength + rnd.nextInt(maxStringLength - minStringLength + 1);
+        sbuf.append("\"");
+        for (int i = 0; i < len; i++) {
+            if (rnd.nextInt(10) == 1) { // 1/10 chances of a control character
+                ch = specials.charAt(rnd.nextInt(specials.length()));
+            } else {
+//                ch = alphanums.charAt(rnd.nextInt(alphanums.length()));
+                ch = (char) rnd.nextInt(Character.MAX_VALUE + 1);
+            }
+            switch (ch) {
+                case '\"':
+                case '\\':
+                    sbuf.append('\\');
+            }
+            sbuf.append(ch);
+        }
+        sbuf.append("\"");
+        return sbuf.toString();
+    }
+}
+
+class JSONGraphGenerator {
+
+    JSONStringGenerator stringGen;
+    JSONNumberGenerator numGen;
+    private final int maxChildPerNode;
+    static Random rnd = new Random(System.currentTimeMillis());
+
+    public JSONGraphGenerator(int maxChildPerNode) {
+        this.maxChildPerNode = maxChildPerNode;
+        stringGen = new JSONStringGenerator();
+        numGen = new JSONNumberGenerator();
+    }
+
+    private TestJsonPrimitive generatePrimitiveData() {
+        int primitiveTypre = rnd.nextInt(10) + 1;
+        switch (primitiveTypre) {
+            case 1:
+            case 2:
+            case 3:
+            case 4:
+                return new TestJsonPrimitive(stringGen.generate());
+            case 5:
+            case 6:
+            case 7:
+            case 8:
+                return new TestJsonPrimitive(numGen.generate());
+            case 9:
+                return new TestJsonPrimitive(Boolean.toString(rnd.nextBoolean()));
+            case 10:
+                return null;
+        }
+        return null;
+    }
+
+    public TestJsonObject generateJsonObject(int size) {
+        TestJsonObject jobj = new TestJsonObject();
+        if (size <= maxChildPerNode) {
+            for (int i = 0; i < size; i++) {
+                jobj.put(stringGen.generate(), generatePrimitiveData());
+            }
+        } else {
+            int newSize = size;
+            do {
+                int childSize = rnd.nextInt(newSize);
+                jobj.put(stringGen.generate(), generateJsonGraph(childSize));
+                newSize = newSize - childSize;
+            } while (newSize > maxChildPerNode);
+            jobj.put(stringGen.generate(), generateJsonGraph(newSize));
+        }
+        return jobj;
+    }
+
+    public TestJsonArray generateJsonArray(int size) {
+        TestJsonArray array = new TestJsonArray();
+        if (size <= maxChildPerNode) {
+            for (int i = 0; i < size; i++) {
+                array.add(generatePrimitiveData());
+            }
+        } else if (size >= maxChildPerNode) {
+            int newSize = size;
+            do {
+                int childSize = rnd.nextInt(newSize);
+                array.add(generateJsonGraph(childSize));
+                newSize = newSize - childSize;
+            } while (newSize > maxChildPerNode);
+            array.add(generateJsonGraph(newSize));
+        }
+        return array;
+    }
+
+    public JSONElement generateJsonGraph(int size) {
+        if (rnd.nextBoolean()) {
+            return generateJsonArray(size);
+        } else {
+            return generateJsonObject(size);
+        }
+    }
+}
Binary file test/jdk/javax/management/remote/rest/keystoreAgent has changed
Binary file test/jdk/javax/management/remote/rest/keystoreClient has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/management.properties	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,6 @@
+com.sun.management.jmxremote.ssl=true
+com.sun.management.jmxremote.ssl.config.file=sslconfig
+# com.sun.management.jmxremote.login.config=<config-name>
+com.sun.management.jmxremote.password.file=password.properties
+# com.sun.management.jmxremote.host=<host-or-interface-name>
+com.sun.management.jmxremote.rest.port=8686
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/management1.properties	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,7 @@
+com.sun.management.jmxremote.ssl=true
+com.sun.management.jmxremote.ssl.config.file=/home/harsha/work/jdk10_rest/jdk/test/sun/management/jmxremote/rest/sslconfig
+# com.sun.management.jmxremote.login.config=<config-name>
+com.sun.management.jmxremote.authenticate=false
+com.sun.management.jmxremote.password.file=/home/harsha/work/jdk10_rest/jdk/test/sun/management/jmxremote/rest/password.properties
+# com.sun.management.jmxremote.host=<host-or-interface-name>
+com.sun.management.jmxremote.rest.port=8686
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/password.properties	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,12 @@
+# Password file for default SQE username.
+SQE_username SQE_password
+
+# Functional authorization tests
+username1 password1
+username2 password2
+username3 password3
+username4 password4
+username5 password5
+username6 password6
+
+usernameFileLoginModule passwordFileLoginModule
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/server.cer	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKDCCAZECBEDtdcwwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCRlIxDjAM
+BgNVBAgTBUlzZXJlMREwDwYDVQQHEwhHcmVub2JsZTEMMAoGA1UEChMDU3VuMQ0w
+CwYDVQQLEwRKMlNFMQwwCgYDVQQDEwNKTVgwHhcNMDQwNzA4MTYyNjUyWhcNMzkw
+NjMwMTYyNjUyWjBbMQswCQYDVQQGEwJGUjEOMAwGA1UECBMFSXNlcmUxETAPBgNV
+BAcTCEdyZW5vYmxlMQwwCgYDVQQKEwNTdW4xDTALBgNVBAsTBEoyU0UxDDAKBgNV
+BAMTA0pNWDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnbqRH7+SCpPA2z06
+DCwDwVaJmkc5mg1nX1j8lebEnDY0OrwlZBikirt3m/cIUnRWLepIgaoFd6HfAIaP
+Lx7AyGqwEv0LqHjTo/hgehmi+oK9oJsMaDqCdIQ+Lb53Lo9ECHDHP84gkCgmQqy6
+EvKR16wiI46d9D8BDe7huIJaUGkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQARo5Fr
+4lFOzLDwUn9lH/3We+4wCbpzvHFOZBKUizv+rTk5oeZHQc+0yXHZMuzTUYShlTvK
+sYLXGUF9BahM2YFvLp40lnIfEYPlNptbJWceN5K2a41A0JoxmuoS2dhegzY6p4ED
+EpoEySMQZS3ZW2AsOQsozGW02E3GaJB7TI93gg==
+-----END CERTIFICATE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/rest/sslconfig	Mon Dec 25 20:42:05 2017 +0530
@@ -0,0 +1,5 @@
+javax.net.ssl.keyStore=keystoreAgent
+javax.net.ssl.keyStorePassword=glopglop
+javax.net.ssl.trustStore=truststoreAgent
+javax.net.ssl.trustStorePassword=glopglop
+
Binary file test/jdk/javax/management/remote/rest/truststoreAgent has changed
Binary file test/jdk/javax/management/remote/rest/truststoreClient has changed