All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.esrf.TangoApi.events.EventConsumerUtil Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
//+======================================================================
// $Source$
//
// Project:   Tango
//
// Description:  java source code for the TANGO client/server API.
//
// $Author: pascal_verdier $
//
// Copyright (C) :      2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,
//						European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// Tango 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
// (at your option) any later version.
// 
// Tango 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 Tango.  If not, see .
//
// $Revision:  $
//
//-======================================================================


package fr.esrf.TangoApi.events;


import fr.esrf.Tango.DevFailed;
import fr.esrf.TangoApi.ApiUtil;
import fr.esrf.TangoApi.CallBack;
import fr.esrf.TangoApi.DeviceProxy;

import java.util.Hashtable;


/**
 * @author pascal_verdier
 */




//===============================================================
/**
 * A class to manage NotifdEventConsumer and ZmqEventConsumer instances
 */
//===============================================================
public class EventConsumerUtil {

    private static EventConsumerUtil    instance = null;
    private static boolean zmqTested = false;
    private static boolean zmqLoadable = true;

    //===============================================================
    /**
     * Default constructor
     */
    //===============================================================
    private EventConsumerUtil() {
        /*
        try {
            //  To start KeepAliveThread.
            NotifdEventConsumer.getInstance();
        }
        catch (DevFailed e) {
            //  Nothing
        }
        */
    }
    //===============================================================

    /**
     * Create a singleton if not already done
     * @return an instance on this singleton
     */
    //===============================================================
    public static EventConsumerUtil getInstance() {
        if (instance == null) {
            instance = new EventConsumerUtil();
        }
        return instance;
    }
    //===============================================================

    /**
     * Check if zmq is loadable:
     *  - JNI library must be in LD_LIBRARY_PATH
     *  - zmq jar file must be in CLASSPATH
     *
     * @return true if ZMQ could be loaded correctly
     */
    //===============================================================
    public static boolean isZmqLoadable(){
        //  ToDo invalid ZMQ
        //return false;
         /*******************/
        if (!zmqTested) {

			String	zmqEnable = System.getenv("ZMQ_DISABLE");
			if (zmqEnable==null)
				zmqEnable = System.getProperty("ZMQ_DISABLE");

			if (zmqEnable==null || !zmqEnable.equals("true")) {
            	try {
                	ZMQutils.getInstance();
                    System.out.println("====================== ZMQ (" + ZMQutils.getZmqVersion() +
                            ") event system is available ============================");
            	} catch (java.lang.NoClassDefFoundError error) {
                    System.err.println("======================================================================");
                	System.err.println("  "+error);
                	System.err.println("  Event system will be available only for notifd notification system ");
                	System.err.println("======================================================================");
                	zmqLoadable = false;
            	} catch (java.lang.UnsatisfiedLinkError error) {
                    System.err.println("======================================================================");
                	System.err.println("  "+error);
                	System.err.println("  Event system will be available only for notifd notification system ");
                	System.err.println("======================================================================");
                	zmqLoadable = false;
            	}
			}
			else {
                System.err.println("======================================================================");
                System.err.println("  ZMQ event system not enabled");
                System.err.println("  Event system will be available only for notifd notification system ");
                System.err.println("======================================================================");
                zmqLoadable = false;
			}
            zmqTested = true;
        }
        return zmqLoadable;
        /********************/
   }
    //===============================================================

    /**
     * @param deviceProxy device to be connected
     * @return consumer if already connected, otherwise return null
     */
    //===============================================================
    private EventConsumer isChannelAlreadyConnected(DeviceProxy deviceProxy) {
        try {
            String adminName = deviceProxy.adm_name();
            EventChannelStruct eventChannelStruct = EventConsumer.getChannelMap().get(adminName);
            if (eventChannelStruct == null) {
                return null;
            } else {
                return eventChannelStruct.consumer;
            }
        } catch (DevFailed e) {
            return null;
        }
    }

    //===============================================================

