Package com.linkedin.databus.client.netty

Source Code of com.linkedin.databus.client.netty.BootstrapStartScnHttpResponseProcessor

package com.linkedin.databus.client.netty;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/


import java.io.InputStream;
import java.nio.channels.Channels;
import java.util.Formatter;

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.util.Timer;

import com.linkedin.databus.client.ChunkedBodyReadableByteChannel;
import com.linkedin.databus.client.DatabusBootstrapConnection;
import com.linkedin.databus.client.DatabusBootstrapConnectionStateMessage;
import com.linkedin.databus.client.netty.AbstractNettyHttpConnection.BaseHttpResponseProcessor;
import com.linkedin.databus.client.pub.ServerInfo;
import com.linkedin.databus.core.Checkpoint;
import com.linkedin.databus.core.DbusClientMode;
import com.linkedin.databus.core.DbusConstants;
import com.linkedin.databus.core.DbusPrettyLogUtils;
import com.linkedin.databus.core.InvalidCheckpointException;
import com.linkedin.databus.core.async.ActorMessageQueue;
import com.linkedin.databus2.core.container.ExtendedReadTimeoutHandler;
import com.linkedin.databus2.core.container.monitoring.mbean.ContainerStatisticsCollector;
import com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException;
import com.linkedin.databus2.core.filter.DbusKeyFilter;

