/******************************************************************************* * 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.nc; import java.util.logging.Logger; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.Object; import NotifyExt.ReconnectionCallback; import NotifyExt.ReconnectionCallbackHelper; import NotifyExt.ReconnectionRegistry; import NotifyExt.ReconnectionRegistryHelper; import gov.sandia.NotifyMonitoringExt.EventChannelFactory; import gov.sandia.NotifyMonitoringExt.EventChannelFactoryHelper; import alma.ACS.OffShoot; import alma.ACSErrTypeCommon.wrappers.AcsJIllegalArgumentEx; import alma.JavaContainerError.wrappers.AcsJContainerServicesEx; import alma.acs.container.ContainerServicesBase; import alma.acsnc.OSReconnectionCallbackPOA; /** * AcsNcReconnectionCallback implements the {@link ReconnectionCallback} * from TAO's notify extensions, using an inheritance structure * compatible with ACS's {@link OffShoot} concept. * The publisher and subscriber classes use this class to register themselves * for future {@link #reconnect(Object)} callbacks after a service restart. * This class encapsulates the handling of the reconnection API. * * TODO: Merge with event callback offshoot * * @author javarias */ public class AcsNcReconnectionCallback extends OSReconnectionCallbackPOA { private final Logger logger; private EventChannelFactory ecf_; private final ReconnectableParticipant parti; private int callback_id_; private ContainerServicesBase services; private volatile boolean id_is_valid_; public AcsNcReconnectionCallback(ReconnectableParticipant parti, Logger logger){ this.parti = parti; this.logger = logger; id_is_valid_ = false; } /** * @see NotifyExt.ReconnectionCallbackOperations#is_alive() */ @Override public boolean is_alive() { return true; } /** * Called by the NotifyService after service restart, giving the new EventChannelFactory reference. * This EventChannelFactory reference is passed to the owning ReconnectableParticipant * who should then use it to reconnect. * * @see NotifyExt.ReconnectionCallbackOperations#reconnect(org.omg.CORBA.Object) */ @Override public void reconnect(Object new_connection) { ecf_ = EventChannelFactoryHelper.narrow(new_connection); if (ecf_ != null){ parti.reconnect(ecf_); } } /** * Called by the event subscriber or supplier when connecting to the NC. * Corba-activates this callback object using <code>services</code> and * registers it with the NotifyService's {@link ReconnectionRegistry}. * <p> * @throws AcsJContainerServicesEx * @throws AcsJIllegalArgumentEx * @TODO: This call does not do anything if the <code>ecf == null</code>, * which is also mentioned in comments in the calling code. * This should be cleaned up, e.g. checked if at all and under which circumstances * this null can happen. */ public void registerForReconnect(ContainerServicesBase services, EventChannelFactory ecf ) throws AcsJContainerServicesEx, AcsJIllegalArgumentEx { // TODO: This is strange... if (ecf == null) { return; } if (services == null) { AcsJIllegalArgumentEx ex = new AcsJIllegalArgumentEx(); ex.setVariable("services"); ex.setValue("null"); throw ex; } this.services = services; ReconnectionRegistry registry = null; try { registry = ReconnectionRegistryHelper.narrow(ecf); } catch (BAD_PARAM ex) { // TODO: Or should we just return, same deal as above with ecf == null? AcsJIllegalArgumentEx ex2 = new AcsJIllegalArgumentEx(ex); ex2.setErrorDesc("The given EventChannelFactory is not a NotifyExt.ReconnectionRegistry. Make sure TAO extensions are used!"); throw ex2; } ecf_= ecf; ReconnectionCallback callback = ReconnectionCallbackHelper.narrow(services.activateOffShoot(this)); callback_id_ = registry.register_callback(callback); id_is_valid_ = true; } public void disconnect(){ if (id_is_valid_){ ReconnectionRegistry registry = ReconnectionRegistryHelper.narrow(ecf_); registry.unregister_callback(callback_id_); /* This should never occur, but in any case*/ try { services.deactivateOffShoot(this); } catch (AcsJContainerServicesEx e) { } id_is_valid_ = false; } } }