You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by mw...@apache.org on 2008/04/11 05:18:22 UTC

svn commit: r647036 - in /mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3: ./ server/ server/ImageServer.java server/ImageServerIoHandler.java

Author: mwebb
Date: Thu Apr 10 20:18:14 2008
New Revision: 647036

URL: http://svn.apache.org/viewvc?rev=647036&view=rev
Log:
added JMX code for the acceptor, ProtocolFilter and sessions created in the handler.

Added:
    mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/
    mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/
    mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServer.java
    mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServerIoHandler.java

Added: mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServer.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServer.java?rev=647036&view=auto
==============================================================================
--- mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServer.java (added)
+++ mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServer.java Thu Apr 10 20:18:14 2008
@@ -0,0 +1,107 @@
+/*
+ *   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.
+ *
+ */
+package org.apache.mina.example.imagine.step3.server;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
+import org.apache.mina.example.imagine.step1.codec.ImageCodecFactory;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.executor.ExecutorFilter;
+import org.apache.mina.integration.jmx.IoFilterMBean;
+import org.apache.mina.integration.jmx.IoServiceMBean;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+
+/**
+ * entry point for the server used in the tutorial on protocol codecs
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ */
+
+public class ImageServer {
+    public static final int PORT = 33789;
+
+    public static void main(String[] args) throws Exception {
+        
+        // create a JMX MBean Server server instance
+        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+        
+        // Create a class that handles sessions, incoming and outgoing data.  For
+        // this step, we will pass in the MBeanServer so that sessions can be 
+        // registered on the MBeanServer.
+        ImageServerIoHandler handler = new ImageServerIoHandler( mBeanServer );
+        
+        // This socket acceptor will handle incoming connections
+        NioSocketAcceptor acceptor = new NioSocketAcceptor();
+        
+        // create a JMX-aware bean that wraps a MINA IoService object.  In this
+        // case, a NioSocketAcceptor.  
+        IoServiceMBean acceptorMBean = new IoServiceMBean( acceptor );
+        
+        // create a JMX ObjectName.  This has to be in a specific format.  
+        ObjectName acceptorName = new ObjectName( acceptor.getClass().getPackage().getName() + 
+            ":type=acceptor,name=" + acceptor.getClass().getSimpleName());
+        
+        // register the bean on the MBeanServer.  Without this line, no JMX will happen for
+        // this acceptor.
+        mBeanServer.registerMBean( acceptorMBean, acceptorName );
+        
+        // add an IoFilter .  This class is responsible for converting the incoming and 
+        // outgoing raw data to ImageRequest and ImageResponse objects
+        ProtocolCodecFilter protocolFilter = new ProtocolCodecFilter(new ImageCodecFactory(false));
+        
+        // create a JMX-aware bean that wraps a MINA IoFilter object.  In this
+        // case, a ProtocolCodecFilter
+        IoFilterMBean protocolFilterMBean = new IoFilterMBean( protocolFilter );
+        
+        // create a JMX ObjectName.
+        ObjectName protocolFilterName = new ObjectName( protocolFilter.getClass().getPackage().getName() + 
+            ":type=protocolfilter,name=" + protocolFilter.getClass().getSimpleName() );
+        
+        // register the bean on the MBeanServer.  Without this line, no JMX will happen for
+        // this filter.
+        mBeanServer.registerMBean( protocolFilterMBean, protocolFilterName );
+        
+        // add the protocolFilter to the acceptor, otherwise no filtering of data will happen
+        acceptor.getFilterChain().addLast("protocol", protocolFilter);
+        
+        // get a reference to the filter chain from the acceptor
+        DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getFilterChain();
+        
+        // add an ExecutorFilter to the filter chain.  The preferred order is to put the executor filter
+        // after any protocol filters due to the fact that protocol codecs are generally CPU-bound
+        // which is the same as I/O filters.
+        filterChainBuilder.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
+        
+        // set this NioSocketAcceptor's handler to the ImageServerHandler
+        acceptor.setHandler(handler);
+        
+        // Bind to the specified address.  This kicks off the listening for 
+        // incoming connections
+        acceptor.bind(new InetSocketAddress(PORT));
+        System.out.println("Step 3 server is listenig at port " + PORT);
+    }
+}