public class NettyHttpDatabusBootstrapConnection
             extends AbstractNettyHttpConnection
             implements DatabusBootstrapConnection
{
  public static final String MODULE = NettyHttpDatabusBootstrapConnection.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private static enum State
  {
    TARGET_SCN_REQUEST_CONNECT,
    TARGET_SCN_REQUEST_WRITE,
    START_SCN_REQUEST_CONNECT,
    START_SCN_REQUEST_WRITE,
    STREAM_REQUEST_CONNECT,
    STREAM_REQUEST_WRITE
  }

  private final ActorMessageQueue _callback;
  private DatabusBootstrapConnectionStateMessage _callbackStateReuse;
  private ExtendedReadTimeoutHandler _readTimeOutHandler;
  private State _curState;
  private Checkpoint _checkpoint;
  private String _sourcesIdList;
  private String _sourcesNameList;
  private int _freeBufferSpace;
  private final RemoteExceptionHandler _remoteExceptionHandler;
  private DbusKeyFilter _filter;
  private GenericHttpResponseHandler _handler;
  //private MyConnectListener _connectListener;

  public NettyHttpDatabusBootstrapConnection(ServerInfo server,
                                         ActorMessageQueue callback,
                                         ClientBootstrap bootstrap,
                                         ContainerStatisticsCollector containerStatsCollector,
                                         RemoteExceptionHandler remoteExceptionHandler,
                                         Timer timeoutTimer,
                                         long writeTimeoutMs,
                                         long readTimeoutMs,
                                         int protocolVersion,
                                         ChannelGroup channelGroup)
  {
    super(server, bootstrap, containerStatsCollector, timeoutTimer, writeTimeoutMs, readTimeoutMs,
          channelGroup, protocolVersion, LOG);
    _callback = callback;
    _remoteExceptionHandler = remoteExceptionHandler;

    //_connectListener = new MyConnectListener();
    //setConnectListener(_connectListener);
  }


  public NettyHttpDatabusBootstrapConnection(ServerInfo relay,
                                             ActorMessageQueue callback,
                                             ChannelFactory channelFactory,
                                             ContainerStatisticsCollector containerStatsCollector,
                                             RemoteExceptionHandler remoteExceptionHandler,
                                             Timer timeoutTimer,
                                             long writeTimeoutMs,
                                             long readTimeoutMs,
                                             int protocolVersion,
                                             ChannelGroup channelGroup)
  {
    this(relay,
         callback,
         new ClientBootstrap(channelFactory),
         containerStatsCollector,
         remoteExceptionHandler,
         timeoutTimer,
         writeTimeoutMs,
         readTimeoutMs,
         protocolVersion,
         channelGroup);
  }


  @Override
  public void requestTargetScn(Checkpoint checkpoint, DatabusBootstrapConnectionStateMessage stateReuse)
  {
    _checkpoint = checkpoint;
    _callbackStateReuse = stateReuse;
    _handler = null;

    if (!hasConnection())
    {
      connect(State.TARGET_SCN_REQUEST_CONNECT);
    }
    else
    {
      onTargetScnConnectSuccess();
    }
  }

  void onTargetScnConnectSuccess()
  {
    _curState = State.TARGET_SCN_REQUEST_WRITE;

    ChannelPipeline channelPipeline = _channel.getPipeline();
    _readTimeOutHandler = (ExtendedReadTimeoutHandler)channelPipeline.get(GenericHttpClientPipelineFactory.READ_TIMEOUT_HANDLER_NAME);
    _readTimeOutHandler.start(channelPipeline.getContext(_readTimeOutHandler));

    BootstrapTargetScnHttpResponseProcessor targetResponseProcessor =
        new BootstrapTargetScnHttpResponseProcessor(this, _callback, _callbackStateReuse,
                                                    _checkpoint,
                                                    _remoteExceptionHandler, _readTimeOutHandler);

    final String url = createTargetScnRequestUrl();
    LOG.info("Sending " + url);

    // Prepare the HTTP request.
    HttpRequest request = createEmptyRequest(url);
    sendRequest(request, new TargetScnRequestResultListener(), targetResponseProcessor);
  }

  private String createTargetScnRequestUrl()
  {
    // Adding checkpoint to the targetSCN request for supporting V3 bootstrap. It is unused in case of V2 bootstrap
    return String.format("/targetSCN?source=%s&checkPoint=%s", _checkpoint.getSnapshotSource(), _checkpoint.toString());
  }

  @Override
  public void requestStartScn(Checkpoint checkpoint, DatabusBootstrapConnectionStateMessage stateReuse, String sourceNamesList)
  {
    _checkpoint = checkpoint;
    _callbackStateReuse = stateReuse;
    _sourcesNameList = sourceNamesList;
    _handler = null;

    if (!hasConnection())
    {
      connect(State.START_SCN_REQUEST_CONNECT);
    }
    else
    {
      onStartScnConnectSuccess();
    }
  }

  void onStartScnConnectSuccess()
  {
    _curState = State.START_SCN_REQUEST_WRITE;

    ChannelPipeline channelPipeline = _channel.getPipeline();
    _readTimeOutHandler = (ExtendedReadTimeoutHandler)channelPipeline.get(GenericHttpClientPipelineFactory.READ_TIMEOUT_HANDLER_NAME);
    _readTimeOutHandler.start(channelPipeline.getContext(_readTimeOutHandler));

    BootstrapStartScnHttpResponseProcessor sourcesResponseProcessor =
        new BootstrapStartScnHttpResponseProcessor(this, _callback, _callbackStateReuse,
                                                   _checkpoint,
                                                   _remoteExceptionHandler,
                                                   _readTimeOutHandler);

    final String url = createStartScnRequestUrl();
    LOG.info("Sending " + url);

    // Prepare the HTTP request.
    HttpRequest request = createEmptyRequest(url);
    sendRequest(request, new StartScnRequestResultListener(), sourcesResponseProcessor);
  }

  private String createStartScnRequestUrl()
  {
    return String.format("/startSCN?sources=%s&checkPoint=%s", _sourcesNameList,
                         _checkpoint.toString());
  }

  @Override
  public void requestStream(String sourcesIdList, DbusKeyFilter filter,
                int freeBufferSpace, Checkpoint cp,
                            DatabusBootstrapConnectionStateMessage stateReuse)
  {
    _checkpoint = cp;
    _callbackStateReuse = stateReuse;
    _sourcesIdList = sourcesIdList;
    _freeBufferSpace = freeBufferSpace;
    _filter = filter;
    _handler = null;

    if (!hasConnection())
    {
      connect(State.STREAM_REQUEST_CONNECT);
    }
    else
    {
      onStreamConnectSuccess();
    }
  }

  void onStreamConnectSuccess()
  {
    _curState = State.STREAM_REQUEST_WRITE;

    ChannelPipeline channelPipeline = _channel.getPipeline();
    _readTimeOutHandler = (ExtendedReadTimeoutHandler)channelPipeline.get(GenericHttpClientPipelineFactory.READ_TIMEOUT_HANDLER_NAME);
    _readTimeOutHandler.start(channelPipeline.getContext(_readTimeOutHandler));

    StreamHttpResponseProcessor streamResponseProcessor =
        new StreamHttpResponseProcessor(this, _callback, _callbackStateReuse, _readTimeOutHandler);

    StringBuilder uriString = new StringBuilder(10240);
    boolean error = populateBootstrapRequestUrl(uriString);

    if (error)
    {
      return;
    }

    final String url = uriString.toString();
    if (LOG.isDebugEnabled())
    {
      LOG.debug("Sending " + url);
    }

    // Prepare the HTTP request.
    HttpRequest request = createEmptyRequest(url);
    sendRequest(request, new BootstrapRequestResultListener(), streamResponseProcessor);
  }

  private boolean populateBootstrapRequestUrl(StringBuilder uriString)
  {
    boolean error = false;
    ObjectMapper objMapper = new ObjectMapper();
    String filterStr = null;

    if ( null != _filter)
    {
      try
      {
        filterStr = objMapper.writeValueAsString(_filter);
      } catch( Exception ex) {
        LOG.error("Got exception while serializing filter. Filter was : " + _filter, ex);
        error = true;
        onRequestFailure(uriString.toString(), ex);
      }
    }

    Formatter uriFmt = new Formatter(uriString);
    if ( null != filterStr)
    {
      uriFmt.format("/bootstrap?sources=%s&checkPoint=%s&output=binary&batchSize=%d&filter=%s",
                  _sourcesIdList, _checkpoint.toString(), _freeBufferSpace, filterStr);
    } else {
      uriFmt.format("/bootstrap?sources=%s&checkPoint=%s&output=binary&batchSize=%d",
                _sourcesIdList, _checkpoint.toString(), _freeBufferSpace);
    }
    uriFmt.close(); //make the compiler shut up

    return error;
  }


  private void connect(State connectState)
  {
    _curState = connectState;
    connectWithListener(new MyConnectListener());
  }

  private void onConnectSuccess(Channel channel)
  {
    switch (_curState)
    {
      case START_SCN_REQUEST_CONNECT: onStartScnConnectSuccess(); break;
      case TARGET_SCN_REQUEST_CONNECT: onTargetScnConnectSuccess(); break;
      case STREAM_REQUEST_CONNECT: onStreamConnectSuccess(); break;
      default: throw new RuntimeException("don't know what to do in state:" + _curState);
    }
  }

  /**
   * TODO : This method is overridden to get the _handler local to this class and not the
   * parent class. Once cleanup is performed to use _handler from parent class, this method
   * must be removed
   */
  @Override
  protected GenericHttpResponseHandler getHandler()
  {
    return _handler;
  }

  private void onRequestFailure(HttpRequest req, Throwable cause)
  {
    onRequestFailure(null == req ? (String)null : req.getUri(), cause);
  }

  private void onRequestFailure(String req, Throwable cause)
  {
    LOG.info("request failure: req=" + req + " cause=" + cause);

    if(shouldIgnoreWriteTimeoutException(cause)) {
      LOG.error("got RequestFailure because of WriteTimeoutException");
      return;
    }
    switch (_curState)
    {
      case START_SCN_REQUEST_CONNECT:
      case START_SCN_REQUEST_WRITE:
        _callbackStateReuse.switchToStartScnRequestError(); break;
      case TARGET_SCN_REQUEST_CONNECT:
      case TARGET_SCN_REQUEST_WRITE:
        _callbackStateReuse.switchToTargetScnRequestError(); break;
      case STREAM_REQUEST_CONNECT:
      case STREAM_REQUEST_WRITE:
        _callbackStateReuse.switchToStreamRequestError(); break;
      default: throw new RuntimeException("don't know what to do in state:" + _curState);
    }

    _callback.enqueueMessage(_callbackStateReuse);
  }

  private class MyConnectListener implements ConnectResultListener
  {
    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.ConnectResultListener#onConnectSuccess(org.jboss.netty.channel.Channel)
     */
    @Override
    public void onConnectSuccess(Channel channel)
    {
      NettyHttpDatabusBootstrapConnection.this.onConnectSuccess(channel);
    }

    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.ConnectResultListener#onConnectFailure(java.lang.Throwable)
     */
    @Override
    public void onConnectFailure(Throwable cause)
    {
      NettyHttpDatabusBootstrapConnection.this.onRequestFailure((String)null, cause);
    }
  }

  /** Callback for /startSCN request result */
  private class StartScnRequestResultListener implements SendRequestResultListener
  {
    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestSuccess(org.jboss.netty.handler.codec.http.HttpRequest)
     */
    @Override
    public void onSendRequestSuccess(HttpRequest req)
    {
      //Do nothing
    }

    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestFailure(org.jboss.netty.handler.codec.http.HttpRequest, java.lang.Throwable)
     */
    @Override
    public void onSendRequestFailure(HttpRequest req, Throwable cause)
    {
      //TODO eventually the onRequestFailure can be expanded here
      onRequestFailure(req, cause);
    }
  }

  /** Callback for /targetSCN request result */
  private class TargetScnRequestResultListener implements SendRequestResultListener
  {
    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestSuccess(org.jboss.netty.handler.codec.http.HttpRequest)
     */
    @Override
    public void onSendRequestSuccess(HttpRequest req)
    {
      //Do nothing
    }

    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestFailure(org.jboss.netty.handler.codec.http.HttpRequest, java.lang.Throwable)
     */
    @Override
    public void onSendRequestFailure(HttpRequest req, Throwable cause)
    {
      //TODO eventually the onRequestFailure can be expanded here
      onRequestFailure(req, cause);
    }
  }

  /** Callback for /bootstrap request result */
  private class BootstrapRequestResultListener implements SendRequestResultListener
  {
    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestSuccess(org.jboss.netty.handler.codec.http.HttpRequest)
     */
    @Override
    public void onSendRequestSuccess(HttpRequest req)
    {
      //Do nothing
    }

    /**
     * @see com.linkedin.databus.client.netty.AbstractNettyHttpConnection.SendRequestResultListener#onSendRequestFailure(org.jboss.netty.handler.codec.http.HttpRequest, java.lang.Throwable)
     */
    @Override
    public void onSendRequestFailure(HttpRequest req, Throwable cause)
    {
      //TODO eventually the onRequestFailure can be expanded here
      onRequestFailure(req, cause);
    }
  }
}

