Package net.tomp2p.rpc

Source Code of net.tomp2p.rpc.DispatchHandler

/*
* Copyright 2009 Thomas Bocek
*
* 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 net.tomp2p.rpc;

import net.tomp2p.connection.ConnectionBean;
import net.tomp2p.connection.PeerBean;
import net.tomp2p.connection.PeerConnection;
import net.tomp2p.connection.PeerException;
import net.tomp2p.connection.Responder;
import net.tomp2p.message.Message;
import net.tomp2p.message.Message.Type;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.peers.PeerStatusListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The dispatcher handlers that can be added to the Dispatcher.
*
* @author Thomas Bocek
*
*/
public abstract class DispatchHandler {
    private static final Logger LOG = LoggerFactory.getLogger(DispatchHandler.class);

    private final PeerBean peerBean;

    private final ConnectionBean connectionBean;

    private boolean sign = false;

    /**
     * Creates a handler with a connection and peer bean.
     *
     * @param peerBean
     *            The peer bean
     * @param connectionBean
     *            The connection bean
     * @param names
     *            The command names
     */
    public DispatchHandler(final PeerBean peerBean, final ConnectionBean connectionBean) {
        this.peerBean = peerBean;
        this.connectionBean = connectionBean;
    }
   
    /**
     * Registers all names on the dispatcher on behalf of the own peer
     * @param names
     */
    public void register(final int... names) {
      Number160 onBehalfOf = peerBean.serverPeerAddress().peerId();
      register(onBehalfOf, names);
    }
   
    /**
     * Registers all names on the dispatcher on behalf of the given peer
      * @param onBehalfOf
     *         The ioHandler can be registered for the own use of in behalf of another peer (e.g. in case of relay node).
    * @param names
     */
    public void register(Number160 onBehalfOf, final int... names) {
        connectionBean.dispatcher().registerIoHandler(peerBean.serverPeerAddress().peerId(), onBehalfOf, this, names);
    }

    /**
     * @param sign
     *            Set to true if message is signed
     */
    public void sign(final boolean sign) {
        this.sign = sign;
    }

    /**
     * @return The peer bean
     */
    public PeerBean peerBean() {
        return peerBean;
    }

    /**
     * @return The connection bean
     */
    public ConnectionBean connectionBean() {
        return connectionBean;
    }

    /**
     * Create a request message and fills it with connection bean and peer bean parameters.
     *
     * @param recipient
     *            The recipient of this message
     * @param name
     *            The commend type
     * @param type
     *            The request type
     * @return The request message
     */
    public Message createMessage(final PeerAddress recipient, final byte name, final Type type) {
        return new Message().recipient(recipient).sender(peerBean().serverPeerAddress())
                .command(name).type(type).version(connectionBean().p2pId());
    }

    /**
     * Create a response message and fills it with connection bean and peer bean parameters.
     *
     * @param requestMessage
     *            The request message
     * @param replyType
     *            The type of the reply
     * @return The reply message
     */
    public Message createResponseMessage(final Message requestMessage, final Type replyType) {
        return createResponseMessage(requestMessage, replyType, peerBean().serverPeerAddress());
    }
   
    public static Message createResponseMessage(final Message requestMessage, final Type replyType, final PeerAddress peerAddress) {
        Message replyMessage = new Message();
        // this will have the ports > 40'000 that we need to know for sendig the reply
        replyMessage.senderSocket(requestMessage.senderSocket());
        replyMessage.recipientSocket(requestMessage.recipientSocket());
        replyMessage.recipient(requestMessage.sender());
        replyMessage.sender(peerAddress);
        replyMessage.command(requestMessage.command());
        replyMessage.type(replyType);
        replyMessage.version(requestMessage.version());
        replyMessage.messageId(requestMessage.messageId());
        replyMessage.udp(requestMessage.isUdp());
        return replyMessage;
    }

    /**
     * Forwards the request to a handler.
     *
     * @param requestMessage
     *            The request message
     * @param peerConnection The peer connection that can be used for communication
     * @param responder
     * @return The reply message
     */
    public void forwardMessage(final Message requestMessage, PeerConnection peerConnection, Responder responder) {
        // here we need a referral, since we got contacted and we don't know
        // if we can contact the peer with its address. The peer may be
        // behind a NAT
        synchronized (peerBean.peerStatusListeners()) {
      for (PeerStatusListener peerStatusListener : peerBean.peerStatusListeners()) {
        peerStatusListener.peerFound(requestMessage.sender(), requestMessage.sender(), peerConnection);
      }
    }
       
        try {
            handleResponse(requestMessage, peerConnection, sign, responder);
        } catch (Throwable e) {
          synchronized (peerBean.peerStatusListeners()) {
            for (PeerStatusListener peerStatusListener : peerBean.peerStatusListeners()) {
          peerStatusListener.peerFailed(requestMessage.sender(), new PeerException(e));
        }
          }
          LOG.error("Exception in custom handler", e);
            responder.failed(Type.EXCEPTION , e.toString());
        }
    }

    /**
     * If the message is OK, that has been previously checked by the user using checkMessage, a reply to the message is
     * generated here.
     *
     * @param message
     *            Request message
     * @param peerConnection
     * @param sign
     *            Flag to indicate if message is signed
     * @param responder2
     * @param responder
     * @return The message from the handler
     * @throws Exception
     *             Any exception
     */
    public abstract void handleResponse(Message message, PeerConnection peerConnection, boolean sign, Responder responder) throws Exception;

}
TOP

Related Classes of net.tomp2p.rpc.DispatchHandler

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.