    /**
     * Subscribe on specified event
     *
     * @param device    specified device
     * @param attribute specified attribute
     * @param event     specified event type
     * @param callback  callback class
     * @param filters   filters (not used with zmq)
     * @param stateless stateless subscription if true
     * @return  event ID.
     * @throws DevFailed if subscription failed
     */
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               CallBack callback,
                               String[] filters,
                               boolean stateless)
            throws DevFailed {
        return subscribe_event(device, attribute, event, callback, -1, filters, stateless);
    }

    //===============================================================
    /**
     * Subscribe on specified event
     *
     * @param device    specified device
     * @param attribute specified attribute
     * @param event     specified event type
     * @param max_size  maximum size for event queue
     * @param filters   filters (not used with zmq)
     * @param stateless stateless subscription if true
     * @return  event ID.
     * @throws DevFailed if subscription failed
     */
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               int max_size,
                               String[] filters,
                               boolean stateless)
            throws DevFailed {
        return subscribe_event(device, attribute, event, null, max_size, filters, stateless);
    }

    //===============================================================
    /**
     * Subscribe on specified event
     *
     * @param device    specified device
     * @param attribute specified attribute
     * @param event     specified event type
     * @param callback  callback class
     * @param max_size  maximum size for event queue
     * @param filters   filters (not used with zmq)
     * @param stateless stateless subscription if true
     * @return  event ID.
     * @throws DevFailed if subscription failed
     */
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               CallBack callback,
                               int max_size,
                               String[] filters,
                               boolean stateless) throws DevFailed {
        ApiUtil.printTrace("trying to subscribe_event to " + device.name() + "/" + attribute);
        int id;
        //  If already connected, subscribe directly on same channel
        EventConsumer   consumer = isChannelAlreadyConnected(device);
        if (consumer!=null) {
            id = consumer.subscribe_event(device,
                    attribute, event, callback, max_size, filters, stateless);
        }
        //  ToDo invalid ZMQ
        /*******************/
        else
        if (isZmqLoadable()) {
            try {
                //  If ZMQ jni library can be loaded, try to connect on ZMQ event system
                id = ZmqEventConsumer.getInstance().subscribe_event(device,
                        attribute, event, callback, max_size, filters, stateless);
            }
            catch (DevFailed e) {
                ApiUtil.printTrace(e.errors[0].desc);
                if (e.errors[0].desc.equals(ZMQutils.SUBSCRIBE_COMMAND_NOT_FOUND)) {
                    //  If not a ZMQ server, try on notifd system.
                    id = subscribeEventWithNotifd(device, attribute,
                            event, callback, max_size, filters,stateless);
                }
                else
                    throw e;
            }
        }
        /*************************/
        else {
            //  If there is no ZMQ jni library loadable, try on notifd system.
            id = subscribeEventWithNotifd(device, attribute,
                    event, callback, max_size, filters,stateless);
        }

        return id;
    }
    //===============================================================
    /**
     * Subscribe on specified event
     *
     * @param device    specified device
     * @param event     specified event type
     * @param callback  callback class
     * @param max_size  maximum size for event queue
     * @param stateless stateless subscription if true
     * @return  event ID.
     * @throws DevFailed if subscription failed
     */
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               int event,
                               CallBack callback,
                               int max_size,
                               boolean stateless) throws DevFailed {
        ApiUtil.printTrace("INTERFACE_CHANGE: trying to subscribe_event to " + device.name());
        int id;
        //  If already connected, subscribe directly on same channel
        EventConsumer   consumer = isChannelAlreadyConnected(device);
        if (consumer!=null) {
            id = consumer.subscribe_event(device, event, callback, max_size, stateless);
        }

        //  If ZMQ jni library can be loaded, try to connect on ZMQ event system
        id = ZmqEventConsumer.getInstance().subscribe_event(
                device, event, callback, max_size, stateless);

        return id;
    }
    //===============================================================
    /**
     * Subscribe on specified event using notifd
     *
     * @param device    specified device
     * @param attribute specified attribute
     * @param event     specified event type
     * @param callback  callback class
     * @param max_size  maximum size for event queue
     * @param filters   filters (not used with zmq)
     * @param stateless stateless subscription if true
     * @return  event ID.
     * @throws DevFailed if subscription failed
     */
    //===============================================================
    private int subscribeEventWithNotifd(DeviceProxy device,
                                   String attribute,
                                   int event,
                                   CallBack callback,
                                   int max_size,
                                   String[] filters,
                                   boolean stateless) throws DevFailed {

        int id;
        id = NotifdEventConsumer.getInstance().subscribe_event(device,
                attribute, event, callback, max_size, filters, stateless);
        ApiUtil.printTrace(device.name() + "/" + attribute + "  connected to Notifd event system");
        return id;
    }
    //===============================================================
    /**
     * Un subscribe event
     * @param event_id  specified event ID
     * @throws DevFailed if un subscribe failed or event not found
     */
    //===============================================================
    public void unsubscribe_event(int event_id) throws DevFailed {

        //  Get the map
        Hashtable
                callBackMap = EventConsumer.getEventCallbackMap();

        //  Get the callback structure
        EventCallBackStruct callbackStruct =
                EventConsumer.getCallBackStruct(callBackMap, event_id);

        //  Unsubscribe on EventConsumer object
        callbackStruct.consumer.unsubscribe_event(event_id);
    }
    //===============================================================
    //===============================================================
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy