src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java
author hb
Thu, 04 Jan 2018 14:39:04 +0530
branchjmx-rest-api
changeset 56006 352a4f213fc6
parent 56002 60ab3b595a8e
child 56007 d6cbabcaf518
permissions -rw-r--r--
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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
55997
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     1
/*
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     4
 *
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    10
 *
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    15
 * accompanied this code).
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    16
 *
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    20
 *
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    23
 * questions.
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    24
 */
f881344569d9 Added copyright header
hb
parents: 55996
diff changeset
    25
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    26
package com.oracle.jmx.remote.rest.http;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    27
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
    28
import com.oracle.jmx.remote.rest.json.JSONArray;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    29
import com.oracle.jmx.remote.rest.json.JSONElement;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    30
import com.oracle.jmx.remote.rest.json.JSONObject;
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
    31
import com.oracle.jmx.remote.rest.json.JSONPrimitive;
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
    32
import com.oracle.jmx.remote.rest.json.parser.JSONParser;
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
    33
import com.oracle.jmx.remote.rest.json.parser.ParseException;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    34
import com.oracle.jmx.remote.rest.mapper.JSONMapper;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    35
import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    36
import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    37
import com.sun.net.httpserver.HttpExchange;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    38
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    39
import javax.management.*;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    40
import javax.management.remote.rest.PlatformRestAdapter;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    41
import java.io.IOException;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    42
import java.io.UnsupportedEncodingException;
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
    43
import java.net.URLDecoder;
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
    44
