Author: mwebb
Date: Mon May 28 20:52:18 2007
New Revision: 542399

URL: http://svn.apache.org/viewvc?view=rev&rev=542399
Log:
initial commit for the UDP example.  This example will have a server which will 
listen for packets that will represent the amount of memory used by a client 
application.  While this is just an example, there could be some 'real world' 
applicability with it.
Thanks for Brigham Stevens for his contribution on the SimpleSessionRecycler 
code.  This class might be placed into the baseline, but that is a discussion 
for later.
As for now, I just wanted to check this in so that we would at least have 
something.  I will follow this up with a tutorial in the MINA documentation 
site.

Added:
    mina/trunk/example/src/main/java/org/apache/mina/example/udp/
    
mina/trunk/example/src/main/java/org/apache/mina/example/udp/ClientPanel.java
    
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitor.java
    
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitorHandler.java
    
mina/trunk/example/src/main/java/org/apache/mina/example/udp/SimpleSessionRecycler.java
    mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/
    
mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/MemMonClient.java

Added: 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/ClientPanel.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/udp/ClientPanel.java?view=auto&rev=542399
==============================================================================
--- 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/ClientPanel.java 
(added)
+++ 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/ClientPanel.java 
Mon May 28 20:52:18 2007
@@ -0,0 +1,73 @@
+/*
+ *  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.udp;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+
+/**
+ * Class the represents a client connection using a JPanel 
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ClientPanel extends JPanel {
+
+       private static final long serialVersionUID = 1L;
+
+       private JTextField textField;
+       
+       public ClientPanel( String label ){
+               super();
+               
+               setPreferredSize(MemoryMonitor.PANEL_SIZE);
+               
+               setLayout( new GridBagLayout() );
+               GridBagConstraints c = new GridBagConstraints();
+               
+               c.insets = new Insets(5,5,5,5);
+               c.anchor = GridBagConstraints.CENTER;
+
+               c.gridwidth = GridBagConstraints.REMAINDER;
+               add( new JLabel(label), c );
+               
+               c.gridwidth = 1;
+               add( new JLabel("Memory Used : "));
+               textField = new JTextField(10);
+               textField.setEditable( false );
+               add( textField, c );
+       }
+               
+       public void updateTextField( final long val ){
+               System.out.println("New value for textfield - " + val);
+               SwingUtilities.invokeLater( new Runnable(){
+                       public void run() {
+                               textField.setText( String.valueOf(val) );
+                       }
+               });
+       }
+}

Added: 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitor.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitor.java?view=auto&rev=542399
==============================================================================
--- 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitor.java 
(added)
+++ 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitor.java 
Mon May 28 20:52:18 2007
@@ -0,0 +1,119 @@
+/*
+ *  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.udp;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
+import org.apache.mina.filter.LoggingFilter;
+import org.apache.mina.transport.socket.nio.DatagramAcceptor;
+import org.apache.mina.transport.socket.nio.DatagramSessionConfig;
+
+/**
+ * The class that will accept and process clients in order to properly
+ * track the memory usage.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MemoryMonitor {
+
+       private static final long serialVersionUID = 1L;
+
+       public static final int PORT = 18567;
+       protected static final Dimension PANEL_SIZE = new Dimension(300,200);
+       
+       private JFrame frame;
+       private JTabbedPane tabbedPane;
+       private ConcurrentHashMap<SocketAddress, ClientPanel> clients;
+
+       public MemoryMonitor() throws IOException {
+
+               DatagramAcceptor acceptor = new DatagramAcceptor();
+               acceptor.setLocalAddress(new InetSocketAddress(PORT));
+               acceptor.setHandler(new MemoryMonitorHandler(this));
+
+               acceptor.setSessionRecycler(new SimpleSessionRecycler());
+
+               DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
+               chain.addLast("logger", new LoggingFilter());
+
+               DatagramSessionConfig dcfg = acceptor.getSessionConfig();
+               dcfg.setTrafficClass(0x10);  /** IPTOS_LOWDELAY */
+               dcfg.setReuseAddress(true);
+
+               frame = new JFrame( "Memory monitor" );
+               tabbedPane = new JTabbedPane();
+               tabbedPane.add( "Welcome", createWelcomePanel());
+               frame.add( tabbedPane, BorderLayout.CENTER );
+               clients = new ConcurrentHashMap<SocketAddress,ClientPanel>();
+               frame.pack();
+               frame.setLocation(300, 300);
+               frame.setVisible( true );
+
+               acceptor.bind();
+               System.out.println("UDPServer listening on port " + PORT);
+       }
+
+       private JPanel createWelcomePanel(){
+               JPanel panel = new JPanel();
+               panel.setPreferredSize(PANEL_SIZE);
+               panel.add( new JLabel("Welcome to the Memory Monitor"));
+               return panel;
+       }
+       
+       protected void recvUpdate(SocketAddress clientAddr, long update) {
+               ClientPanel clientPanel = clients.get(clientAddr);
+               if( clientPanel != null )
+                       clientPanel.updateTextField(update);
+               else
+                       System.err.println("Received update from unknown 
client");
+       }
+
+       protected void addClient(SocketAddress clientAddr) {
+               if (!containsClient(clientAddr)) {
+                       ClientPanel clientPanel = new 
ClientPanel(clientAddr.toString());
+                       tabbedPane.add(clientAddr.toString(), clientPanel);
+                       clients.put(clientAddr, clientPanel);
+               }
+       }
+
+       protected boolean containsClient(SocketAddress clientAddr) {
+               return clients.contains(clientAddr);
+       }
+
+       protected void removeClient(SocketAddress clientAddr) {
+               clients.remove(clientAddr);
+       }
+
+       public static void main(String[] args) throws IOException {
+               new MemoryMonitor();
+       }
+}