class BootstrapTargetScnHttpResponseProcessor extends BaseHttpResponseProcessor
{
  public static final String MODULE = BootstrapTargetScnHttpResponseProcessor.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private final ActorMessageQueue _callback;
  private final DatabusBootstrapConnectionStateMessage _stateReuse;
  private final Checkpoint _checkpoint;
  private final RemoteExceptionHandler _remoteExceptionHandler;

  /**
   * Constructor
   * @param parent                the AbstractNettyHttpConnection object that instantiated this
   *                              response processor
   * @param bootstrapPullThread   callback to send the processed response or errors to
   * @param readStartScnState     a message object to reuse for the callback
   *                              (TODO remove that: premature GC optimization)
   * @param readTimeOutHandler    the ReadTimeoutHandler for the connection handled by this
   *                              response handler.
   */
  public BootstrapTargetScnHttpResponseProcessor(AbstractNettyHttpConnection parent,
                                                 ActorMessageQueue bootstrapPullThread,
                                                 DatabusBootstrapConnectionStateMessage readStartScnState,
                                                 Checkpoint checkpoint,
                                                 RemoteExceptionHandler remoteExceptionHandler,
                                                 ExtendedReadTimeoutHandler readTimeoutHandler)
  {
    super(parent, readTimeoutHandler);
    _callback = bootstrapPullThread;
    _stateReuse = readStartScnState;
    _checkpoint = checkpoint;
    _remoteExceptionHandler = remoteExceptionHandler;
  }