import java.nio.charset.StandardCharsets;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    45
import java.util.*;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    46
import java.util.concurrent.ConcurrentHashMap;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    47
import java.util.concurrent.CopyOnWriteArrayList;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    48
import java.util.regex.Matcher;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    49
import java.util.regex.Pattern;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    50
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    51
public class MBeanCollectionResource implements RestResource, NotificationListener {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    52
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    53
    private List<ObjectName> allowedMbeans;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    54
    private final MBeanServer mBeanServer;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    55
    private final Map<String, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    56
    private static final int pageSize = 10;
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
    57
    private static final String pathPrefix = "^/?jmx/servers/[a-zA-Z0-9\\-\\.]+/mbeans";
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    58
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    59
    // Only MXBean or any other MBean that uses types
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    60
    // that have a valid mapper functions
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    61
    private boolean isMBeanAllowed(ObjectName objName) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    62
        try {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    63
            MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName);
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    64
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    65
            // Return true for MXbean
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    66
            Descriptor desc = mInfo.getDescriptor();
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    67
            String isMxBean = (String) desc.getFieldValue("mxbean");
56001
95c0323f0c1a Few bug fixes
hb
parents: 56000
diff changeset
    68
            if (isMxBean != null && isMxBean.equalsIgnoreCase("true"))
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    69
                return true;
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    70
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    71
            // Check attribute types
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    72
            MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    73
            for (MBeanAttributeInfo attrInfo : attrsInfo) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    74
                String type = attrInfo.getType();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    75
                if (!JSONMappingFactory.INSTANCE.isTypeMapped(type)) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    76
                    return false;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    77
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    78
            }
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    79
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    80
            // Check operation parameters and return types
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    81
            MBeanOperationInfo[] operations = mInfo.getOperations();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    82
            for (MBeanOperationInfo opInfo : operations) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    83
                MBeanParameterInfo[] signature = opInfo.getSignature();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    84
                for (MBeanParameterInfo sig : signature) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    85
                    if (!JSONMappingFactory.INSTANCE.isTypeMapped(sig.getType())) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    86
                        return false;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    87
                    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    88
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    89
                if (!JSONMappingFactory.INSTANCE.isTypeMapped(opInfo.getReturnType())) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    90
                    return false;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    91
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    92
            }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    93
            return true;
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    94
        } catch (InstanceNotFoundException | IntrospectionException |
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
    95
                ReflectionException | ClassNotFoundException ex) {
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    96
            ex.printStackTrace();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    97
            return false;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    98
        }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
    99
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   100
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   101
    private void introspectMBeanTypes(MBeanServer server) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   102
        if (allowedMbeans.isEmpty()) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   103
            Set<ObjectInstance> allMBeans = server.queryMBeans(null, null); // get all Mbeans
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   104
            allMBeans.stream().filter((objIns) -> (isMBeanAllowed(objIns.getObjectName())))
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   105
                    .forEachOrdered(objIns -> allowedMbeans.add(objIns.getObjectName()));
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   106
        }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   107
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   108
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   109
    @Override
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   110
    public void handleNotification(Notification notification, Object handback) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   111
        try {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   112
            MBeanServerNotification mbs = (MBeanServerNotification) notification;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   113
            if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   114
                ObjectName mBeanName = mbs.getMBeanName();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   115
                if (isMBeanAllowed(mBeanName)) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   116
                    allowedMbeans.add(mBeanName);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   117
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   118
            } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   119
                if (allowedMbeans.contains(mbs.getMBeanName().toString())) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   120
                    allowedMbeans.remove(mbs.getMBeanName().toString());
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   121
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   122
            }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   123
        } catch (Exception e) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   124
        }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   125
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   126
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   127
    public MBeanCollectionResource(MBeanServer mBeanServer) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   128
        this.mBeanServer = mBeanServer;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   129
        allowedMbeans = new ArrayList<>();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   130
        introspectMBeanTypes(mBeanServer);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   131
        allowedMbeans = new CopyOnWriteArrayList<>(allowedMbeans);
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   132
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   133
        // Create a REST handler for each MBean
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   134
        allowedMbeans.forEach(objectName -> mBeanResourceMap.put(objectName.toString(),
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   135
                new MBeanResource(mBeanServer, objectName)));
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   136
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   137
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   138
    @Override
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   139
    public void handle(HttpExchange exchange) throws IOException {
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   140
        String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName());
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   141
55995
a798bdd52997 POST : Attribute update - working
hb
parents: 55994
diff changeset
   142
        if (path.matches(pathPrefix + "/?$")) {
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   143
            RestResource.super.handle(exchange);
55995
a798bdd52997 POST : Attribute update - working
hb
parents: 55994
diff changeset
   144
        } else if (path.matches(pathPrefix + "/[^/]+/?.*")) {
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   145
            // Extract mbean name
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   146
            // Forward the request to its corresponding rest resource
55995
a798bdd52997 POST : Attribute update - working
hb
parents: 55994
diff changeset
   147
            Pattern mbeans = Pattern.compile(pathPrefix + "/");
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   148
            Matcher matcher = mbeans.matcher(path);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   149
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   150
            if (matcher.find()) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   151
                String ss = path.substring(matcher.end());
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   152
                String mBeanName = ss;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   153
                if (ss.indexOf('/') != -1) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   154
                    mBeanName = ss.substring(0, ss.indexOf('/'));
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   155
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   156
                MBeanResource mBeanResource = mBeanResourceMap.get(mBeanName);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   157
                if (mBeanResource == null) {
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   158
                    HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   159
                    return;
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   160
                }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   161
                mBeanResource.handle(exchange);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   162
            }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   163
        }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   164
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   165
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   166
    @Override
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   167
    public HttpResponse doGet(HttpExchange exchange) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   168
        try {
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   169
            final String path = PlatformRestAdapter.getDomain()
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   170
                    + URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName())
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   171
                    .replaceAll("/$", "");
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   172
            List<ObjectName> filteredMBeans = allowedMbeans;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   173
            Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange);
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   174
            String query = exchange.getRequestURI().getQuery();
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   175
            if (query != null && queryMap.isEmpty()) {
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   176
                return new HttpResponse(HttpResponse.BAD_REQUEST,
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   177
                        "Invalid query params : Allowed query keys [objectname,page]");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   178
            } else if (query != null && !queryMap.isEmpty()) {
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   179
                Map<String, String> newMap = new HashMap<>(queryMap);
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   180
                newMap.remove("objectname");
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   181
                newMap.remove("page");
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   182
                if (!newMap.isEmpty()) { // Invalid query params
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   183
                    return new HttpResponse(HttpResponse.BAD_REQUEST,
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   184
                            "Invalid query params : Allowed query keys [objectname,page]");
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   185
                }
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   186
            }
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   187
            if (queryMap.containsKey("objectname")) {        // Filter based on ObjectName query
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   188
                Set<ObjectName> queryMBeans = mBeanServer
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   189
                        .queryNames(new ObjectName(queryMap.get("objectname")), null);
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   190
                queryMBeans.retainAll(allowedMbeans);   // Intersection of two lists
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   191
                filteredMBeans = new ArrayList<>(queryMBeans);
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   192
            }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   193
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   194
            JSONObject _links = HttpUtil.getPaginationLinks(exchange, filteredMBeans, pageSize);
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   195
            List<ObjectName> mbeanPage = HttpUtil.filterByPage(exchange, filteredMBeans, pageSize);
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   196
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   197
            List<Map<String, String>> items = new ArrayList<>(filteredMBeans.size());
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   198
            for (ObjectName objectName : mbeanPage) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   199
                Map<String, String> item = new LinkedHashMap<>();
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   200
                item.put("name", objectName.toString());
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   201
                MBeanResource mBeanResource = mBeanResourceMap.get(objectName.toString());
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   202
                try {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   203
                    JSONObject mBeanInfo = mBeanResource.getMBeanInfo(mBeanServer, objectName);
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   204
                    JSONElement element = mBeanInfo.get("descriptor");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   205
                    if (element != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   206
                        JSONElement element1 = ((JSONObject) element).get("interfaceClassName");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   207
                        if (element1 != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   208
                            String intfName = (String) ((JSONPrimitive) element1).getValue();
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   209
                            item.put("interfaceClassName", intfName);
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   210
                        }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   211
                    }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   212
                    element = mBeanInfo.get("className");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   213
                    if (element != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   214
                        String className = (String) ((JSONPrimitive) element).getValue();
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   215
                        item.put("className", className);
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   216
                    }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   217
                    element = mBeanInfo.get("description");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   218
                    if (element != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   219
                        String description = (String) ((JSONPrimitive) element).getValue();
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   220
                        item.put("description", description);
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   221
                    }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   222
                    element = mBeanInfo.get("attributeInfo");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   223
                    if(element != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   224
                        item.put("attributeCount", ((JSONArray)element).size() + "");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   225
                    }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   226
                    element = mBeanInfo.get("operationInfo");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   227
                    if(element != null) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   228
                        item.put("operationCount", ((JSONArray)element).size() + "");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   229
                    }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   230
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   231
                } catch (InstanceNotFoundException | IntrospectionException | ReflectionException e) {
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   232
                }
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   233
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   234
                String href = path + "/" + objectName.toString();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   235
                href = HttpUtil.escapeUrl(href);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   236
                item.put("href", href);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   237
                items.add(item);
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   238
                String info = HttpUtil.escapeUrl(href + "/info");
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   239
                item.put("info", info);
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   240
            }
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   241
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   242
            Map<String, String> properties = new HashMap<>();
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   243
56002
60ab3b595a8e Lot of bug fixes
hb
parents: 56001
diff changeset
   244
            properties.put("mbeanCount", Integer.toString(filteredMBeans.size()));
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   245
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   246
            JSONMapper typeMapper1 = JSONMappingFactory.INSTANCE.getTypeMapper(items);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   247
            JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   248
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   249
            JSONElement linkElem = typeMapper1.toJsonValue(items);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   250
            JSONElement propElem = typeMapper2.toJsonValue(properties);
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   251
            JSONObject jobj = new JSONObject();
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   252
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   253
            jobj.putAll((JSONObject) propElem);
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   254
            jobj.put("mbeans", linkElem);
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   255
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   256
            if (_links != null && !_links.isEmpty()) {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   257
                jobj.put("_links", _links);
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   258
            }
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   259
            return new HttpResponse(jobj.toJsonString());
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   260
        } catch (JSONMappingException e) {
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   261
            return HttpResponse.SERVER_ERROR;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   262
        } catch (UnsupportedEncodingException e) {
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   263
            return HttpResponse.BAD_REQUEST;
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   264
        } catch (MalformedObjectNameException e) {
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   265
            return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   266
        }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   267
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   268
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   269
    @Override
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   270
    public HttpResponse doPost(HttpExchange exchange) {
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   271
        try {
56006
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   272
            String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName());
352a4f213fc6 1. URL decoding of URL
hb
parents: 56002
diff changeset
   273
            String reqBody = null;
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   274
            if (path.matches(pathPrefix + "/?$")) { // POST to current URL
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   275
                reqBody = HttpUtil.readRequestBody(exchange);
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   276
                if (reqBody == null || reqBody.isEmpty()) { // No Parameters
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   277
                    return HttpResponse.BAD_REQUEST;
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   278
                }
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   279
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   280
                JSONParser parser = new JSONParser(reqBody);
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   281
                JSONElement jsonElement = parser.parse();
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   282
                if (!(jsonElement instanceof JSONObject)) {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   283
                    return new HttpResponse(HttpResponse.BAD_REQUEST,
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   284
                            "Invalid parameters : [" + reqBody + "]");
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   285
                }
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   286
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   287
                JSONObject jsonObject = (JSONObject) jsonElement;
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   288
                JSONObject result = new JSONObject();
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   289
                for (String mBeanName : jsonObject.keySet()) {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   290
                    MBeanResource mBeanResource = mBeanResourceMap.get(mBeanName);
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   291
                    if (mBeanResource != null) {
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   292
                        JSONElement element = jsonObject.get(mBeanName);
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   293
                        if (element instanceof JSONObject) {
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   294
                            JSONElement res = mBeanResource.handleBulkRequest
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   295
                                    ((JSONObject) element);
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   296
                            result.put(mBeanName, res);
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   297
                        } else {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   298
                            result.put(mBeanName, "Invalid input");
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   299
                        }
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   300
                    } else {
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   301
                        result.put(mBeanName, "Invalid MBean");
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   302
                    }
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   303
                }
56000
054866e5113c Code cleanup - MBeanColl*Resource, MBeanResource
hb
parents: 55997
diff changeset
   304
                return new HttpResponse(result.toJsonString());
55996
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   305
            } else {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   306
                return HttpResponse.METHOD_NOT_ALLOWED;
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   307
            }
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   308
        } catch (ParseException e) {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   309
            return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid JSON String for request body");
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   310
        } catch (IOException e) {
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   311
            return HttpResponse.BAD_REQUEST;
e8d4ccaf6877 Bulk operation at MBeanServer level
hb
parents: 55995
diff changeset
   312
        }
55994
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   313
    }
9721e36abeb0 Implementation of GET for new APIs
hb
parents:
diff changeset
   314
}