Added: 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitorHandler.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitorHandler.java?view=auto&rev=542399
==============================================================================
--- 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitorHandler.java
 (added)
+++ 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/MemoryMonitorHandler.java
 Mon May 28 20:52:18 2007
@@ -0,0 +1,85 @@
+/*
+ *  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.udp;
+
+import java.net.SocketAddress;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+
+/**
+ * Class the extends IoHandlerAdapter in order to properly handle
+ * connections and the data the connections send
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MemoryMonitorHandler extends IoHandlerAdapter {
+
+       private MemoryMonitor server;
+       
+       public MemoryMonitorHandler( MemoryMonitor server ){
+               this.server = server;
+       }
+       
+       @Override
+       public void exceptionCaught(IoSession session, Throwable cause) throws 
Exception {
+               cause.printStackTrace();
+               session.close();
+       }
+
+       @Override
+       public void messageReceived(IoSession session, Object message) throws 
Exception {
+               
+               if( message instanceof ByteBuffer ){
+                       ByteBuffer buffer = (ByteBuffer)message;
+                       SocketAddress remoteAddress = 
session.getRemoteAddress();
+                       server.recvUpdate( remoteAddress, buffer.getLong() );
+               }
+       }
+
+       @Override
+       public void sessionClosed(IoSession session) throws Exception {
+               System.out.println("Session closed...");
+               SocketAddress remoteAddress = session.getRemoteAddress();
+               server.removeClient( remoteAddress );
+       }
+
+       @Override
+       public void sessionCreated(IoSession session) throws Exception {
+               
+               System.out.println("Session created...");
+               
+               SocketAddress remoteAddress = session.getRemoteAddress();
+               server.addClient( remoteAddress );
+       }
+
+       @Override
+       public void sessionIdle(IoSession session, IdleStatus status) throws 
Exception {
+               System.out.println("Session idle...");
+       }
+
+       @Override
+       public void sessionOpened(IoSession session) throws Exception {
+               System.out.println("Session Opened...");
+       }
+}

Added: 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/SimpleSessionRecycler.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/udp/SimpleSessionRecycler.java?view=auto&rev=542399
==============================================================================
--- 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/SimpleSessionRecycler.java
 (added)
+++ 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/SimpleSessionRecycler.java
 Mon May 28 20:52:18 2007
@@ -0,0 +1,65 @@
+/*
+ *  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.udp;
+
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoSessionRecycler;
+
+public class SimpleSessionRecycler implements IoSessionRecycler {
+
+       Map<Long, IoSession> map = Collections.synchronizedMap(new 
HashMap<Long, IoSession>());
+
+       public void put(IoSession session) {
+               SocketAddress local = session.getLocalAddress();
+               SocketAddress remote = session.getRemoteAddress();
+               map.put(getKey(local, remote), session);
+       }
+
+       long getKey(SocketAddress local, SocketAddress remote) {
+               long key = ((long) local.hashCode() << 32) | remote.hashCode();
+               return key;
+       }
+
+       /**
+        * Attempts to retrieve a recycled [EMAIL PROTECTED] IoSession}.
+        * 
+        * @param localAddress
+        *            the local socket address of the [EMAIL PROTECTED] 
IoSession} the
+        *            transport wants to recycle.
+        * @param remoteAddress
+        *            the remote socket address of the [EMAIL PROTECTED] 
IoSession} the
+        *            transport wants to recycle.
+        * @return a recycled [EMAIL PROTECTED] IoSession}, or null if one 
cannot be found.
+        */
+       public IoSession recycle(SocketAddress localAddress,
+                       SocketAddress remoteAddress) {
+               IoSession session = map.get(getKey(localAddress, 
remoteAddress));
+               return session;
+       }
+
+       public void remove(IoSession session) {
+               map.remove(getKey(session.getLocalAddress(), 
session.getRemoteAddress()));
+       }
+}
\ No newline at end of file

