mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
03.00.2013 23de152d5ce528a0bec277441cab35d9cafea6df
Fix OPENDJ-1161 - Allow configuration of RMI port in JMX connector.
These changes are adding a new optional configuration parameter : rmi-port, to allow specifying a fixed port for the RMI connection underlying JMX. This is required when managing applications need to connect to OpenDJ through a firewall.
CR-2429.
5 files modified
152 ■■■■■ changed files
opends/resource/schema/02-config.ldif 8 ●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml 34 ●●●●● patch | view | raw | blame | history
opends/src/admin/messages/JMXConnectionHandlerCfgDefn.properties 4 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java 97 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/jmx/RmiConnector.java 9 ●●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif
@@ -3749,6 +3749,11 @@
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.132
  NAME 'ds-cfg-rmi-port' EQUALITY integerMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler'
  SUP top
@@ -4456,7 +4461,8 @@
  MAY ( ds-cfg-listen-address $
        ds-cfg-ssl-cert-nickname $
        ds-cfg-use-ssl $
        ds-cfg-key-manager-provider )
        ds-cfg-key-manager-provider $
        ds-cfg-rmi-port )
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.63
  NAME 'ds-task-import'
opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
@@ -24,6 +24,7 @@
  !
  !
  !      Copyright 2007-2009 Sun Microsystems, Inc.
  !      Portions Copyright 2013 ForgeRock AS.
  ! -->
<adm:managed-object name="jmx-connection-handler"
  plural-name="jmx-connection-handlers"
@@ -67,11 +68,12 @@
      </adm:defined>
    </adm:default-behavior>
  </adm:property-override>
     <adm:property name="listen-address" multi-valued="true" read-only="true">
  <adm:property name="listen-address" multi-valued="true" read-only="true">
    <adm:synopsis>
      Specifies the address or set of addresses on which this
      <adm:user-friendly-name />
      should listen for connections from SNMP clients.
      should listen for connections from JMX clients. However JMX/RMI
      doesn't allow this, and this property cannot be set.
    </adm:synopsis>
    <adm:description>
      Multiple addresses may be provided as separate values for this
@@ -146,4 +148,32 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="rmi-port">
    <adm:synopsis>
        Specifies the port number on which the JMX RMI service
        will listen for connections from clients. A value of 0
        indicates the service to choose a port of its own.
    </adm:synopsis>
    <adm:description>
        If the value provided is different than 0, the value
        will be used as the RMI port. Otherwise, the RMI service
        will choose a port of its own.
    </adm:description>
    <adm:requires-admin-action>
      <adm:component-restart />
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:defined>
        <adm:value>0</adm:value>
      </adm:defined>
    </adm:default-behavior>
    <adm:syntax>
      <adm:integer lower-limit="0" upper-limit="65535" />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-rmi-port</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/messages/JMXConnectionHandlerCfgDefn.properties
@@ -15,10 +15,12 @@
property.key-manager-provider.synopsis=Specifies the name of the key manager that should be used with this JMX Connection Handler .
property.key-manager-provider.requires-admin-action.synopsis=Changes to this property take effect immediately, but only for subsequent attempts to access the key manager provider for associated client connections.
property.key-manager-provider.syntax.aggregation.constraint-synopsis=The referenced key manager provider must be enabled when the JMX Connection Handler is enabled and configured to use SSL.
property.listen-address.synopsis=Specifies the address or set of addresses on which this JMX Connection Handler should listen for connections from SNMP clients.
property.listen-address.synopsis=Specifies the address or set of addresses on which this JMX Connection Handler should listen for connections from JMX clients. However JMX/RMI doesn't allow this, and this property cannot be set.
property.listen-address.description=Multiple addresses may be provided as separate values for this attribute. If no values are provided, then the JMX Connection Handler listens on all interfaces.
property.listen-port.synopsis=Specifies the port number on which the JMX Connection Handler will listen for connections from clients.
property.listen-port.description=Only a single port number may be provided.
property.rmi-port.synopsis=Specifies the port number on which the JMX RMI service will listen for connections from clients. A value of 0 indicates the service to choose a port of its own.
property.rmi-port.description=If the value provided is different than 0, the value will be used as the RMI port. Otherwise, the RMI service will choose a port of its own.
property.ssl-cert-nickname.synopsis=Specifies the nickname (also called the alias) of the certificate that the JMX Connection Handler should use when performing SSL communication.
property.ssl-cert-nickname.description=This is only applicable when the JMX Connection Handler is configured to use SSL.
property.ssl-cert-nickname.default-behavior.alias.synopsis=Let the server decide.
opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
@@ -122,6 +122,10 @@
      portChanged = true;
    }
    if (currentConfig.getRmiPort() != config.getRmiPort())
    {
      rmiConnectorRestart = true;
    }
    if (currentConfig.isUseSSL() != config.isUseSSL()) {
      rmiConnectorRestart = true;
    }
@@ -205,9 +209,7 @@
  @Override
  public Map<String, String> getAlerts()
  {
    Map<String, String> alerts = new LinkedHashMap<String, String>();
    return alerts;
    return new LinkedHashMap<String, String>();
  }
