Package org.cipango.diameter.node

Source Code of org.cipango.diameter.node.AbstractDiameterConnector

// ========================================================================
// Copyright 2008-2009 NEXCOM Systems
// ------------------------------------------------------------------------
// Licensed 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.cipango.diameter.node;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;

import org.cipango.diameter.log.DiameterMessageListener;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;

public abstract class AbstractDiameterConnector extends AbstractLifeCycle implements DiameterConnector //, Buffers
{
 
  private static String __localhost;
   
    static
    {
        try
        {
            __localhost = InetAddress.getLocalHost().getHostAddress();
        }
        catch (Exception e)
        {
            Log.ignore(e);
            __localhost = "127.0.0.1";
        }
    }
 
  private Node _node;
 
  private int _acceptors = 1;
  private int _acceptorPriorityOffset = 0;
 
  private String _host;
  private int _port;
 
  private Thread[] _acceptorThread;
  private ArrayList<Buffer> _buffers;
  private int _messageBufferSize = 8192;
 
  protected AtomicLong _messagesReceived = new AtomicLong();
  protected AtomicLong _messagesSent = new AtomicLong();
 
  protected DiameterMessageListener _listener;
 
  public AbstractDiameterConnector()
  {
     _port = getDefaultPort();
       setHost( __localhost);
  }
 
  @Override
  protected void doStart() throws Exception
  {
    if (_node == null)
      throw new IllegalStateException("No node");
   
    open();
   
    if (_buffers != null)
      _buffers.clear();
    else
      _buffers = new ArrayList<Buffer>();
   
    super.doStart();
   
    if (_listener instanceof LifeCycle)
      ((LifeCycle) _listener).start();
   
    synchronized (this)
    {
      _acceptorThread = new Thread[getAcceptors()];
      for (int i = 0; i < _acceptorThread.length; i++)
      {
        _acceptorThread[i] = new Thread(new Acceptor(i));
        _acceptorThread[i].start();
      }
    }
    Log.info("Started {}", this);
  }
 
  @Override
  protected void doStop() throws Exception
 
    if (_listener instanceof LifeCycle)
      ((LifeCycle) _listener).stop();
   
    super.doStop();
   
    close();
   
    Thread[] acceptors = null;
        synchronized(this)
        {
            acceptors = _acceptorThread;
            _acceptorThread = null;
        }
        if (acceptors != null)
        {
            for (int i = 0; i < acceptors.length; i++)
            {
                Thread thread = acceptors[i];
                if (thread != null)
                    thread.interrupt();
            }
        } 
  }
 
  public void setMessageListener(DiameterMessageListener listener)
  {
    try
    {
      if (_listener != null  && _listener instanceof LifeCycle)
        ((LifeCycle) _listener).stop();
    }
    catch (Exception e)
    {
      Log.warn(e);
    }
   
    if (_node != null && _node.getServer() != null)
      _node.getServer().getContainer().update(this, _listener, listener, "listener");
   
    _listener = listener;
   
    try
    {
      if (isStarted() && (_listener instanceof LifeCycle))
        ((LifeCycle) _listener).start();
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
  }
 
  public DiameterMessageListener getMessageListener()
  {
    return _listener;
  }
 
  public Buffer getBuffer(int size)
  {
    if (size == _messageBufferSize)
    {
      synchronized(_buffers)
      {
        if (_buffers.size() > 0)
          return (Buffer) _buffers.remove(_buffers.size() - 1);
      }
      return newBuffer(size);
    }
    return newBuffer(size);
  }
 
  public void returnBuffer(Buffer buffer)
  {
    buffer.clear();
    if (!buffer.isVolatile() && !buffer.isImmutable())
        {
      int c = buffer.capacity();
            if (c == _messageBufferSize)
            {
                synchronized(_buffers)
                {
                  _buffers.add(buffer);
                }
            }
        }
  }
 
  public int getMessageBufferSize()
  {
    return _messageBufferSize;
  }
 
  protected Buffer newBuffer(int size)
  {
    return new ByteArrayBuffer(size);
  }
 
  public int getAcceptors()
  {
    return _acceptors;
  }
 
  public void setHost(String host)
  {
    if (host == null)
        host = __localhost;
   
    _host = host;
  }
 
  public String getHost()
  {
    return _host;
  }
 
  public void setPort(int port)
  {
    _port = port;
  }
 
  public int getPort()
  {
    return _port;
  }
 
  public void setNode(Node node)
  {
    if (_node != null && _node != node && _node.getServer() != null)
      _node.getServer().getContainer().update(this, _listener, null, "listener");
       
    if (node != null && node != _node && node.getServer() != null)
      node.getServer().getContainer().update(this, null, _listener, "listener");
   
    _node = node;
  }
 
  public Node getNode()
  {
    return _node;
  }
 
  protected abstract void accept(int acceptorID) throws IOException, InterruptedException;
 
  protected abstract int getDefaultPort();
 
  @Override
  public String toString()
    {
        String name = this.getClass().getName();
        int dot = name.lastIndexOf('.');
        if (dot>0)
            name=name.substring(dot+1);
       
        return name+"@"+(getHost()==null?"0.0.0.0":getHost())+":"+(getLocalPort()<=0?getPort():getLocalPort());
    }
 
  public long getMessageReceived()
  {
    return _messagesReceived.get();
  }
 
  public long getMessageSent()
  {
    return _messagesSent.get();
  }
 
  public void statsReset()
    {
        _messagesReceived.set(0);
        _messagesSent.set(0);
    }
 
  private class Acceptor implements Runnable
  {
    int _acceptor = 0;
   
    Acceptor(int id)
    {
      _acceptor = id;
    }
    public void run()
    {
      Thread current = Thread.currentThread();
      synchronized (AbstractDiameterConnector.this)
      {
        if (_acceptorThread == null)
          return;
        _acceptorThread[_acceptor] = current;
      }
      String name = _acceptorThread[_acceptor].getName();
      current.setName(name + " - Acceptor" + _acceptor + " " + AbstractDiameterConnector.this);
      int priority = current.getPriority();
     
      try
      {
        current.setPriority(priority - _acceptorPriorityOffset);
        while (isRunning() && getTransport() != null)
        {
          try
          {
            accept(_acceptor);
          }
          catch (IOException e)
          {
            Log.ignore(e);
          }
          catch (Throwable t)
          {
            Log.warn(t);
          }
        }
      }
      finally
      {
        current.setPriority(priority);
        current.setName(name);
        try
        {
          if (_acceptor == 0)
            close();
        }
        catch (IOException e)
        {
          Log.warn(e);
        }
        synchronized (AbstractDiameterConnector.this)
        {
          if (_acceptorThread != null)
            _acceptorThread[_acceptor] = null;
        }
      }
    }
  }
}
TOP

Related Classes of org.cipango.diameter.node.AbstractDiameterConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.