zebrogamq.gamelogic.ChannelsManager.java Source code

Java tutorial

Introduction

Here is the source code for zebrogamq.gamelogic.ChannelsManager.java

Source

/**
 ZebroGaMQ: Communication Middleware for Mobile Gaming
 Copyright: Copyright (C) 2009-2012
 Contact: denis.conan@telecom-sudparis.eu, michel.simatic@telecom-sudparis.eu
    
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 3 of the License, or any later version.
    
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 Lesser General Public License for more details.
    
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 USA
    
 Developer(s): Denis Conan, Gabriel Adgeg
 */

package zebrogamq.gamelogic;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MissedHeartbeatException;

public class ChannelsManager {

    private static final int CONNECTION_ESTABLISHMENT_TIMEOUT = 1000; // in ms

    private final ConnectionFactory factory;
    private final ConsumeChannel consumeChannel;
    private final PublishChannel publishChannel;
    private final HeartbeatChannel heartbeatChannel;

    /**
     * Instantiate the ChannelsManager, required for the consumption and the publication of messages.
     * As soon as this method is called, the consumption of messages is automatically started.
     * 
     * @param state the GameLogicState of the player
     * @param loai   the list of GameLogicAction 
     * @return      the ChannelsManager to use to publish messages.
     * @throws IOException if an exception occurs during the connection to the RabbitMQ broker.
     */

    public static ChannelsManager getInstance(final GameLogicState state,
            final List<Map<String, ? extends GameLogicActionInterface>> loai) throws IOException {
        return new ChannelsManager(state, loai, false);
    }

    /**
     * Instantiate the ChannelsManager, required for the consumption and the publication of messages.
     * As soon as this method is called, the consumption of messages is automatically started.
     * If the action kind and the action name of the messages consumed are not registered in the list of GameLogicAction,
     * setting the boolean enableRawAction to true allow to trigger a generic raw action, instead of raising an 
     * ActionInvocationException.
     * 
     * @param state the GameLogicState of the player
     * @param loai   the list of GameLogicAction 
     * @param enableRawAction to enable the use of a generic raw action.
     * @return      the ChannelsManager to use to publish messages.
     * @throws IOException if an exception occurs during the connection to the RabbitMQ broker.
     */
    public static ChannelsManager getInstance(final GameLogicState state,
            final List<Map<String, ? extends GameLogicActionInterface>> loai, boolean enableRawAction)
            throws IOException {
        return new ChannelsManager(state, loai, true);
    }

    private ChannelsManager(final GameLogicState state,
            final List<Map<String, ? extends GameLogicActionInterface>> loai, boolean enableRawAction)
            throws IOException {
        // initialize state
        initGameLogicState(state);
        // initialize connection factory
        factory = getConnectionFactory(state);
        // instantiate attributes
        heartbeatChannel = new HeartbeatChannel(this, state);
        consumeChannel = new ConsumeChannel(this, state, loai, enableRawAction);
        publishChannel = new PublishChannel(this, state);
    }

    private void initGameLogicState(GameLogicState state) {
        if (state.gameName == null) {
            throw new IllegalStateException("RabbitMQGameInstanceChannel tries to create" + " null game name");
        }
        if (state.instanceName == null) {
            throw new IllegalStateException(
                    "RabbitMQGameInstanceChannel tries to create" + " null game instance name");
        }
        state.virtualHost = Util.getRabbitMQProperties().getProperty("virtualHostSeparator") + state.gameName
                + Util.getRabbitMQProperties().getProperty("virtualHostSeparator") + state.instanceName;
        state.exchangeName = Util.getRabbitMQProperties().getProperty("gameLogicExchangeName");
        if (state.exchangeName == null) {
            throw new IllegalStateException("RabbitMQGameInstanceChannel tries to create" + " null exchange name");
        }
        if (Util.getRabbitMQProperties().getProperty("gameLogicBrokerHost") == null) {
            throw new IllegalStateException(
                    "RabbitMQGameInstanceChannel tries to connect to" + " null game logic broker host");
        }
        if (state.login == null) {
            throw new IllegalStateException("RabbitMQGameInstanceChannel tries to connect with" + " null login");
        }
        if (state.password == null) {
            throw new IllegalStateException("RabbitMQGameInstanceChannel tries to connect with" + " null password");
        }
    }

