From 8247ab85175d1c4869bd817c0ffc34536d799f32 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Thu, 1 Nov 2018 23:10:06 +0000
Subject: [PATCH] Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62871
 Improve MBeans for Endpoint instances (type ThreadPool in JMX) by using
 explicit declaration of attributes and operations rather than relying on
 introspection. Add a new MBean to expose the Socketproperties values.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc8.5.x/trunk@1845520 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/tomcat/util/net/AbstractEndpoint.java   |   6 +
 .../apache/tomcat/util/net/SocketProperties.java   |  11 +
 .../apache/tomcat/util/net/mbeans-descriptors.xml  | 675 +++++++++++++++++++++
 .../apache/catalina/mbeans/TestRegistration.java   |   3 +
 webapps/docs/changelog.xml                         |   6 +
 5 files changed, 701 insertions(+)
 create mode 100644 java/org/apache/tomcat/util/net/mbeans-descriptors.xml

Index: apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/AbstractEndpoint.java
===================================================================
--- apache-tomcat-9.0.12-src.orig/java/org/apache/tomcat/util/net/AbstractEndpoint.java
+++ apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/AbstractEndpoint.java
@@ -1049,6 +1049,11 @@ public abstract class AbstractEndpoint<S
             oname = new ObjectName(domain + ":type=ThreadPool,name=\"" + getName() + "\"");
             Registry.getRegistry(null, null).registerComponent(this, oname, null);
 
+            ObjectName socketPropertiesOname = new ObjectName(domain +
+                    ":type=ThreadPool,name=\"" + getName() + "\",subType=SocketProperties");
+            socketProperties.setObjectName(socketPropertiesOname);
+            Registry.getRegistry(null, null).registerComponent(socketProperties, socketPropertiesOname, null);
+
             for (SSLHostConfig sslHostConfig : findSslHostConfigs()) {
                 registerJmx(sslHostConfig);
             }
@@ -1167,6 +1172,7 @@ public abstract class AbstractEndpoint<S
         }
         Registry registry = Registry.getRegistry(null, null);
         registry.unregisterComponent(oname);
+        registry.unregisterComponent(socketProperties.getObjectName());
         for (SSLHostConfig sslHostConfig : findSslHostConfigs()) {
             unregisterJmx(sslHostConfig);
         }
Index: apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/SocketProperties.java
===================================================================
--- apache-tomcat-9.0.12-src.orig/java/org/apache/tomcat/util/net/SocketProperties.java
+++ apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/SocketProperties.java
@@ -24,6 +24,8 @@ import java.net.StandardSocketOptions;
 import java.nio.channels.AsynchronousServerSocketChannel;
 import java.nio.channels.AsynchronousSocketChannel;
 
+import javax.management.ObjectName;
+
 /**
  * Properties that can be set in the &lt;Connector&gt; element
  * in server.xml. All properties are prefixed with &quot;socket.&quot;
@@ -173,6 +175,9 @@ public class SocketProperties {
      */
     protected int unlockTimeout = 250;
 
+    private ObjectName oname = null;
+
+
     public void setProperties(Socket socket) throws SocketException{
         if (rxBufSize != null)
             socket.setReceiveBufferSize(rxBufSize.intValue());
@@ -421,5 +426,11 @@ public class SocketProperties {
         this.unlockTimeout = unlockTimeout;
     }
 
+    void setObjectName(ObjectName oname) {
+        this.oname = oname;
+    }
 
+    ObjectName getObjectName() {
+        return oname;
+    }
 }
