Package net.tomp2p.rpc

Source Code of net.tomp2p.rpc.TaskRPC

/*
* 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 java.io.IOException;
import java.security.KeyPair;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import net.tomp2p.connection2.ChannelCreator;
import net.tomp2p.connection2.ConnectionBean;
import net.tomp2p.connection2.PeerBean;
import net.tomp2p.connection2.RequestHandler;
import net.tomp2p.futures.FutureResponse;
import net.tomp2p.message.Message;
import net.tomp2p.message.Message.Command;
import net.tomp2p.message.Message.Type;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.Number320;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.storage.Data;
import net.tomp2p.task.TaskManager;
import net.tomp2p.task.TaskStatus;
import net.tomp2p.task.Worker;
import net.tomp2p.utils.Utils;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TaskRPC extends DispatchHandler {
    final private static Logger logger = LoggerFactory.getLogger(TaskRPC.class);

    private final TaskManager taskManager;

    public TaskRPC(PeerBean peerBean, ConnectionBean connectionBean) {
        super(peerBean, connectionBean);
        this.taskManager = peerBean.getTaskManager();
        registerIoHandler(Command.TASK);
    }

    /**
     * Sends a task to a remote peer. This is an RPC.
     *
     * @param remotePeer
     *            The remote peer to send this request
     * @param channelCreator
     *            The channel creator that creates connections
     * @param forceTCP
     *            Set to true if the communication should be TCP, default is UDP
     * @return The future response to keep track of future events
     */
    public FutureResponse sendTask(final PeerAddress remotePeer, ChannelCreator channelCreator, Number160 taskID,
            Map<Number160, Data> dataMap, Worker mapper, KeyPair keyPair, boolean forceUDP, boolean sign) {
        final Message message = createMessage(remotePeer, Command.TASK, Type.REQUEST_1);
        FutureResponse futureResponse = new FutureResponse(message);
        try {
            byte[] me = Utils.encodeJavaObject(mapper);
            ChannelBuffer payload = ChannelBuffers.wrappedBuffer(me);
            message.setPayload(payload);
            message.setDataMap(dataMap);
            message.setKey(taskID);
            if (sign) {
                message.setPublicKeyAndSign(keyPair);
            }
            if (forceUDP) {
                final RequestHandler<FutureResponse> requestHandler = new RequestHandler<FutureResponse>(
                        futureResponse, getPeerBean(), getConnectionBean(), message);
                if (logger.isDebugEnabled()) {
                    logger.debug("send Task " + message);
                }
                return requestHandler.sendUDP(channelCreator);
            } else {
                final RequestHandlerTCP<FutureResponse> requestHandler = new RequestHandlerTCP<FutureResponse>(
                        futureResponse, getPeerBean(), getConnectionBean(), message);
                if (logger.isDebugEnabled()) {
                    logger.debug("send Task " + message);
                }
                return requestHandler.sendTCP(channelCreator);
            }
        } catch (IOException ioe) {
            futureResponse.setFailed(ioe.toString());
            if (logger.isErrorEnabled()) {
                ioe.printStackTrace();
            }
            return futureResponse;
        }
    }

    public FutureResponse sendResult(final PeerAddress remotePeer, ChannelCreator channelCreator, Number160 taskID,
            Map<Number160, Data> dataMap, KeyPair keyPair, boolean forceUDP, boolean sign) {
        final Message message = createMessage(remotePeer, Command.TASK, Type.REQUEST_3);
        FutureResponse futureResponse = new FutureResponse(message);
        if (dataMap != null) {
            message.setDataMap(dataMap);
        }
        message.setKey(taskID);
        if (sign) {
            message.setPublicKeyAndSign(keyPair);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("send Result " + message);
        }
        if (forceUDP) {
            final RequestHandler<FutureResponse> requestHandler = new RequestHandler<FutureResponse>(
                    futureResponse, getPeerBean(), getConnectionBean(), message);
            return requestHandler.sendUDP(channelCreator);
        } else {
            final RequestHandlerTCP<FutureResponse> requestHandler = new RequestHandlerTCP<FutureResponse>(
                    futureResponse, getPeerBean(), getConnectionBean(), message);
            return requestHandler.sendTCP(channelCreator);
        }
    }

    public FutureResponse taskStatus(final PeerAddress remotePeer, ChannelCreator channelCreator,
            Collection<Number160> taskIDs, boolean forceTCP) {
        final Message message = createMessage(remotePeer, Command.TASK, Type.REQUEST_2);
        message.setKeys(taskIDs);
        FutureResponse futureResponse = new FutureResponse(message);
        if (!forceTCP) {
            final RequestHandler<FutureResponse> requestHandler = new RequestHandler<FutureResponse>(
                    futureResponse, getPeerBean(), getConnectionBean(), message);
            return requestHandler.sendUDP(channelCreator);
        } else {
            final RequestHandlerTCP<FutureResponse> requestHandler = new RequestHandlerTCP<FutureResponse>(
                    futureResponse, getPeerBean(), getConnectionBean(), message);
            return requestHandler.sendTCP(channelCreator);
        }
    }

    @Override
    public Message handleResponse(final Message message, boolean sign) throws Exception {
        if (!((message.getType() == Type.REQUEST_1 || message.getType() == Type.REQUEST_2 || message.getType() == Type.REQUEST_3) && message
                .getCommand() == Command.TASK)) {
            throw new IllegalArgumentException("Message content is wrong");
        }
        if (logger.isDebugEnabled()) {
            logger.debug("send Task - received " + message);
        }
        final Message responseMessage = createResponseMessage(message, Type.OK);
        if (sign) {
            responseMessage.setPublicKeyAndSign(getPeerBean().getKeyPair());
        }
        if (message.getType() == Type.REQUEST_1) {
            Number160 taskId = message.getKey();
            // request 1 is task creation
            Map<Number160, Data> dataMap = message.getDataMap();
            ChannelBuffer channelBuffer = message.getPayload1();
            Object obj = Utils.decodeJavaObject(channelBuffer);
            Worker mapper = (Worker) obj;
            int queuePosition = taskManager.submitTask(getPeerBean().getPeer(), taskId, mapper, dataMap,
                    message.getSender(), sign);
            responseMessage.setInteger(queuePosition);
        } else if (message.getType() == Type.REQUEST_2) {
            Collection<Number160> taskIDs = message.getKeys();
            Map<Number160, Data> dataMap = new HashMap<Number160, Data>();
            for (Number160 taskId : taskIDs) {
                Number320 taskKey = new Number320(taskId, message.getSender().getPeerId());
                TaskStatus taskStatus = taskManager.taskStatus(taskKey);
                Data data = new Data(taskStatus);
                dataMap.put(taskId, data);
            }
            responseMessage.setDataMap(dataMap);
            if (logger.isDebugEnabled()) {
                logger.debug("finished task status for tasks " + taskIDs);
            }
        } else if (message.getType() == Type.REQUEST_3) {
            Number160 taskId = message.getKey();
            Map<Number160, Data> dataMap = message.getDataMap();
            Number320 taskKey = new Number320(taskId, message.getSender().getPeerId());
            taskManager.notifyListeners(taskKey, dataMap);
        } else {
            responseMessage.setType(Type.NOT_FOUND);
        }
        return responseMessage;
    }
}
TOP

Related Classes of net.tomp2p.rpc.TaskRPC

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.