@SuppressWarnings("rawtypes")
public static QueueSession establishNegotiation(EJValue val, QueueChannel queueChannel, ErraiService service)
throws IOException {
QueueSession session = null;
final EJObject ejObject = val.isObject();
if (ejObject == null) {
return null;
}
final String commandType = ejObject.get(MessageParts.CommandType.name()).isString().stringValue();
// this client apparently wants to connect.
if (BusCommand.Associate.name().equals(commandType)) {
final String sessionKey = ejObject.get(MessageParts.ConnectionSessionKey.name()).isString().stringValue();
// has this client already attempted a connection, and is in a wait verify
// state
if (sessionKey != null && (session = service.getBus().getSessionBySessionId(sessionKey)) != null) {
final LocalContext localCometSession = LocalContext.get(session);
if (localCometSession.hasAttribute(WebSocketServerHandler.SESSION_ATTR_WS_STATUS)
&& WebSocketServerHandler.WEBSOCKET_ACTIVE.equals(localCometSession.getAttribute(String.class,
WebSocketServerHandler.SESSION_ATTR_WS_STATUS))) {
// set the session queue into direct channel mode.
final MessageQueue queue = service.getBus().getQueueBySession(sessionKey);
queue.setDeliveryHandler(DirectDeliveryHandler.createFor(queueChannel));
LOGGER.debug("set direct delivery handler on session: {}", session.getSessionId());
return session;
}
// check the activation key matches.
final EJString activationKey = ejObject.get(MessageParts.WebSocketToken.name()).isString();
if (activationKey == null || !WebSocketTokenManager.verifyOneTimeToken(session, activationKey.stringValue())) {
// nope. go away!
final String error = "bad negotiation key";
LOGGER.debug("activation key not match for session: {}", session.getSessionId());
sendMessage(queueChannel, WebSocketNegotiationMessage.getFailedNegotiation(error));
}
else {
// the key matches. now we send the reverse challenge to prove this
// client is actually
// already talking to the bus over the COMET channel.
final String reverseToken = WebSocketTokenManager.getNewOneTimeToken(session);
localCometSession.setAttribute(WebSocketServerHandler.SESSION_ATTR_WS_STATUS,
WebSocketServerHandler.WEBSOCKET_AWAIT_ACTIVATION);
// send the challenge.
LOGGER.debug("reverse challange for session: {}", session.getSessionId());
sendMessage(queueChannel, WebSocketNegotiationMessage.getReverseChallenge(reverseToken));
return null;
}
sendMessage(queueChannel, WebSocketNegotiationMessage.getSuccessfulNegotiation());
}