Index: apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/mbeans-descriptors.xml
===================================================================
--- /dev/null
+++ apache-tomcat-9.0.12-src/java/org/apache/tomcat/util/net/mbeans-descriptors.xml
@@ -0,0 +1,675 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<mbeans-descriptors>
+
+  <mbean         name="NioEndpoint"
+            className="org.apache.catalina.mbeans.ClassNameMBean"
+               domain="Catalina"
+                group="ThreadPool"
+                 type="org.apache.tomcat.util.net.NioEndpoint">
+
+    <attribute   name="acceptCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadPriority"
+                 type="int"/>
+
+    <attribute   name="alpnSupported"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="bindOnInit"
+                 type="boolean"/>
+
+    <attribute   name="connectionCount"
+                 type="long"
+            writeable="false"/>
+
+    <attribute   name="connectionLinger"
+                 type="int"/>
+
+    <attribute   name="connectionTimeout"
+                 type="int"/>
+
+    <attribute   name="currentThreadCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="currentThreadsBusy"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="daemon"
+                 type="boolean"/>
+
+    <attribute   name="defaultSSLHostConfigName"
+                 type="java.lang.String"/>
+
+    <attribute   name="deferAccept"
+                 type="boolean"
+            writeable="false"/>
+
+    <attribute   name="domain"
+                 type="java.lang.String"/>
+
+    <attribute   name="executorTerminationTimeoutMillis"
+                 type="long"/>
+
+    <attribute   name="keepAliveCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="keepAliveTimeout"
+                 type="int"/>
+
+    <attribute   name="localPort"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="maxConnections"
+                 type="int"/>
+
+    <attribute   name="maxKeepAliveRequests"
+                 type="int"/>
+
+    <attribute   name="maxThreads"
+                 type="int"/>
+
+    <attribute   name="minSpareThreads"
+                 type="int"/>
+
+    <attribute   name="modelerType"
+                 type="java.lang.String"
+            writeable="false"/>
+
+    <attribute   name="name"
+                 type="java.lang.String"/>
+
+    <attribute   name="paused"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="pollerThreadCount"
+                 type="int"/>
+
+    <attribute   name="pollerThreadPriority"
+                 type="int"/>
+
+    <attribute   name="port"
+                 type="int"/>
+
+    <attribute   name="running"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="sSLEnabled"
+                 type="boolean"
+                   is="true"/>
+
+    <attribute   name="selectorTimeout"
+                 type="long"/>
+
+    <attribute   name="sniParseLimit"
+                 type="int"/>
+
+    <attribute   name="sslImplementation"
+                 type="org.apache.tomcat.util.net.SSLImplementation"
+            writeable="false"/>
+
+    <attribute   name="sslImplementationName"
+                 type="java.lang.String"/>
+
+    <attribute   name="tcpNoDelay"
+                 type="boolean"/>
+
+    <attribute   name="threadPriority"
+                 type="int"/>
+
+    <attribute   name="useInheritedChannel"
+                 type="boolean"/>
+
+    <attribute   name="useSendfile"
+                 type="boolean"/>
+
+    <operation       name="addNegotiatedProtocol"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="bind"
+               returnType="void"/>
+
+    <operation       name="closeServerSocketGraceful"
+               returnType="void"/>
+
+    <operation       name="createExecutor"
+               returnType="void"/>
+
+    <operation       name="destroy"
+               returnType="void"/>
+
+    <operation       name="findSslHostConfigs"
+               returnType="[Lorg.apache.tomcat.util.net.SSLHostConfig;"/>
+
+    <operation       name="getAttribute"
+               returnType="java.lang.Object">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="getProperty"
+               returnType="java.lang.String">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="hasNegotiableProtocols"
+               returnType="boolean"/>
+
+    <operation       name="init"
+               returnType="void"/>
+
+    <operation       name="pause"
+               returnType="void"/>
+
+    <operation       name="reloadSslHostConfig"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="reloadSslHostConfigs"
+               returnType="void"/>
+
+    <operation       name="removeSslHostConfig"
+               returnType="org.apache.tomcat.util.net.SSLHostConfig">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="resume"
+               returnType="void"/>
+
+    <operation       name="setProperty"
+               returnType="boolean">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+      <parameter name="param1"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="shutdownExecutor"
+               returnType="void"/>
+
+    <operation       name="start"
+               returnType="void"/>
+
+    <operation       name="startInternal"
+               returnType="void"/>
+
+    <operation       name="stop"
+               returnType="void"/>
+
+    <operation       name="stopInternal"
+               returnType="void"/>
+
+    <operation       name="unbind"
+               returnType="void"/>
+
+  </mbean>
+
+  <mbean         name="Nio2Endpoint"
+            className="org.apache.catalina.mbeans.ClassNameMBean"
+               domain="Catalina"
+                group="ThreadPool"
+                 type="org.apache.tomcat.util.net.Nio2Endpoint">
+
+    <attribute   name="acceptCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadPriority"
+                 type="int"/>
+
+    <attribute   name="alpnSupported"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="bindOnInit"
+                 type="boolean"/>
+
+    <attribute   name="connectionCount"
+                 type="long"
+            writeable="false"/>
+
+    <attribute   name="connectionLinger"
+                 type="int"/>
+
+    <attribute   name="connectionTimeout"
+                 type="int"/>
+
+    <attribute   name="currentThreadCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="currentThreadsBusy"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="daemon"
+                 type="boolean"/>
+
+    <attribute   name="defaultSSLHostConfigName"
+                 type="java.lang.String"/>
+
+    <attribute   name="deferAccept"
+                 type="boolean"
+            writeable="false"/>
+
+    <attribute   name="domain"
+                 type="java.lang.String"/>
+
+    <attribute   name="executorTerminationTimeoutMillis"
+                 type="long"/>
+
+    <attribute   name="keepAliveCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="keepAliveTimeout"
+                 type="int"/>
+
+    <attribute   name="localPort"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="maxConnections"
+                 type="int"/>
+
+    <attribute   name="maxKeepAliveRequests"
+                 type="int"/>
+
+    <attribute   name="maxThreads"
+                 type="int"/>
+
+    <attribute   name="minSpareThreads"
+                 type="int"/>
+
+    <attribute   name="modelerType"
+                 type="java.lang.String"
+            writeable="false"/>
+
+    <attribute   name="name"
+                 type="java.lang.String"/>
+
+    <attribute   name="paused"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="port"
+                 type="int"/>
+
+    <attribute   name="running"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="sSLEnabled"
+                 type="boolean"
+                   is="true"/>
+
+    <attribute   name="sniParseLimit"
+                 type="int"/>
+
+    <attribute   name="sslImplementation"
+                 type="org.apache.tomcat.util.net.SSLImplementation"
+            writeable="false"/>
+
+    <attribute   name="sslImplementationName"
+                 type="java.lang.String"/>
+
+    <attribute   name="tcpNoDelay"
+                 type="boolean"/>
+
+    <attribute   name="threadPriority"
+                 type="int"/>
+
+    <attribute   name="useSendfile"
+                 type="boolean"/>
+
+    <operation       name="addNegotiatedProtocol"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="bind"
+               returnType="void"/>
+
+    <operation       name="closeServerSocketGraceful"
+               returnType="void"/>
+
+    <operation       name="createExecutor"
+               returnType="void"/>
+
+    <operation       name="destroy"
+               returnType="void"/>
+
+    <operation       name="findSslHostConfigs"
+               returnType="[Lorg.apache.tomcat.util.net.SSLHostConfig;"/>
+
+    <operation       name="getAttribute"
+               returnType="java.lang.Object">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="getProperty"
+               returnType="java.lang.String">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="hasNegotiableProtocols"
+               returnType="boolean"/>
+
+    <operation       name="init"
+               returnType="void"/>
+
+    <operation       name="pause"
+               returnType="void"/>
+
+    <operation       name="reloadSslHostConfig"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="reloadSslHostConfigs"
+               returnType="void"/>
+
+    <operation       name="removeSslHostConfig"
+               returnType="org.apache.tomcat.util.net.SSLHostConfig">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="resume"
+               returnType="void"/>
+
+    <operation       name="setProperty"
+               returnType="boolean">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+      <parameter name="param1"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="shutdownExecutor"
+               returnType="void"/>
+
+    <operation       name="start"
+               returnType="void"/>
+
+    <operation       name="startInternal"
+               returnType="void"/>
+
+    <operation       name="stop"
+               returnType="void"/>
+
+    <operation       name="stopInternal"
+               returnType="void"/>
+
+    <operation       name="unbind"
+               returnType="void"/>
+
+  </mbean>
+
+  <mbean         name="AprEndpoint"
+            className="org.apache.catalina.mbeans.ClassNameMBean"
+               domain="Catalina"
+                group="ThreadPool"
+                 type="org.apache.tomcat.util.net.AprEndpoint">
+
+    <attribute   name="acceptCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadCount"
+                 type="int"/>
+
+    <attribute   name="acceptorThreadPriority"
+                 type="int"/>
+
+    <attribute   name="alpnSupported"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="bindOnInit"
+                 type="boolean"/>
+
+    <attribute   name="connectionCount"
+                 type="long"
+            writeable="false"/>
+
+    <attribute   name="connectionLinger"
+                 type="int"/>
+
+    <attribute   name="connectionTimeout"
+                 type="int"/>
+
+    <attribute   name="currentThreadCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="currentThreadsBusy"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="daemon"
+                 type="boolean"/>
+
+    <attribute   name="defaultSSLHostConfigName"
+                 type="java.lang.String"/>
+
+    <attribute   name="deferAccept"
+                 type="boolean"/>
+
+    <attribute   name="domain"
+                 type="java.lang.String"/>
+
+    <attribute   name="executorTerminationTimeoutMillis"
+                 type="long"/>
+
+    <attribute   name="ipv6v6only"
+                 type="boolean"/>
+
+    <attribute   name="keepAliveCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="keepAliveTimeout"
+                 type="int"/>
+
+    <attribute   name="localPort"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="maxConnections"
+                 type="int"/>
+
+    <attribute   name="maxKeepAliveRequests"
+                 type="int"/>
+
+    <attribute   name="maxThreads"
+                 type="int"/>
+
+    <attribute   name="minSpareThreads"
+                 type="int"/>
+
+    <attribute   name="modelerType"
+                 type="java.lang.String"
+            writeable="false"/>
+
+    <attribute   name="name"
+                 type="java.lang.String"/>
+
+    <attribute   name="paused"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="pollTime"
+                 type="int"/>
+
+    <attribute   name="port"
+                 type="int"/>
+
+    <attribute   name="running"
+                 type="boolean"
+            writeable="false"
+                   is="true"/>
+
+    <attribute   name="sSLEnabled"
+                 type="boolean"
+                   is="true"/>
+
+    <attribute   name="sendfileCount"
+                 type="int"
+            writeable="false"/>
+
+    <attribute   name="sendfileSize"
+                 type="int"/>
+
+    <attribute   name="tcpNoDelay"
+                 type="boolean"/>
+
+    <attribute   name="threadPriority"
+                 type="int"/>
+
+    <attribute   name="useSendfile"
+                 type="boolean"/>
+
+    <operation       name="addNegotiatedProtocol"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="bind"
+               returnType="void"/>
+
+    <operation       name="closeServerSocketGraceful"
+               returnType="void"/>
+
+    <operation       name="createExecutor"
+               returnType="void"/>
+
+    <operation       name="destroy"
+               returnType="void"/>
+
+    <operation       name="findSslHostConfigs"
+               returnType="[Lorg.apache.tomcat.util.net.SSLHostConfig;"/>
+
+    <operation       name="getAttribute"
+               returnType="java.lang.Object">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="getProperty"
+               returnType="java.lang.String">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="getSslContext"
+               returnType="long">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="hasNegotiableProtocols"
+               returnType="boolean"/>
+
+    <operation       name="init"
+               returnType="void"/>
+
+    <operation       name="pause"
+               returnType="void"/>
+
+    <operation       name="reloadSslHostConfig"
+               returnType="void">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="reloadSslHostConfigs"
+               returnType="void"/>
+
+    <operation       name="removeSslHostConfig"
+               returnType="org.apache.tomcat.util.net.SSLHostConfig">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="resume"
+               returnType="void"/>
+
+    <operation       name="setProperty"
+               returnType="boolean">
+      <parameter name="param0"
+                 type="java.lang.String"/>
+      <parameter name="param1"
+                 type="java.lang.String"/>
+    </operation>
+
+    <operation       name="shutdownExecutor"
+               returnType="void"/>
+
+    <operation       name="start"
+               returnType="void"/>
+
+    <operation       name="startInternal"
+               returnType="void"/>
+
+    <operation       name="stop"
+               returnType="void"/>
+
+    <operation       name="stopInternal"
+               returnType="void"/>
+
+    <operation       name="unbind"
+               returnType="void"/>
+
+  </mbean>
+
+</mbeans-descriptors>
+
+
Index: apache-tomcat-9.0.12-src/test/org/apache/catalina/mbeans/TestRegistration.java
===================================================================
--- apache-tomcat-9.0.12-src.orig/test/org/apache/catalina/mbeans/TestRegistration.java
+++ apache-tomcat-9.0.12-src/test/org/apache/catalina/mbeans/TestRegistration.java
@@ -134,6 +134,9 @@ public class TestRegistration extends To
                 + ObjectName.quote(ADDRESS),
         "Tomcat:type=ThreadPool,name="
                 + ObjectName.quote("http-" + type + "-" + ADDRESS + "-" + port),
+        "Tomcat:type=ThreadPool,name="
+                + ObjectName.quote("http-" + type + "-" + ADDRESS + "-" + port) +
+                ",subType=SocketProperties",
         };
     }
 
Index: apache-tomcat-9.0.12-src/webapps/docs/changelog.xml
===================================================================
--- apache-tomcat-9.0.12-src.orig/webapps/docs/changelog.xml
+++ apache-tomcat-9.0.12-src/webapps/docs/changelog.xml
@@ -264,6 +264,12 @@
         subsequently incremented when using asynchronous processing over HTTP/2.
         (markt)
       </fix>
+      <fix>
+        <bug>62871</bug>: Improve MBeans for Endpoint instances (type
+        <code>ThreadPool</code> in JMX) by using explicit declaration of
+        attributes and operations rather than relying on introspection. Add a
+        new MBean to expose the <code>Socketproperties</code> values. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">
