Package asia.stampy.client.listener.disconnect

Source Code of asia.stampy.client.listener.disconnect.AbstractDisconnectListenerAndInterceptor

/*
* Copyright (C) 2013 Burton Alexander
*
* 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.
*
*/
package asia.stampy.client.listener.disconnect;

import java.lang.invoke.MethodHandles;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import asia.stampy.client.message.disconnect.DisconnectMessage;
import asia.stampy.common.StampyLibrary;
import asia.stampy.common.gateway.AbstractStampyMessageGateway;
import asia.stampy.common.gateway.HostPort;
import asia.stampy.common.gateway.MessageListenerHaltException;
import asia.stampy.common.gateway.StampyMessageListener;
import asia.stampy.common.message.StampyMessage;
import asia.stampy.common.message.StompMessageType;
import asia.stampy.common.message.interceptor.AbstractOutgoingMessageInterceptor;
import asia.stampy.common.message.interceptor.InterceptException;
import asia.stampy.server.message.receipt.ReceiptMessage;

/**
* This class intercepts an outgoing {@link StompMessageType#DISCONNECT} message
* if a receipt has been requested. When the receipt from the server arrives the
* {@link AbstractDisconnectListenerAndInterceptor#isCloseOnDisconnectMessage()}
* is evaluated and if true the <b>session</b> is closed.<br>
* <br>
* <i>To do a graceful shutdown, where the client is assured that all previous
* frames have been received by the server, the client SHOULD: send a DISCONNECT
* frame with a receipt header set. Example: DISCONNECT receipt:77 ^@ wait for
* the RECEIPT frame response to the DISCONNECT. Example: RECEIPT receipt-id:77
* ^@ close the <strike>socket</strike> session.</i>
*/
@StampyLibrary(libraryName = "stampy-client-server")
public abstract class AbstractDisconnectListenerAndInterceptor<CLNT extends AbstractStampyMessageGateway> extends
    AbstractOutgoingMessageInterceptor<CLNT> implements StampyMessageListener {
  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  private static StompMessageType[] TYPES = { StompMessageType.DISCONNECT, StompMessageType.RECEIPT };

  private boolean closeOnDisconnectMessage = true;
  private String receiptId;

  /*
   * (non-Javadoc)
   *
   * @see
   * asia.stampy.common.message.interceptor.StampyOutgoingMessageInterceptor
   * #getMessageTypes()
   */
  @Override
  public StompMessageType[] getMessageTypes() {
    return TYPES;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * asia.stampy.common.message.interceptor.StampyOutgoingMessageInterceptor
   * #isForMessage(asia.stampy.common.message.StampyMessage)
   */
  @Override
  public boolean isForMessage(StampyMessage<?> message) {
    switch (message.getMessageType()) {
    case DISCONNECT:
      boolean absent = StringUtils.isEmpty(getReceiptId());

      if (!absent) {
        log.warn("Outstanding receipt id {} in DisconnectListenerAndInterceptor, resetting", getReceiptId());
        setReceiptId((String) null);
      }

      return StringUtils.isNotEmpty(((DisconnectMessage) message).getHeader().getReceipt());
    case RECEIPT:
      ReceiptMessage receipt = (ReceiptMessage) message;
      return StringUtils.isNotEmpty(getReceiptId()) && getReceiptId().equals(receipt.getHeader().getReceiptId());
    default:
      return false;

    }
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * asia.stampy.common.message.interceptor.StampyOutgoingMessageInterceptor
   * #interceptMessage(asia.stampy.common.message.StampyMessage,
   * asia.stampy.common.HostPort)
   */
  @Override
  public void interceptMessage(StampyMessage<?> message, HostPort hostPort) throws InterceptException {
    switch (message.getMessageType()) {
    case DISCONNECT:
      setReceiptId((DisconnectMessage) message);
      break;
    default:
      return;

    }
  }

  /*
   * (non-Javadoc)
   *
   * @see asia.stampy.common.gateway.StampyMessageListener#messageReceived(asia.
   * stampy.common.message.StampyMessage, asia.stampy.common.HostPort)
   */
  @Override
  public void messageReceived(StampyMessage<?> message, HostPort hostPort) throws Exception {
    switch (message.getMessageType()) {
    case RECEIPT:
      setReceiptId((String) null);
      if (isCloseOnDisconnectMessage()) {
        log.info("Receipt for disconnect message received, disconnecting");
        getGateway().closeConnection(hostPort);
        throw new MessageListenerHaltException();
      }
      break;
    default:
      return;

    }
  }

  private void setReceiptId(DisconnectMessage message) {
    String id = message.getHeader().getReceipt();
    log.info("Disconnect message intercepted, receipt id {}", id);
    setReceiptId(id);
  }

  /**
   * Checks if is close on disconnect message.
   *
   * @return true, if is close on disconnect message
   */
  public boolean isCloseOnDisconnectMessage() {
    return closeOnDisconnectMessage;
  }

  /**
   * Inject the desired behaviour on system startup.
   *
   * @param closeOnDisconnectMessage
   *          the new close on disconnect message
   */
  public void setCloseOnDisconnectMessage(boolean closeOnDisconnectMessage) {
    this.closeOnDisconnectMessage = closeOnDisconnectMessage;
  }

  /**
   * Gets the receipt id.
   *
   * @return the receipt id
   */
  public String getReceiptId() {
    return receiptId;
  }

  /**
   * Sets the receipt id.
   *
   * @param receiptId
   *          the new receipt id
   */
  public void setReceiptId(String receiptId) {
    this.receiptId = receiptId;
  }

}
TOP

Related Classes of asia.stampy.client.listener.disconnect.AbstractDisconnectListenerAndInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.