<!--
 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.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
</head>
<body>
JMX (Java Management eXtension) integration.

<h2>Monitoring Your MINA Services and Sessions</h3>

<h3>Monitoring an IoService</h3>
<pre>
acceptor = new SocketAcceptor();
       
try
{
    IoServiceManager iosm = new IoServiceManager(acceptor);
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();  
    ObjectName name = new ObjectName( "com.acme.test:type=IoServiceManager,name=MyMINAServer" );
    mbs.registerMBean( iosm, name );
}
catch( JMException e )
{
    logger.error( "JMX Exception: ", e );
}
</pre>

<h3>Monitoring an IoSession</h3>

Each session is registered to MBean server individually.

<pre>
acceptor.addListener( new IoServiceListener()
{
    public void serviceActivated( IoService service, SocketAddress serviceAddress, IoHandler handler, IoServiceConfig config )
    {
    }

    public void serviceDeactivated( IoService service, SocketAddress serviceAddress, IoHandler handler, IoServiceConfig config )
    {
    }

    public void sessionCreated( IoSession session )
    {
        try
        {
            IoSessionManager sessMgr = new IoSessionManager( session );
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();  
            ObjectName name = new ObjectName( "com.acme.test.session:type=IoSessionManager,name=" + session.getRemoteAddress().toString().replace( ':', '/' ) );
            mbs.registerMBean( sessMgr, name );
        }
        catch( JMException e )
        {
            logger.error( "JMX Exception: ", e );
        }      
    }

    public void sessionDestroyed( IoSession session )
    {
        try
        {
            ObjectName name = new ObjectName( "com.acme.test.session:type=IoSessionManager,name=" + session.getRemoteAddress().toString().replace( ':', '/' ) );
            ManagementFactory.getPlatformMBeanServer().unregisterMBean( name );
        }
        catch( JMException e )
        {
            logger.error( "JMX Exception: ", e );
        }      
    }
});
</pre>
</body>
</html>