  @Override
  public void finishResponse() throws Exception
  {
    super.finishResponse();

  if (_errorHandled)
  {
    return;
  }

    try
    {
      String exceptionName = RemoteExceptionHandler.getExceptionName(_decorated);
      Throwable remoteException = _remoteExceptionHandler.getException(_decorated);
      if (null != remoteException &&
          remoteException instanceof BootstrapDatabaseTooOldException)
      {
        _remoteExceptionHandler.handleException(remoteException);
      }
      else if (null != exceptionName)
      {
        LOG.error("/targetScn response error: " + RemoteExceptionHandler.getExceptionMessage(_decorated));
        _stateReuse.switchToTargetScnResponseError();
      }
      else
      {
        InputStream bodyStream = Channels.newInputStream(_decorated);
        ObjectMapper mapper = new ObjectMapper();
        String scnString = mapper.readValue(bodyStream, String.class);
        LOG.info("targetScn:" + scnString);

        long targetScn = Long.parseLong(scnString);

        _stateReuse.switchToTargetScnSuccess();

        // make sure we are in the expected mode -- sanity checks
        Checkpoint ckpt = _checkpoint;
        if (ckpt.getConsumptionMode() != DbusClientMode.BOOTSTRAP_SNAPSHOT)
        {
          throw new InvalidCheckpointException("TargetScnResponseProcessor:"
                                     + " expecting in client mode: " + DbusClientMode.BOOTSTRAP_SNAPSHOT,
                                     ckpt);
        }
        else if (! ckpt.isSnapShotSourceCompleted())
        {
          throw new InvalidCheckpointException("TargetScnResponseProcessor: current snapshot source not completed",
                                               ckpt);
        }

        LOG.info("Target SCN "
                 + targetScn
                 + " received for bootstrap catchup source "
                 + ckpt.getCatchupSource()
                 + " after completion of snapshot source "
                 + ckpt.getSnapshotSource());
        ckpt.setBootstrapTargetScn(targetScn);
      }
    }
    catch (Exception ex)
    {
      LOG.error("/targetScn response error:" + ex.getMessage(), ex);
      _stateReuse.switchToTargetScnResponseError();
    }

    _callback.enqueueMessage(_stateReuse);
  }

