ctx.sendUpstream(e);
return;
}
// Retrieve the PubSubResponse from the Message that was sent by the
// server.
PubSubResponse response = (PubSubResponse) e.getMessage();
logger.debug("Response received from host: {}, response: {}.",
va(NetUtils.getHostFromChannel(ctx.getChannel()), response));
// Determine if this PubSubResponse is an ack response for a PubSub
// Request or if it is a message being pushed to the client subscriber.
if (response.hasMessage()) {
// Subscribed messages being pushed to the client so handle/consume
// it and return.
if (null == subHandler) {
logger.error("Received message from a non-subscription channel : {}",
response);
} else {
subHandler.handleSubscribeMessage(response);
}
return;
}
// Process Subscription Events
if (response.hasResponseBody()) {
ResponseBody resp = response.getResponseBody();
// A special subscription event indicates the state of a subscriber
if (resp.hasSubscriptionEvent()) {
if (null == subHandler) {
logger.error("Received subscription event from a non-subscription channel : {}",
response);
} else {
SubscriptionEventResponse eventResp = resp.getSubscriptionEvent();
logger.debug("Received subscription event {} for (topic:{}, subscriber:{}).",
va(eventResp.getEvent(), response.getTopic(),
response.getSubscriberId()));
subHandler.handleSubscriptionEvent(response.getTopic(),
response.getSubscriberId(),
eventResp.getEvent());
}
return;
}
}
// Response is an ack to a prior PubSubRequest so first retrieve the
// PubSub data for this txn.
PubSubData pubSubData = txn2PubSubData.remove(response.getTxnId());
// Validate that the PubSub data for this txn is stored. If not, just
// log an error message and return since we don't know how to handle
// this.
if (pubSubData == null) {
logger.error("PubSub Data was not found for PubSubResponse: {}", response);
return;
}
// Store the topic2Host mapping if this wasn't a server redirect. We'll
// assume that if the server was able to have an open Channel connection
// to the client, and responded with an ack message other than the
// NOT_RESPONSIBLE_FOR_TOPIC one, it is the correct topic master.
if (!response.getStatusCode().equals(StatusCode.NOT_RESPONSIBLE_FOR_TOPIC)) {
// Retrieve the server host that we've connected to and store the
// mapping from the topic to this host. For all other non-redirected
// server statuses, we consider that as a successful connection to the
// correct topic master.
InetSocketAddress host = NetUtils.getHostFromChannel(ctx.getChannel());
channelManager.storeTopic2HostMapping(pubSubData.topic, host);
}
// Depending on the operation type, call the appropriate handler.
logger.debug("Handling a {} response: {}, pubSubData: {}, host: {}.",
va(pubSubData.operationType, response, pubSubData, ctx.getChannel()));
AbstractResponseHandler respHandler = handlers.get(pubSubData.operationType);
if (null == respHandler) {
// The above are the only expected PubSubResponse messages received
// from the server for the various client side requests made.
logger.error("Response received from server is for an unhandled operation {}, txnId: {}.",
va(pubSubData.operationType, response.getTxnId()));
pubSubData.getCallback().operationFailed(pubSubData.context,
new UnexpectedConditionException("Can't find response handler for operation "
+ pubSubData.operationType));
return;
}