/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) ESO - European Southern Observatory, 2011 * (in the framework of the ALMA collaboration). * All rights reserved. * * 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 2.1 of the License, or (at your option) 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 *******************************************************************************/ package alma.acs.nsstatistics; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.logging.Logger; import org.omg.CosNotifyChannelAdmin.EventChannel; import org.omg.CosNotifyChannelAdmin.EventChannelFactory; import gov.sandia.CosNotification.NotificationServiceMonitorControl; import alma.acscommon.ALARM_NOTIFICATION_FACTORY_NAME; import alma.acscommon.ARCHIVE_NOTIFICATION_FACTORY_NAME; import alma.acscommon.LOGGING_NOTIFICATION_FACTORY_NAME; import alma.acscommon.NOTIFICATION_FACTORY_NAME; /** * Encapsulates a Corba notify service for use in the model and in GUI elements. * <p> * All equality and comparison methods are based on the simplified name. */ public class NotifyServiceData extends AbstractNotifyServiceElement implements Comparable<NotifyServiceData> { private final HashMap<String, ChannelData> channels; private final String factoryName; /** * The notify service reference. May be null for a while if the service is unreachable when the eventGUI is started. */ private EventChannelFactory efact; /** * The MC object does not provide a persistent reference and must therefore be udpated after service restart. * @see #updateMC(NotificationServiceMonitorControl) */ private volatile NotificationServiceMonitorControl mc; /** * Flag that tells us if the corba notify service referenced by this class is reachable or not. * In case of being unreachable, it may or may not exist. * This flag is independent of {@link #isRegistered}. */ private volatile boolean isReachable; // /** // * Flag that tells us if the corba notify service referenced by this class is registered in the naming service. // * This flag is independent of {@link #isReachable}. // * Note that a service that has died will typically still be registered in the naming service. // */ // private boolean isRegistered; private final Logger logger; /** * TODO: Get MC object in the ctor instead of passing it. * Also get it again somehow after a service restart. * * @param name The simplified display name * @param factoryName The full name (ID) * @param ecf Corba reference to the notify service * @param mc Corba reference to the monitor-control object (TAO extension) */ public NotifyServiceData(String name, String factoryName, EventChannelFactory ecf, NotificationServiceMonitorControl mc, Logger logger) { super(name); channels = new HashMap<String, ChannelData>(10); efact = ecf; this.factoryName = factoryName; this.mc = mc; // this.isRegistered = true; this.isReachable = true; this.logger = logger; } /** * @return The corba ref to the notify service, or <code>null</code> if the eventGUI has never found * this service to be reachable and thus has not obtained a correctly narrowed reference yet. */ public EventChannelFactory getEventChannelFactory() { return efact; } public NotificationServiceMonitorControl getMc() { return mc; } /** * The notify service ref must be updated once after the notify service becomes available, after initial unreachability. */ public void updateEventChannelFactory(EventChannelFactory efact) { if (this.efact == null) { this.efact = efact; } else { logger.warning("Ignoring call to 'updateEventChannelFactory' for notify service '" + getFactoryName() + "' because we already have that corba ref!"); } } /** * The MC object ref must be updated when a notify service was restarted. */ public void updateMC(NotificationServiceMonitorControl monitorControl) { mc = monitorControl; } /** * TODO: Possibly use this information to graphically distinguish between the notify service instances * always started by ACS, and any additional service instances. */ public boolean isStandardNotifyService() { return (factoryName.equals(NOTIFICATION_FACTORY_NAME.value) || factoryName.equals(ALARM_NOTIFICATION_FACTORY_NAME.value) || factoryName.equals(ARCHIVE_NOTIFICATION_FACTORY_NAME.value) || factoryName.equals(LOGGING_NOTIFICATION_FACTORY_NAME.value) ); } public boolean isReachable() { return isReachable; } public void setReachable(boolean isReachable) { this.isReachable = isReachable; } // public boolean isRegistered() { // return isRegistered; // } // // public void setRegistered(boolean isRegistered) { // this.isRegistered = isRegistered; // } public ArrayList<ChannelData> getChannels() { return new ArrayList<ChannelData>(channels.values()); } public ChannelData getChannelByName(String channelName) { return channels.get(channelName); } public ChannelData getChannelById(int ncId) { for (ChannelData nc : getChannels()) { if (nc.getNcId() == ncId) { return nc; } } return null; } /** * This method can be used to merge incomplete NC information sets coming from the naming service, * the regular notify service API, and the MC TAO extension API. * <p> * The matching may fail even if the corba references point to the same NC object, * see {@link org.omg.CORBA.Object#_is_equivalent(org.omg.CORBA.Object)}. */ public ChannelData getChannelByCorbaRef(EventChannel corbaRef) { for (ChannelData nc : getChannels()) { if (nc.getCorbaRef()._is_equivalent(corbaRef)) { return nc; } } return null; } public List<ChannelData> getNewChannels() { List<ChannelData> ret = new ArrayList<ChannelData>(); for (ChannelData nc : getChannels()) { if (nc.isNewNc()) { ret.add(nc); } } return ret; } public void addChannel(String channelName, ChannelData cdata) { channels.put(channelName, cdata); } public void removeChannel(String channelName) { channels.remove(channelName); } ///////////////////////////////////////////////////// @Override public int getNumberConsumers() { int ret = 0; for (ChannelData channelData : getChannels()) { ret += channelData.getNumberConsumers(); } return ret; } @Override public int getNumberSuppliers() { int ret = 0; for (ChannelData channelData : getChannels()) { ret += channelData.getNumberSuppliers(); } return ret; } @Override public int getDeltaConsumers() { int ret = 0; for (ChannelData channelData : getChannels()) { ret += channelData.getDeltaConsumers(); } return ret; } @Override public int getDeltaSuppliers() { int ret = 0; for (ChannelData channelData : getChannels()) { ret += channelData.getDeltaSuppliers(); } return ret; } public String getFactoryName() { return factoryName; } ///////////////////////////////////////////////////// public int compareTo(NotifyServiceData o) { return getName().compareTo(o.getName()); } @Override public boolean equals(Object o) { if (o == null || !(o instanceof NotifyServiceData)) { return false; } return getName().equals(((NotifyServiceData)o).getName()); } @Override public int hashCode() { return getName().hashCode(); } }