  @Override
  public void startResponse(HttpResponse response) throws Exception
  {
    _decorated = new ChunkedBodyReadableByteChannel();
    super.startResponse(response);
  }

  @Override
  public void handleChannelException(Throwable cause)
  {
    DbusPrettyLogUtils.logExceptionAtError("Exception during /targetSCN response: ", cause, LOG);
    if (_responseStatus != ResponseStatus.CHUNKS_FINISHED)
    {
      LOG.info("Enqueueing TargetSCN Response Error State to Puller Queue");
      _stateReuse.switchToTargetScnResponseError();
      _callback.enqueueMessage(_stateReuse);
    } else {
      LOG.info("Skipping Enqueueing TargetSCN Response Error State to Puller Queue");

    }
    super.handleChannelException(cause);
  }
}

class BootstrapStartScnHttpResponseProcessor extends BaseHttpResponseProcessor
{
  public static final String MODULE = BootstrapStartScnHttpResponseProcessor.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private final ActorMessageQueue _callback;
  private final DatabusBootstrapConnectionStateMessage _stateReuse;
  private final Checkpoint _checkpoint;
  private final RemoteExceptionHandler _remoteExceptionHandler;

  /**
   * Constructor
   * @param parent                the AbstractNettyHttpConnection object that instantiated this
   *                              response processor
   * @param bootstrapPullThread   callback to send the processed response or errors to
   * @param readStartScnState     a message object to reuse for the callback
   *                              (TODO remove that: premature GC optimization)
   * @param readTimeOutHandler    the ReadTimeoutHandler for the connection handled by this
   *                              response handler.
   */
  public BootstrapStartScnHttpResponseProcessor(AbstractNettyHttpConnection parent,
                                                ActorMessageQueue bootstrapPullThread,
                                                DatabusBootstrapConnectionStateMessage readStartScnState,
                                                Checkpoint checkpoint,
                                                RemoteExceptionHandler remoteExceptionHandler,
                                                ExtendedReadTimeoutHandler readTimeOutHandler)
  {
    super(parent, readTimeOutHandler);
    _callback = bootstrapPullThread;
    _stateReuse = readStartScnState;
    _checkpoint = checkpoint;
    _remoteExceptionHandler = remoteExceptionHandler;
  }

