org.rifidi.edge.adapter.awid.awid2010.AwidSession.java Source code

Java tutorial

Introduction

Here is the source code for org.rifidi.edge.adapter.awid.awid2010.AwidSession.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Transcends, LLC.
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU 
 * General Public License as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version. This program 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 General Public License for more details. You 
 * should have received a copy of the GNU General Public License along with this program; if not, 
 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 
 * USA. 
 * http://www.gnu.org/licenses/gpl-2.0.html
 *******************************************************************************/
package org.rifidi.edge.adapter.awid.awid2010;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rifidi.edge.adapter.awid.awid2010.communication.AwidEndpoint;
import org.rifidi.edge.adapter.awid.awid2010.communication.commands.AbstractAwidCommand;
import org.rifidi.edge.adapter.awid.awid2010.communication.commands.ReaderStatusCommand;
import org.rifidi.edge.adapter.awid.awid2010.communication.commands.StopCommand;
import org.rifidi.edge.adapter.awid.awid2010.communication.messages.AckMessage;
import org.rifidi.edge.adapter.awid.awid2010.communication.messages.ReaderStatusMessage;
import org.rifidi.edge.adapter.awid.awid2010.gpio.AwidGPIOSession;
import org.rifidi.edge.api.SessionStatus;
import org.rifidi.edge.notification.NotifierService;
import org.rifidi.edge.sensors.AbstractCommandConfiguration;
import org.rifidi.edge.sensors.AbstractSensor;
import org.rifidi.edge.sensors.ByteMessage;
import org.rifidi.edge.sensors.TimeoutCommand;
import org.rifidi.edge.sensors.sessions.AbstractPubSubIPSensorSession;
import org.rifidi.edge.sensors.sessions.MessageParsingStrategyFactory;

/**
 * The session that provides communication with the Awid reader. It extends the
 * AbstratPubSubIPSensorSession so that the reading and writing to and from TCP
 * sockets is handled. Incoming messages from the reader are sent to registered
 * listeners, in this case the AwidEndpoint.
 * 
 * @author Kyle Neumeier - kyle@pramari.com
 * 
 */
public class AwidSession extends AbstractPubSubIPSensorSession {

    /** The factory that produces the MessageParsingStrategy */
    private final AwidMessageParsingStrategyFactory parsingStratFac;
    /** The endpoint handles incoming messages */
    private final AwidEndpoint awidEndpoint;
    /** The logger for this class */
    private static final Log logger = LogFactory.getLog(AwidSession.class);
    /** Sends out JMS notifications about the state */
    private final NotifierService notifierService;
    /** Session for GPIO Commands */
    private AwidGPIOSession gpioSession;

    private boolean is3014 = false;

    /**
     * Constructor
     * 
     * @param sensor
     *            The sensor that produced this session
     * @param ID
     *            The ID of this session
     * @param host
     *            The IP address of the awid
     * @param port
     *            The port of the awid
     * @param reconnectionInterval
     *            The time inbetween successive reconnection attempts
     * @param maxConAttempts
     *            The maxiumum number of attempts to make to recoonect
     * @param template
     *            Helper object for sending out JMS messages
     * @param commandConfigurations
     *            The Commands available.
     * @param notifierSerivce
     *            Helper object to send out notifications about the state
     */
    public AwidSession(AbstractSensor<?> sensor, String ID, String host, int port, int reconnectionInterval,
            int maxConAttempts,

            Set<AbstractCommandConfiguration<?>> commandConfigurations, NotifierService notifierSerivce,
            boolean is3014) {
        super(sensor, ID, host, port, reconnectionInterval, maxConAttempts, commandConfigurations);
        this.parsingStratFac = new AwidMessageParsingStrategyFactory();
        // create a new object that listens for incoming messages
        awidEndpoint = new AwidEndpoint(getTimeout());
        // subscribe the endpoint
        this.subscribe(awidEndpoint);
        this.notifierService = notifierSerivce;
        this.is3014 = is3014;
        this.gpioSession = new AwidGPIOSession(sensor, "1", host, 4001);
    }

