# HG changeset patch # User hb # Date 1515056944 -19800 # Node ID 352a4f213fc629b65ea3f0bfc5285debd1b8f0c5 # Parent 90cff2ac77b840e52553056f334bd30c8dfa6c07 1. URL decoding of URL 2. MBean info availble in MBeanCollection page 3. MBeanCollection post supports objectname filtering 4. Tests now use reflection instead of Methodhndles 3. couple of bug fixes diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java Thu Jan 04 14:39:04 2018 +0530 @@ -35,6 +35,7 @@ import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.LinkedHashMap; import java.util.List; @@ -91,16 +92,13 @@ public static Map 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 queryParams = new LinkedHashMap<>(); if (query == null || query.isEmpty()) { return queryParams; } + query = URLDecoder.decode(query, StandardCharsets.UTF_8.displayName()); String[] params = query.trim().split("&"); for (String param : params) { int idx = param.indexOf('='); @@ -148,7 +146,11 @@ String msg = charset == null ? response.getBody() : URLEncoder.encode(response.getBody(), charset); byte[] bytes = msg.getBytes(); Headers resHeaders = exchange.getResponseHeaders(); - resHeaders.add("Content-Type", "application/json; charset=" + charset); + if(charset != null && !charset.isEmpty()) { + resHeaders.add("Content-Type", "application/json; charset=" + charset); + } else { + resHeaders.add("Content-Type", "application/json;"); + } exchange.sendResponseHeaders(response.getCode(), bytes.length); try (OutputStream os = exchange.getResponseBody()) { diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java Thu Jan 04 14:39:04 2018 +0530 @@ -25,8 +25,10 @@ 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.json.parser.JSONParser; import com.oracle.jmx.remote.rest.json.parser.ParseException; import com.oracle.jmx.remote.rest.mapper.JSONMapper; @@ -38,7 +40,8 @@ import javax.management.remote.rest.PlatformRestAdapter; import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -134,7 +137,8 @@ @Override public void handle(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); + String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName()); + if (path.matches(pathPrefix + "/?$")) { RestResource.super.handle(exchange); } else if (path.matches(pathPrefix + "/[^/]+/?.*")) { @@ -161,27 +165,28 @@ @Override public HttpResponse doGet(HttpExchange exchange) { - final String path = PlatformRestAdapter.getDomain() - + exchange.getRequestURI().getPath().replaceAll("/$", ""); try { + final String path = PlatformRestAdapter.getDomain() + + URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName()) + .replaceAll("/$", ""); List filteredMBeans = allowedMbeans; Map queryMap = HttpUtil.getGetRequestQueryMap(exchange); String query = exchange.getRequestURI().getQuery(); - if(query != null && queryMap.isEmpty()) { + if (query != null && queryMap.isEmpty()) { return new HttpResponse(HttpResponse.BAD_REQUEST, - "Invalid query params : Allowed query keys [query,page]"); - }else if(query != null && !queryMap.isEmpty()) { + "Invalid query params : Allowed query keys [objectname,page]"); + } else if (query != null && !queryMap.isEmpty()) { Map newMap = new HashMap<>(queryMap); - newMap.remove("query"); + newMap.remove("objectname"); newMap.remove("page"); - if(!newMap.isEmpty()) { // Invalid query params + if (!newMap.isEmpty()) { // Invalid query params return new HttpResponse(HttpResponse.BAD_REQUEST, - "Invalid query params : Allowed query keys [query,page]"); + "Invalid query params : Allowed query keys [objectname,page]"); } } - if (queryMap.containsKey("query")) { // Filter based on ObjectName query + if (queryMap.containsKey("objectname")) { // Filter based on ObjectName query Set queryMBeans = mBeanServer - .queryNames(new ObjectName(queryMap.get("query")), null); + .queryNames(new ObjectName(queryMap.get("objectname")), null); queryMBeans.retainAll(allowedMbeans); // Intersection of two lists filteredMBeans = new ArrayList<>(queryMBeans); } @@ -190,14 +195,49 @@ List mbeanPage = HttpUtil.filterByPage(exchange, filteredMBeans, pageSize); List> items = new ArrayList<>(filteredMBeans.size()); - mbeanPage.forEach(objectName -> { - Map item = new LinkedHashMap<>(2); + for (ObjectName objectName : mbeanPage) { + Map item = new LinkedHashMap<>(); item.put("name", objectName.toString()); + MBeanResource mBeanResource = mBeanResourceMap.get(objectName.toString()); + try { + JSONObject mBeanInfo = mBeanResource.getMBeanInfo(mBeanServer, objectName); + JSONElement element = mBeanInfo.get("descriptor"); + if (element != null) { + JSONElement element1 = ((JSONObject) element).get("interfaceClassName"); + if (element1 != null) { + String intfName = (String) ((JSONPrimitive) element1).getValue(); + item.put("interfaceClassName", intfName); + } + } + element = mBeanInfo.get("className"); + if (element != null) { + String className = (String) ((JSONPrimitive) element).getValue(); + item.put("className", className); + } + element = mBeanInfo.get("description"); + if (element != null) { + String description = (String) ((JSONPrimitive) element).getValue(); + item.put("description", description); + } + element = mBeanInfo.get("attributeInfo"); + if(element != null) { + item.put("attributeCount", ((JSONArray)element).size() + ""); + } + element = mBeanInfo.get("operationInfo"); + if(element != null) { + item.put("operationCount", ((JSONArray)element).size() + ""); + } + + } catch (InstanceNotFoundException | IntrospectionException | ReflectionException e) { + } + String href = path + "/" + objectName.toString(); href = HttpUtil.escapeUrl(href); item.put("href", href); items.add(item); - }); + String info = HttpUtil.escapeUrl(href + "/info"); + item.put("info", info); + } Map properties = new HashMap<>(); @@ -228,9 +268,9 @@ @Override public HttpResponse doPost(HttpExchange exchange) { - String path = exchange.getRequestURI().getPath(); - String reqBody = null; try { + String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName()); + String reqBody = null; if (path.matches(pathPrefix + "/?$")) { // POST to current URL reqBody = HttpUtil.readRequestBody(exchange); if (reqBody == null || reqBody.isEmpty()) { // No Parameters diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java Thu Jan 04 14:39:04 2018 +0530 @@ -31,6 +31,7 @@ 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 com.oracle.jmx.remote.rest.json.parser.TokenMgrError; import com.oracle.jmx.remote.rest.mapper.JSONDataException; import com.oracle.jmx.remote.rest.mapper.JSONMapper; import com.oracle.jmx.remote.rest.mapper.JSONMappingException; @@ -44,6 +45,8 @@ import javax.management.remote.rest.PlatformRestAdapter; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -79,7 +82,7 @@ @Override public void handle(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); + String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName()); if (path.matches(pathPrefix + "/?$")) { RestResource.super.handle(exchange); } else if (path.matches(pathPrefix + "/info$") @@ -98,16 +101,17 @@ String path = PlatformRestAdapter.getDomain() + exchange.getRequestURI().getPath().replaceAll("/$", ""); - if (path.endsWith("info")) { - return doMBeanInfo(); - } + try { + path = URLDecoder.decode(path, StandardCharsets.UTF_8.displayName()); + if (path.endsWith("info")) { + return doMBeanInfo(); + } - String infoPath = path + "/info"; + String infoPath = path + "/info"; - try { Map allAttributes = getAllAttributes(); Map _links = new LinkedHashMap<>(); - _links.put("info", HttpUtil.escapeUrl(infoPath)); + //_links.put("info", HttpUtil.escapeUrl(infoPath)); MBeanOperationInfo[] opInfo = mBeanServer.getMBeanInfo(objectName).getOperations(); JSONArray jarr = new JSONArray(); @@ -136,7 +140,6 @@ JSONObject jobj = new JSONObject(); jobj.put("attributes", jsonElement1); jobj.put("operations", jarr); - jobj.put("_links", jsonElement2); return new HttpResponse(jobj.toJsonString()); } else { return HttpResponse.SERVER_ERROR; @@ -222,7 +225,7 @@ } } catch (InstanceNotFoundException e) { // Should never happen - } catch (JSONDataException | ParseException e) { + } catch (JSONDataException | ParseException | TokenMgrError e) { return new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid JSON : " + reqBody, e.getMessage()); } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException | IOException e) { return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e)); @@ -354,7 +357,7 @@ return result; } - private JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean) + JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean) throws InstanceNotFoundException, IntrospectionException, ReflectionException { JSONObject jobj = new JSONObject(); diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java Thu Jan 04 14:39:04 2018 +0530 @@ -33,6 +33,8 @@ import javax.management.remote.rest.PlatformRestAdapter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -57,9 +59,16 @@ if (filteredList == null) { return HttpResponse.OK; } - - final String path = PlatformRestAdapter.getDomain() + - exchange.getRequestURI().getPath().replaceAll("/$", ""); + String query = exchange.getRequestURI().getQuery(); + if (query != null) { + return HttpResponse.BAD_REQUEST; + } + String exchangePath = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName()) + .replaceAll("/$", ""); + if (!exchangePath.equalsIgnoreCase("/jmx/servers")) { + return HttpResponse.REQUEST_NOT_FOUND; + } + final String path = PlatformRestAdapter.getDomain() + exchangePath; JSONObject root = new JSONObject(); if (_links != null && !_links.isEmpty()) { diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerResource.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerResource.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerResource.java Thu Jan 04 14:39:04 2018 +0530 @@ -50,6 +50,8 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.HttpURLConnection; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; @@ -157,7 +159,7 @@ } } - String path = exchange.getRequestURI().getPath(); + String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName()); String pathPrefix = httpContext.getPath(); // Route request to appropriate resource if (path.matches(pathPrefix + "/?$")) { diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java Thu Jan 04 14:39:04 2018 +0530 @@ -31,6 +31,7 @@ import java.io.IOException; /** + * * @author harsha */ public interface RestResource extends HttpHandler { diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONPrimitive.java --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONPrimitive.java Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONPrimitive.java Thu Jan 04 14:39:04 2018 +0530 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.oracle.jmx.remote.rest.json; /** diff -r 90cff2ac77b8 -r 352a4f213fc6 src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JsonParser.jj --- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JsonParser.jj Tue Jan 02 15:03:52 2018 +0530 +++ b/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JsonParser.jj Thu Jan 04 14:39:04 2018 +0530 @@ -85,7 +85,7 @@ | < #DIGITS : ()+> | < #DIGIT: ["0"-"9"]> | -| +| | } diff -r 90cff2ac77b8 -r 352a4f213fc6 test/jdk/javax/management/remote/rest/RestAdapterConfigTest.java --- a/test/jdk/javax/management/remote/rest/RestAdapterConfigTest.java Tue Jan 02 15:03:52 2018 +0530 +++ b/test/jdk/javax/management/remote/rest/RestAdapterConfigTest.java Thu Jan 04 14:39:04 2018 +0530 @@ -8,13 +8,14 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.io.*; +import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.KeyStore; -import java.util.ArrayList; -import java.util.List; import java.util.Properties; - +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; /* @test * @summary Configuration test for rest adapter @@ -33,20 +34,13 @@ private static String sslClientConfig; private static String passwordFile; private static String configFile; - private static final List tasks = new ArrayList<>(); - private static RestAdapterTest test = new RestAdapterTest(); + private static RestAdapterTest restAdapterTest = new RestAdapterTest(); + private static final Set tests; static { - tasks.add(test::testAllMBeanServers); - tasks.add(test::testAllMBeanInfo); - tasks.add(test::testAllMBeans); - tasks.add(test::testMBeanFiltering); - tasks.add(test::testMBeanGetAttributes); - tasks.add(test::testMBeanSetAttributes); - tasks.add(test::testMbeanNoArgOperations); - tasks.add(test::testAllMBeansBulkRequest); - tasks.add(test::testThreadMXBeanBulkRequest); - tasks.add(test::testThreadMXBeanThreadInfo); + tests = Stream.of(RestAdapterTest.class.getMethods()) + .filter(a -> a.getName().startsWith("test")) + .collect(Collectors.toSet()); } private void createAgentSslConfigFile(String fileName) throws IOException { @@ -183,30 +177,38 @@ @Test public void testHttpNoAuth() throws Exception { setupMgmtConfig(configFile, false, false); - test.setupServers(); - tasks.forEach(Runnable::run); - test.tearDownServers(); + restAdapterTest.setupServers(); + for (Method m : tests) { + m.invoke(restAdapterTest); + } + restAdapterTest.tearDownServers(); } public void testHttpsNoAuth() throws Exception { setupMgmtConfig(configFile, true, false); - test.setupServers(); - tasks.forEach(Runnable::run); - test.tearDownServers(); + restAdapterTest.setupServers(); + for (Method m : tests) { + m.invoke(restAdapterTest); + } + restAdapterTest.tearDownServers(); } public void testHttpAuth() throws Exception { setupMgmtConfig(configFile, false, true); - test.setupServers(); - tasks.forEach(Runnable::run); - test.tearDownServers(); + restAdapterTest.setupServers(); + for (Method m : tests) { + m.invoke(restAdapterTest); + } + restAdapterTest.tearDownServers(); } public void testHttpsAuth() throws Exception { setupMgmtConfig(configFile, true, true); - test.setupServers(); - tasks.forEach(Runnable::run); - test.tearDownServers(); + restAdapterTest.setupServers(); + for (Method m : tests) { + m.invoke(restAdapterTest); + } + restAdapterTest.tearDownServers(); } @AfterClass @@ -221,4 +223,5 @@ if (f.exists()) f.delete(); } + } diff -r 90cff2ac77b8 -r 352a4f213fc6 test/jdk/javax/management/remote/rest/RestAdapterPerfTest.java --- a/test/jdk/javax/management/remote/rest/RestAdapterPerfTest.java Tue Jan 02 15:03:52 2018 +0530 +++ b/test/jdk/javax/management/remote/rest/RestAdapterPerfTest.java Thu Jan 04 14:39:04 2018 +0530 @@ -10,20 +10,17 @@ * @run testng/othervm RestAdapterPerfTest */ +import java.lang.reflect.InvocationTargetException; import jdk.test.lib.Utils; -import jdk.test.lib.process.ProcessTools; -import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; -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 @@ -35,18 +32,14 @@ @Test public void testMultipleClients() throws Exception { RestAdapterTest test = new RestAdapterTest(); - List tasks = new ArrayList<>(); - - tasks.add(test::testAllMBeanServers); - tasks.add(test::testAllMBeanInfo); - tasks.add(test::testAllMBeans); - tasks.add(test::testMBeanFiltering); - tasks.add(test::testMBeanGetAttributes); - tasks.add(test::testMBeanSetAttributes); - tasks.add(test::testMbeanNoArgOperations); - tasks.add(test::testAllMBeansBulkRequest); - tasks.add(test::testThreadMXBeanBulkRequest); - tasks.add(test::testThreadMXBeanThreadInfo); + List tasks = Stream.of(RestAdapterTest.class.getMethods()) + .filter(m -> m.getName().startsWith("test")).map(m -> (Runnable)() -> { + try { + m.invoke(test); + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + }).collect(Collectors.toList()); ThreadPoolExecutor es = (ThreadPoolExecutor) Executors.newFixedThreadPool(20); es.setThreadFactory((Runnable R) -> new Thread(R, "perf-" + count.getAndIncrement())); diff -r 90cff2ac77b8 -r 352a4f213fc6 test/jdk/javax/management/remote/rest/RestAdapterTest.java --- a/test/jdk/javax/management/remote/rest/RestAdapterTest.java Tue Jan 02 15:03:52 2018 +0530 +++ b/test/jdk/javax/management/remote/rest/RestAdapterTest.java Thu Jan 04 14:39:04 2018 +0530 @@ -75,7 +75,7 @@ try { MBeanServerConnection mBeanServer = connector.getMBeanServerConnection(); Set objectInstances = mBeanServer.queryMBeans(null, null); - return objectInstances.stream().map(a -> a.getObjectName().toString()).collect(Collectors.toSet()); + return objectInstances.stream().map(a -> a.getObjectName().getCanonicalName()).collect(Collectors.toSet()); } catch (Exception ex) { throw new RuntimeException(ex); } @@ -149,6 +149,12 @@ JSONPrimitive jp = (JSONPrimitive) jobj.get("name"); String name = (String) jp.getValue(); mbeanNames.add(name); + JSONPrimitive jhref = (JSONPrimitive) jobj.get("href"); + String href = (String) jhref.getValue(); + verifyHttpResponse(executeHttpRequest(href)); + JSONPrimitive jinfo = (JSONPrimitive) jobj.get("info"); + String info = (String) jinfo.getValue(); + verifyHttpResponse(executeHttpRequest(info)); } JSONObject linkObj = (JSONObject) root.get("_links"); @@ -395,12 +401,12 @@ public void testMBeanFiltering() { String url = restUrl + "/platform/mbeans?"; - List filtersOk = Arrays.asList("query=*:type=DiagnosticCommand,*", - "query=java.lang:*&page=2", - "query=java.lang:*&page=1", - "query=*:type=Diag*"); + List filtersOk = Arrays.asList("objectname=*:type=DiagnosticCommand,*", + "objectname=java.lang:*&page=2", + "objectname=java.lang:*&page=1", + "objectname=*:type=Diag*"); - List filtersKo = Arrays.asList("","*:type=DiagnosticCommand,*","query=java.lang:*&page=1&invalid=4"); + List filtersKo = Arrays.asList("","*:type=DiagnosticCommand,*","objectname=java.lang:*&page=1&invalid=4"); for(String filter : filtersOk) { HttpResponse httpResponse = executeHttpRequest(url + filter); @@ -458,7 +464,7 @@ MBeanServerConnection mBeanServer = connector.getMBeanServerConnection(); for (String name : mbeans) { ObjectName objectName = new ObjectName(name); - String url = "/platform/mbeans/" + objectName.toString(); + String url = "/platform/mbeans/" + objectName.getCanonicalName(); JSONObject attrMap = restGetAttributes(name); MBeanAttributeInfo[] attrInfos = mBeanServer.getMBeanInfo(objectName).getAttributes(); Set writableAttrs = Stream.of(attrInfos) @@ -663,4 +669,12 @@ HttpResponse httpResponse = executeHttpRequest(url, result.toJsonString(), true); verifyHttpResponse(httpResponse); } + + @Test(priority = 6) + public void testMbeansQueryBulkRequest() { + String url = restUrl + "/platform/mbeans"; + String request = "{\"?*:type=MemoryPool,*\":{\"attributes\":{\"get\":[\"Name\",\"Usage\"]},\"operations\":\"resetPeakUsage\"},\"java.lang:name=Compressed Class Space,type=MemoryPool\":{\"attributes\":{\"get\":[\"MemoryManagerNames\"]}}}"; + HttpResponse httpResponse = executeHttpRequest(url, request, true); + verifyHttpResponse(httpResponse); + } } \ No newline at end of file