  @Override
  public void finishResponse() throws Exception
  {
    super.finishResponse();

  if (_errorHandled)
  {
    return;
  }

    try
    {
      String exceptionName = RemoteExceptionHandler.getExceptionName(_decorated);
      Throwable remoteException = _remoteExceptionHandler.getException(_decorated);
      if (null != remoteException &&
          remoteException instanceof BootstrapDatabaseTooOldException)
      {
        _remoteExceptionHandler.handleException(remoteException);
      }
      else if (null != exceptionName)
      {
        LOG.error("/startScn response error: " + RemoteExceptionHandler.getExceptionMessage(_decorated));
        _stateReuse.switchToStartScnResponseError();
        LOG.error("Failed to process /startscn response");
      }
      else
      {
        String hostHdr = DbusConstants.UNKNOWN_HOST;
        String svcHdr = DbusConstants.UNKNOWN_SERVICE_ID;

        if (null != getParent())
        {
          hostHdr = getParent().getRemoteHost();
          svcHdr = getParent().getRemoteService();
          LOG.info("initiated bootstrap sesssion to host " + hostHdr + " service " + svcHdr);
        }

        InputStream bodyStream = Channels.newInputStream(_decorated);

        ObjectMapper mapper = new ObjectMapper();
        String scnString = mapper.readValue(bodyStream, String.class);

        ServerInfo serverInfo  = null;
        String serverHostPort = _decorated.getMetadata(DbusConstants.SERVER_INFO_HOSTPORT_HEADER_PARAM);
        try
        {
          serverInfo = ServerInfo.buildServerInfoFromHostPort(serverHostPort, DbusConstants.HOSTPORT_DELIMITER);
        } catch(Exception ex) {
          LOG.error("Unable to extract Boostrap Server info from StartSCN response. ServerInfo was :" + serverHostPort, ex);
        }

        LOG.info("Response startScn:" + scnString + ", from bootstrap Server :" + serverHostPort);
        long startScn = Long.parseLong(scnString);
        Checkpoint ckpt = _checkpoint;

        if (startScn < 0)
        {
          LOG.error("unexpected value for startSCN: " + startScn);
          _stateReuse.switchToStartScnResponseError();
        }
        else if (ckpt.getConsumptionMode() != DbusClientMode.BOOTSTRAP_SNAPSHOT)
        {
          LOG.error("StartScnResponseProcessor:" + " expecting in client mode: " + DbusClientMode.BOOTSTRAP_SNAPSHOT
                    + " while in the incorrect mode: " + ckpt.getConsumptionMode());
        }
        else
        {
          LOG.info("Start SCN "
                    + startScn
                    + " received for bootstrap snapshot source "
                    + ckpt.getSnapshotSource());
          ckpt.setBootstrapStartScn(startScn);
          ckpt.setBootstrapServerInfo(serverHostPort);

          /*
           * No need to create a seperate BootstrapConnection as we are guaranteed to have a bootstrap Connection
           * at this point.
           */
          _stateReuse.switchToStartScnSuccess(_checkpoint, null, serverInfo);
        }
      }
    }
    catch (Exception ex)
    {
      LOG.error("Failed to process /startscn response", ex);
      _stateReuse.switchToStartScnResponseError();
    }

    _callback.enqueueMessage(_stateReuse);
  }

  @Override
  public void startResponse(HttpResponse response) throws Exception
  {
    _decorated = new ChunkedBodyReadableByteChannel();
    super.startResponse(response);
  }

  @Override
  public void handleChannelException(Throwable cause)
  {
    DbusPrettyLogUtils.logExceptionAtError("Exception during /startSCN response: ", cause, LOG);
    if (_responseStatus != ResponseStatus.CHUNKS_FINISHED)
    {
      LOG.info("Enqueueing StartSCN Response Error State to Puller Queue");
      _stateReuse.switchToStartScnResponseError();
      _callback.enqueueMessage(_stateReuse);
    } else {
      LOG.info("Skipping Enqueueing StartSCN Response Error State to Puller Queue");
    }
    super.handleChannelException(cause);
  }
}
TOP

Related Classes of com.linkedin.databus.client.netty.BootstrapStartScnHttpResponseProcessor

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.