@@ -280,6 +282,14 @@
    return currentConfig.getListenPort();
  }
  /**
   * Get the JMX connection handler's rmi port.
   *
   * @return Returns the JMX connection handler's rmi port.
   */
  public int getRmiPort() {
    return currentConfig.getRmiPort();
  }
  /**
@@ -326,22 +336,11 @@
    // Configuration is ok.
    currentConfig = config;
    // Attempt to bind to the listen port to verify whether the connection
    // handler will be able to start.
    try
    List<Message> reasons = new LinkedList<Message>();
    if (!isPortConfigurationAcceptable(String.valueOf(config.dn()),
        config.getListenPort(), reasons))
    {
      if (StaticUtils.isAddressInUse(
        new InetSocketAddress(config.getListenPort()).getAddress(),
        config.getListenPort(), true)) {
        throw new IOException(
          ERR_CONNHANDLER_ADDRESS_INUSE.get().toString());
      }
    }
    catch (Exception e)
    {
      Message message =
          ERR_CONNHANDLER_CANNOT_BIND.get("JMX", String.valueOf(config.dn()),
              WILDCARD_ADDRESS, config.getListenPort(), getExceptionMessage(e));
      Message message = reasons.get(0);
      logError(message);
      throw new InitializationException(message);
    }
@@ -399,7 +398,6 @@
  }
  /**
   * {@inheritDoc}
   */
@@ -409,32 +407,48 @@
  {
    JMXConnectionHandlerCfg config = (JMXConnectionHandlerCfg) configuration;
    if ((currentConfig == null) ||
    if (currentConfig == null ||
        (!currentConfig.isEnabled() && config.isEnabled()) ||
        (currentConfig.getListenPort() != config.getListenPort())) {
      // Attempt to bind to the listen port to verify whether the connection
      // handler will be able to start.
      try {
        if (StaticUtils.isAddressInUse(
          new InetSocketAddress(config.getListenPort()).getAddress(),
          config.getListenPort(), true)) {
          throw new IOException(
            ERR_CONNHANDLER_ADDRESS_INUSE.get().toString());
        }
      } catch (Exception e) {
        Message message =
            ERR_CONNHANDLER_CANNOT_BIND.get("JMX", String.valueOf(config.dn()),
                WILDCARD_ADDRESS, config.getListenPort(),
                getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
        currentConfig.getListenPort() != config.getListenPort() &&
        !isPortConfigurationAcceptable(String.valueOf(config.dn()),
          config.getListenPort(), unacceptableReasons))
    {
      return false;
    }
    if (config.getRmiPort() != 0 &&
        (currentConfig == null ||
        (!currentConfig.isEnabled() && config.isEnabled()) ||
        currentConfig.getRmiPort() != config.getRmiPort()) &&
        !isPortConfigurationAcceptable(String.valueOf(config.dn()),
          config.getRmiPort(), unacceptableReasons))
    {
      return false;
    }
    return isConfigurationChangeAcceptable(config, unacceptableReasons);
  }
  /**
   * Attempt to bind to the port to verify whether the connection
   * handler will be able to start.
   * @return true is the port is free to use, false otherwise.
   */
  private boolean isPortConfigurationAcceptable(String configDN,
                      int newPort, List<Message> unacceptableReasons) {
    try {
      if (StaticUtils.isAddressInUse(
          new InetSocketAddress(newPort).getAddress(), newPort, true)) {
        throw new IOException(ERR_CONNHANDLER_ADDRESS_INUSE.get().toString());
      }
    } catch (Exception e) {
      Message message = ERR_CONNHANDLER_CANNOT_BIND.get("JMX", configDN,
              WILDCARD_ADDRESS, newPort, getExceptionMessage(e));
      unacceptableReasons.add(message);
      return false;
    }
    return true;
  }
  /**
   * {@inheritDoc}
@@ -453,7 +467,7 @@
   * Determines whether or not clients are allowed to connect over JMX
   * using SSL.
   *
   * @return Returns <code>true</code> if clients are allowed to
   * @return Returns {@code true} if clients are allowed to
   *         connect over JMX using SSL.
   */
  public boolean isUseSSL() {
@@ -494,8 +508,9 @@
    {
      rmiConnector.initialize();
    }
    catch (RuntimeException e)
    catch (RuntimeException ignore)
    {
      // Already caught and logged
    }
  }
opends/src/server/org/opends/server/protocols/jmx/RmiConnector.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS.
 */
package org.opends.server.protocols.jmx;
@@ -127,7 +128,7 @@
  private OpendsRmiServerSocketFactory rmiSsf;
  /**
   * The RMI protocol verison used by this connector.
   * The RMI protocol version used by this connector.
   */
  private String rmiVersion;
@@ -271,7 +272,7 @@
  /**
   * Starts a secure RMI connector, with a client that doesn't have to
   * present a certificate, on the local mbean server.
   * present a certificate, on the local MBean server.
   * This method assumes that the common registry was successfully
   * started.
   * <p>
@@ -386,8 +387,8 @@
        TRACER.debugVerbose("Create and start the JMX RMI connector");
      }
      OpendsRMIJRMPServerImpl opendsRmiConnectorServer =
          new OpendsRMIJRMPServerImpl(
              0, rmiClientSockeyFactory, rmiServerSockeyFactory, env);
          new OpendsRMIJRMPServerImpl(jmxConnectionHandler.getRmiPort(),
              rmiClientSockeyFactory, rmiServerSockeyFactory, env);
      jmxRmiConnectorNoClientCertificate = new RMIConnectorServer(url, env,
          opendsRmiConnectorServer, mbs);
      jmxRmiConnectorNoClientCertificate.start();