////
  Copyright 2009-2023 Roland Huss

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
////

[#list]
=== Listing MBeans (list)

The list operation collects information about available
MBeans. This information includes the MBean names, their
attributes, operations and notifications along with type
information and description (as far as they are provided by the
MBean author which doesn't seem to be often the case).

[#get-list]
==== GET list request

The GET request format for a Jolokia list request is

----
<base-url>/list/<inner path>
----

The `<inner path>`, as described in xref:jolokia_protocol.adoc#paths[Paths]
specifies a subset of the complete response. You can
use this to select a specific domain, MBean or
attribute/operation. See the next section for the format of the
complete response.      

[#post-list]
==== POST list request

A list POST request has the following keys:

.POST list Request
[cols="15,~,30"]
|===
|Key|Description|Example

|`type`
|*`list`*
|

|`path`
|Inner path for accessing the value of a subset of the complete list
xref:jolokia_protocol.adoc#paths[Paths]).

|`java.lang/type=Memory/attr`
|===

The following request fetches the information about the MBean `java.lang:type=Memory`

[,json]
----
{
  "type": "list",
  "path": "java.lang/type=Memory"
}
----

[#response-list]
==== List response

The `value` has the following format:

[,json]
----
{
  "<domain>": {
    "<prop list>": {
      "attr": {
        "<attr name>": {
          "type": "<attribute type>",
          "desc": "<textual description of attribute>",
          "rw": "true|false"
        },
        ...
      },
      "op": {
        "<operation name>": {
          "args": [
            {
              "type": "<argument type>",
              "name": "<argument name>",
              "desc": "<textual description of argument>"
            },
            ...
          ],
          "ret": "<return type>",
          "desc": "<textual description of operation>"
        },
        ...
      },
      "notif": {
        "<notification type>": {
            "name": "<name>",
            "desc": "<desc>",
            "types": [ "<type1>", "<type2>", ... ]
        },
        ...
      },
      "class": "fully qualified class name",
      "desc": "description",
      "ctor": {
        ...
      },
      "interfaces": [
        ...
      ]
    },
    ...
  },
  ...
}
----

The `domain name` and the `property
list` together uniquely identify a single MBean. The
property list is in the so called _canonical
order_, i.e. in the form
`"<key1>=<val1>,<key2>=<val2>,.."`
where the keys are ordered alphabetically. Each MBean has zero
or more attributes and operations which can be reached in an
MBeans JSON object with the keys `attr` and
`op` respectively. Within these groups the
contained information is explained above in the schema and
consist of Java types for attributes, arguments and return
values, descriptive information and whether an attribute is
writable (`rw` == `true`) or
read-only.

As for reading attributes you can fetch a subset of this information using an
path. E.g a path of `domain/prop-list` would return the value for a single
bean only. For example, a request 

----
http://localhost:8080/jolokia/list/java.lang/type=Memory
----

results in an answer

[,json]
----
{
  "request": {
    "path": "java.lang/type=Memory",
    "type": "list"
  },
  "value": {
    "op": {
      "gc": {
        "args": [],
        "ret": "void",
        "desc": "gc"
      }
    },
    "notif": {
      "javax.management.Notification": {
        "types": [
          "java.management.memory.threshold.exceeded",
          "java.management.memory.collection.threshold.exceeded"
        ],
        "name": "javax.management.Notification",
        "desc": "Memory Notification"
      }
    },
    "attr": {
      "ObjectPendingFinalizationCount": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "int",
        "desc": "ObjectPendingFinalizationCount"
      },
      "Verbose": {
        "r": true,
        "rw": true,
        "w": true,
        "is": true,
        "type": "boolean",
        "desc": "Verbose"
      },
      "HeapMemoryUsage": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "javax.management.openmbean.CompositeData",
        "desc": "HeapMemoryUsage"
      },
      "NonHeapMemoryUsage": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "javax.management.openmbean.CompositeData",
        "desc": "NonHeapMemoryUsage"
      },
      "ObjectName": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "javax.management.ObjectName",
        "desc": "ObjectName"
      }
    },
    "class": "sun.management.MemoryImpl",
    "desc": "Information on the management interface of the MBean"
  },
  "status": 200,
  "timestamp": 1770643662
}
----

NOTE:: Since Jolokia 2.1.0 we can use `includeRequest` parameter to tell Jolokia to exclude `request` field from the response.

==== Restrict the depth of the returned tree

The optional parameter `maxDepth` can be used
to restrict the depth of the return tree. Two value are
possible: A `maxDepth` of `1` restricts the
return value to a map with the JMX domains as keys, a
`maxDepth` of `2` truncates the map returned to
the domain names (first level) and the MBean's properties
(second level). The final values of the maps don't have any
meaning and are dummy values.

==== Extension points

When returning `list()` results, Jolokia translates each MBean's `javax.management.MBeanInfo` information into a JSON fragment. Standard fields of this fragment are:

* `class` - information about the class of an MBean
* `desc` - the description
* `attr` - attributes of an MBean
* `op` - operations of an MBean
* `notif` - notifications supported by an MBean
* `ctor` - constructors of an MBean

These fields are added by default, built-in implementations of `org.jolokia.server.core.service.api.DataUpdater`.

Since Jolokia 2.1.0 we can now discover (using `/META-INF/jolokia/services`) additional services of `org.jolokia.server.core.service.api.DataUpdater` class which can be used to construct (or override) additional fields of MBean's JSON information. +
Potential use-case may be information related to RBAC (Role-based Access Control).

One additional built-in _data updater_ is `org.jolokia.service.jmx.handler.list.ListKeysDataUpdater` which can be enabled using `listKeys=true` processing parameter. We can use it to get additional `"keys"` MBeanInfo containing keys obtained from MBean's ObjectName. For example:

[,json]
----
{
  "request": {
    "path": "java.lang",
    "type": "list"
  },
  "value": {
    "name=G1 Survivor Space,type=MemoryPool": {
      ...
      "keys": {
        "name": "G1 Survivor Space",
        "type": "MemoryPool"
      },
...
----

Since Jolokia 2.5.0, we can use `listInterfaces=true` parameter to get information about the interfaces implemented by an MBean:

[,json]
----
{
  "request": {
    "path": "java.lang/type=Memory",
    "type": "list"
  },
  "value": {
    ...
    "interfaces": [
      "javax.management.NotificationEmitter",
      "java.lang.management.PlatformManagedObject",
      "javax.management.NotificationBroadcaster",
      "java.lang.management.MemoryMXBean"
    ],
    ...
----

Another big addition to Jolokia 2.5.0 is new processing parameter. When sending `openTypes=true`, we get full information about
the composite/tabular Open Types used by the MBean (attributes or method parameters and return values). For example:

[,json]
----
{
  "request": {
    "path": "java.lang/type=Memory",
    "type": "list"
  },
  "value": {
    ...
    "attr": {
      "ObjectPendingFinalizationCount": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "int",
        "desc": "ObjectPendingFinalizationCount",
        "openType": "java.lang.Integer"
      },
      "Verbose": {
        "r": true,
        "rw": true,
        "w": true,
        "is": true,
        "type": "boolean",
        "desc": "Verbose",
        "openType": "java.lang.Boolean"
      },
      "HeapMemoryUsage": {
        "r": true,
        "rw": false,
        "w": false,
        "is": false,
        "type": "javax.management.openmbean.CompositeData",
        "desc": "HeapMemoryUsage",
        "openType": {
          "kind": "composite",
          "type": "java.lang.management.MemoryUsage",
          "class": "javax.management.openmbean.CompositeData",
          "items": {
            "init": "java.lang.Long",
            "committed": "java.lang.Long",
            "max": "java.lang.Long",
            "used": "java.lang.Long"
          },
          "desc": "java.lang.management.MemoryUsage"
        }
      },
      ...
----

In the above example, we can see the actual type structure of `HeapMemoryUsage` attribute.

[#optimized-response-list]
==== Optimized List response

Since Jolokia 2.1.0 we provide now `listCache` request processing parameter. When this parameter is set to `true` (it's `false` for backward compatibility), `list()` response has different format - instead of a structure like:

----
domain:
  mbean:
    op:
    attr:
    notif:
    class:
    desc:
  ...
...
----

we now have:

----
"domains":
  domain:
    mbean: cache-key
    ...
  ...
"cache":
  cache-key:
    op:
    attr:
    notif:
    class:
    desc:
  ...
----

Effectively:

* domain → mbean tree is moved 1 level down under `"domains"` field of `list()` response
* mbean _may_ contain known `op`, `attr`, ... fields, but may also be just a _cache key_ pointing to `op`, `attr`, ... data stored under this _key_ under `"cache"` field of `list()` response
* the _cache keys_ are generated by `org.jolokia.service.jmx.api.CacheKeyProvider` services/extensions