    private ConnectionFactory getConnectionFactory(final GameLogicState state) {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(Util.getRabbitMQProperties().getProperty("gameLogicBrokerHost"));
        factory.setUsername(state.login);
        factory.setPassword(state.password);
        factory.setVirtualHost(state.virtualHost);
        factory.setPort(Integer.valueOf(Util.getRabbitMQProperties().getProperty("gameLogicBrokerPort",
                String.valueOf(factory.getPort()))));
        factory.setConnectionTimeout(CONNECTION_ESTABLISHMENT_TIMEOUT);
        // set the heartbeat value for the amqp connections
        // to avoid the keeping of obsolete consumers
        factory.setRequestedHeartbeat(Integer.valueOf(Util.getRabbitMQProperties()
                .getProperty("amqpConnectionHeartbeat", String.valueOf(factory.getRequestedHeartbeat()))));
        return factory;
    }

    /*
     * Create a new TCP/IP connection to broker.
     */
    Connection newConnection() throws IOException {
        synchronized (factory) {
            return factory.newConnection();
        }
    }

    void exit() {
        Util.println(" Exiting: closing channels and connections");
        heartbeatChannel.close();
        consumeChannel.close();
        publishChannel.close();
    }

    /**
     * Publish a message to a specific recipient (designed by its login)
     * and specify the action that should be triggered by the recipient on 
     * the reception of this message.
     * 
     * @param    consumer    the login of the recipient
     * @param    state      the GameLogicState of the game logic
     * @param    action      the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publish(final String consumer, final GameLogicState state, final GameLogicActionInterface action,
            final String message) throws IOException {
        publishChannel.publish(consumer, state, action, message);
    }

    /**
     * Publish a message to a specific recipient (designed by its login)
     * and specify the action that should be triggered by the recipient on 
     * the reception of this message.
     * 
     * @param    consumer    the login of the recipient
     * @param    state      the GameLogicState of the game logic
     * @param    action      the name of the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publish(final String consumer, final GameLogicState state, final String action,
            final String message) throws IOException {
        publishChannel.publish(consumer, state, action, message);
    }

    /**
     * Publish a message to all the players and to the Game Logic server,
     * and specify the action that should be triggered by recipients on 
     * the reception of this message.
     * 
     * @param    state      the GameLogicState of the game logic
     * @param    action      the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publishToAll(final GameLogicState state, final GameLogicActionInterface action,
            final String message) throws IOException {
        publishChannel.publishToAll(state, action, message);
    }

    /**
     * Publish a message to all the players and to the Game Logic server,
     * and specify the action that should be triggered by recipients on 
     * the reception of this message.
     * 
     * @param    state      the GameLogicState of the game logic
     * @param    action      the name of the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publishToAll(final GameLogicState state, final String action, final String message)
            throws IOException {
        publishChannel.publishToAll(state, action, message);
    }

    /**
     * Publish a message to the Game Logic server, and specify the action 
     * that it should triggered on the reception of this message.
     * 
     * @param    state      the GameLogicState of the game logic 
     * @param    action      the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publishToGameLogicServer(final GameLogicState state, final GameLogicActionInterface action,
            final String message) throws IOException {
        publishChannel.publishToGameLogicServer(state, action, message);
    }

    /**
     * Publish a message to the Game Logic server, and specify the action 
     * that it should triggered on the reception of this message.
     * 
     * @param    state      the GameLogicState of the game logic 
     * @param    action      the name of the action to trigger on the recipient side
     * @param    message      the message 
     * 
     * @throws    IOException if an exception occurs during the publish.
     * @throws    MissedHeartbeatException when the maximum numbers of retry has been done.
     *          The method PlayerState.exit() should be called on the handling of this exception.
     */
    public void publishToGameLogicServer(final GameLogicState state, final String action, final String message)
            throws IOException {
        publishChannel.publishToGameLogicServer(state, action, message);
    }
}