Added: 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/MemMonClient.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/MemMonClient.java?view=auto&rev=542399
==============================================================================
--- 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/MemMonClient.java
 (added)
+++ 
mina/trunk/example/src/main/java/org/apache/mina/example/udp/client/MemMonClient.java
 Mon May 28 20:52:18 2007
@@ -0,0 +1,143 @@
+/*
+ *  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.udp.client;
+
+import java.net.InetSocketAddress;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoFutureListener;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.example.udp.MemoryMonitor;
+import org.apache.mina.transport.socket.nio.DatagramConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Sends its memory usage to the MemoryMonitor server.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MemMonClient extends IoHandlerAdapter {
+
+       private Logger log = LoggerFactory.getLogger( MemMonClient.class );
+       
+       private IoSession session;
+       private IoConnector connector;
+       
+       /**
+        * Default constructor.
+        */
+       public MemMonClient() {
+
+               log.debug("UDPClient::UDPClient");
+               log.debug( "Created a datagram connector" );
+               connector = new DatagramConnector();
+               
+               log.debug( "Setting the handler" );
+               connector.setHandler( this );
+               
+               log.debug( "About to connect to the server...");
+               ConnectFuture connFuture = connector.connect( new 
InetSocketAddress("localhost", 
+                               MemoryMonitor.PORT ));
+               
+               log.debug("About to wait.");
+               connFuture.awaitUninterruptibly();
+               
+               log.debug( "Adding a future listener." );
+               connFuture.addListener( new IoFutureListener(){
+                       public void operationComplete(IoFuture future) {
+                               ConnectFuture connFuture = 
(ConnectFuture)future;
+                               if( connFuture.isConnected() ){
+                                       log.debug("...connected");
+                                       session = future.getSession();
+                                       try {
+                                               sendData();
+                                       } catch (InterruptedException e) {
+                                               e.printStackTrace();
+                                       }
+                               } else {
+                                       log.error("Not connected...exiting");
+                               }
+                       }
+               });
+       }
+       
+       private void sendData() throws InterruptedException {
+               for( int i=0; i<30; i++ ){
+                       long free = Runtime.getRuntime().freeMemory();
+                       ByteBuffer buffer = ByteBuffer.allocate(8);
+                       buffer.putLong( free );
+                       buffer.flip();
+                       session.write( buffer );
+                       
+                       try {
+                               Thread.sleep( 1000 );
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                               throw new InterruptedException( e.getMessage() 
);
+                       }
+               }
+       }
+       
+       @Override
+       public void exceptionCaught(IoSession session, Throwable cause) throws 
Exception {
+               cause.printStackTrace();
+       }
+
+       @Override
+       public void messageReceived(IoSession session, Object message) throws 
Exception {
+               log.debug("Session recv...");
+       }
+
+       @Override
+       public void messageSent(IoSession session, Object message) throws 
Exception {
+               log.debug("Message sent...");
+       }
+
+       @Override
+       public void sessionClosed(IoSession session) throws Exception {
+               log.debug("Session closed...");
+       }
+
+       @Override
+       public void sessionCreated(IoSession session) throws Exception {
+               log.debug("Session created...");
+       }
+
+       @Override
+       public void sessionIdle(IoSession session, IdleStatus status) throws 
Exception {
+               log.debug("Session idle...");
+       }
+
+       @Override
+       public void sessionOpened(IoSession session) throws Exception {
+               log.debug("Session opened...");
+       }
+
+       public static void main(String[] args) {
+               new MemMonClient();
+       }
+}


Reply via email to