    /*
     * (non-Javadoc)
     * 
     * @seeorg.rifidi.edge.core.sensors.base.AbstractIPSensorSession#
     * getMessageParsingStrategyFactory()
     */
    @Override
    public MessageParsingStrategyFactory getMessageParsingStrategyFactory() {
        return parsingStratFac;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.rifidi.edge.sensors.SensorSession#connect()
     */
    @Override
    public void connect() throws IOException {
        super.connect();
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    gpioSession.connect();
                } catch (Exception e) {
                    logger.warn("Cannot connect GPIOSessoin: " + gpioSession);
                }

            }
        });
        t.start();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.base.AbstractIPSensorSession#onConnect()
     */
    @Override
    public boolean onConnect() throws IOException {
        // Wait for the welcome message to be received. If it's not recieved
        // after 10*100 ms, give up
        for (int i = 0; i < 15; i++) {
            if (awidEndpoint.isConnected()) {
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        if (awidEndpoint.isConnected()) {
            logger.debug("Awid Welcome Message Received.");
            gpioSession.disconnect();
            return true;
        } else {
            logger.warn("No Awid Welcome Message Received");
            return false;
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractIPSensorSession#onConnectFailed
     * ()
     */
    @Override
    protected void onConnectFailed() {
        logger.warn("On Connect Failed. Attempt to connect again.");
        super.onConnectFailed();

        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    connect();
                } catch (IOException e) {
                    disconnect();
                }

            }
        });
        t.start();

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.rifidi.edge.sensors.SensorSession#getResetCommand()
     */
    @Override
    protected TimeoutCommand getResetCommand() {
        return new TimeoutCommand("AwidResetCommand") {
            @Override
            public void execute() throws TimeoutException {
                StopCommand command = new StopCommand();
                try {
                    AwidSession session = (AwidSession) super.sensorSession;
                    clearUndelieverdMessages();
                    session.sendMessage(command);
                    ByteMessage response = session.getEndpoint().receiveMessage(session.getTimeout());
                    AckMessage ack = new AckMessage(response.message);
                } catch (IOException e) {
                    logger.warn("IOException on stop command");
                }

            }
        };
    }

    /*
     * (non-Javadoc)
     * 
     * @seeorg.rifidi.edge.core.sensors.sessions.AbstractIPSensorSession#
     * getKeepAliveCommand()
     */
    @Override
    protected TimeoutCommand getKeepAliveCommand() {
        return new TimeoutCommand("AWIDKeepAliveCommand") {

            @Override
            public void execute() throws TimeoutException {
                ReaderStatusCommand command = new ReaderStatusCommand();
                try {
                    AwidSession session = (AwidSession) super.sensorSession;
                    clearUndelieverdMessages();
                    session.sendMessage(command);
                    ByteMessage response = session.getEndpoint().receiveMessage(session.getTimeout());
                    AckMessage ack = new AckMessage(response.message);

                    response = session.getEndpoint().receiveMessage(session.getTimeout());
                    ReaderStatusMessage status = new ReaderStatusMessage(response.message);

                } catch (TimeoutException ex) {
                    ex.printStackTrace();
                    throw ex;
                } catch (IOException e) {
                    logger.warn("IOException on keepalive");
                }

            }
        };
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractSensorSession#submit(java
     * .lang.String, long, java.util.concurrent.TimeUnit)
     */
    @Override
    public Integer submit(String commandID, long interval, TimeUnit unit) {
        int id = super.submit(commandID, interval, unit);
        this.notifierService.jobSubmitted(this.getSensor().getID(), this.getID(), id, commandID, (interval > 0L));
        return id;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractSensorSession#killComand
     * (java.lang.Integer)
     */
    @Override
    public void killComand(Integer id) {
        super.killComand(id);
        this.notifierService.jobDeleted(this.getSensor().getID(), this.getID(), id);
    }

    public AwidGPIOSession getGPIOSession() {
        return gpioSession;
    }

    public AwidEndpoint getEndpoint() {
        return this.awidEndpoint;
    }

    /**
     * Clients of the session should use this method to send commands to the
     * awid reader
     * 
     * @param command
     *            The command to send
     * @throws IOException
     */
    public void sendMessage(AbstractAwidCommand command) throws IOException {
        super.sendMessage(new ByteMessage(command.getCommand()));
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractSensorSession#setStatus
     * (org.rifidi.edge.api.SessionStatus)
     */
    @Override
    protected synchronized void setStatus(SessionStatus status) {
        // ensure communication is disconnected before receiveing welcome
        // message
        if (status == SessionStatus.LOGGINGIN) {
            this.awidEndpoint.disconnect();
        }
        super.setStatus(status);
        this.notifierService.sessionStatusChanged(getSensor().getID(), getID(), status);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractIPSensorSession#disconnect
     * ()
     */
    @Override
    public void disconnect() {
        super.disconnect();
        gpioSession.disconnect();
    }

    /**
     * Called when destroying this session
     */
    protected void destroy() {
        this.unsubscribe(this.awidEndpoint);
        gpioSession.disconnect();
    }

    /**
     * Is the reader a 3014?
     * 
     * @return
     */
    public boolean is3014() {
        return is3014;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.AbstractIPSensorSession#toString()
     */
    @Override
    public String toString() {
        return super.toString() + ", " + gpioSession.toString();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.rifidi.edge.sensors.sessions.pubsub.AbstractPubSubIPSensorSession
     * #clearUndelieverdMessages()
     */
    @Override
    protected void clearUndelieverdMessages() {
        awidEndpoint.clearUndeliveredMessages();
    }
}