Added: mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServerIoHandler.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServerIoHandler.java?rev=647036&view=auto
==============================================================================
--- mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServerIoHandler.java (added)
+++ mina/trunk/example/src/main/java/org/apache/mina/example/imagine/step3/server/ImageServerIoHandler.java Thu Apr 10 20:18:14 2008
@@ -0,0 +1,173 @@
+/*
+ *   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.
+ *
+ */
+package org.apache.mina.example.imagine.step3.server;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.example.imagine.step1.ImageRequest;
+import org.apache.mina.example.imagine.step1.ImageResponse;
+import org.apache.mina.integration.jmx.IoSessionMBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * server-side {@link org.apache.mina.common.IoHandler}
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ */
+
+public class ImageServerIoHandler extends IoHandlerAdapter {
+
+    private final static String characters = "mina rocks abcdefghijklmnopqrstuvwxyz0123456789";
+
+    public static final String INDEX_KEY = ImageServerIoHandler.class.getName() + ".INDEX";
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private MBeanServer mBeanServer;
+    
+    /**
+     * Creates a new instance of ImageServerIoHandler.  For this step, we pass in a reference
+     * to the MBeanServer.  This instance will be used to register new IoSession objects
+     * so that the JMX subsystem can report statistics on the sessions.
+     *
+     * @param mBeanServer
+     *  The JMX MBeanServer that will register the sessions
+     */
+    public ImageServerIoHandler( MBeanServer mBeanServer ) {
+        this.mBeanServer = mBeanServer;
+    }
+    
+    /**
+     * This method is called first when a new connection to the server is made.  In here we will set
+     * up the JMX session MBean.
+     * 
+     * @see org.apache.mina.common.IoHandlerAdapter#sessionCreated(org.apache.mina.common.IoSession)
+     */
+    public void sessionCreated( IoSession session ) throws Exception
+    {
+        // create a session MBean in order to load into the MBeanServer and allow
+        // this session to be managed by the JMX subsystem.
+        IoSessionMBean sessionMBean = new IoSessionMBean( session );
+        
+        // create a JMX ObjectName.  This has to be in a specific format.  
+        ObjectName sessionName = new ObjectName( session.getClass().getPackage().getName() + 
+            ":type=session,name=" + session.getClass().getSimpleName() + "-" + session.getId());
+        
+        // register the bean on the MBeanServer.  Without this line, no JMX will happen for
+        // this session
+        mBeanServer.registerMBean( sessionMBean, sessionName );
+    }
+
+    /**
+     * Called when the session is opened, which will come after the session created.
+     * 
+     * @see org.apache.mina.common.IoHandlerAdapter#sessionOpened(org.apache.mina.common.IoSession)
+     */
+    public void sessionOpened(IoSession session) throws Exception {
+        
+        // set the index to zero.  This is used to determine how the build the
+        // string that is sent to the client.
+        session.setAttribute(INDEX_KEY, 0);
+    }
+
+    /**
+     * This method will be called whenever an exception occurs.  For this handler,
+     * the logger will generate a warning message.
+     * 
+     * @see org.apache.mina.common.IoHandlerAdapter#exceptionCaught(org.apache.mina.common.IoSession, java.lang.Throwable)
+     */
+    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
+        logger.warn(cause.getMessage(), cause);
+    }
+
+    /**
+     * Handle incoming messages.
+     * 
+     * @see org.apache.mina.common.IoHandlerAdapter#messageReceived(org.apache.mina.common.IoSession, java.lang.Object)
+     */
+    public void messageReceived(IoSession session, Object message) throws Exception {
+        ImageRequest request = (ImageRequest) message;
+        String text1 = generateString(session, request.getNumberOfCharacters());
+        String text2 = generateString(session, request.getNumberOfCharacters());
+        BufferedImage image1 = createImage(request, text1);
+        BufferedImage image2 = createImage(request, text2);
+        ImageResponse response = new ImageResponse(image1, image2);
+        session.write(response);
+    }
+
+    /**
+     * Create an image using the specified request and the text.  
+     *
+     * @param request
+     *  Determines the height and width of the image
+     * @param text
+     *  The text that is placed in the image
+     * @return
+     *  a BufferedImage representing the text.
+     */
+    private BufferedImage createImage(ImageRequest request, String text) {
+        BufferedImage image = new BufferedImage(request.getWidth(), request.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
+        Graphics graphics = image.createGraphics();
+        graphics.setColor(Color.YELLOW);
+        graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
+        Font serif = new Font("serif", Font.PLAIN, 30);
+        graphics.setFont(serif);
+        graphics.setColor(Color.BLUE);
+        graphics.drawString(text, 10, 50);
+        return image;
+    }
+
+    /**
+     * Generate a string based on the 'characters' field in this class.  The
+     * characters that make up the string are based on the session 
+     * attribute "INDEX_KEY"
+     *
+     * @param session
+     *  The {@link IoSession} object that will provide the INDEX_KEY attribute
+     * @param length
+     *  The length that the String will be
+     * @return
+     *  The generated String
+     */
+    private String generateString(IoSession session, int length) {
+        Integer index = (Integer) session.getAttribute(INDEX_KEY);
+        StringBuffer buffer = new StringBuffer(length);
+        while (buffer.length() < length) {
+            buffer.append(characters.charAt(index));
+            index++;
+            if (index >= characters.length()) {
+                index = 0;
+            }
+        }
+        session.setAttribute(INDEX_KEY, index);
+        return buffer.toString();
+    }
+
+}