package org.sdnplatform.sync.internal.remote;
import java.util.List;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import org.sdnplatform.sync.Versioned;
import org.sdnplatform.sync.error.AuthException;
import org.sdnplatform.sync.error.SyncException;
import org.sdnplatform.sync.error.SyncException.ErrorType;
import org.sdnplatform.sync.internal.config.AuthScheme;
import org.sdnplatform.sync.internal.rpc.AbstractRPCChannelHandler;
import org.sdnplatform.sync.internal.rpc.TProtocolUtil;
import org.sdnplatform.sync.internal.util.CryptoUtil;
import org.sdnplatform.sync.thrift.CursorResponseMessage;
import org.sdnplatform.sync.thrift.DeleteResponseMessage;
import org.sdnplatform.sync.thrift.ErrorMessage;
import org.sdnplatform.sync.thrift.GetResponseMessage;
import org.sdnplatform.sync.thrift.HelloMessage;
import org.sdnplatform.sync.thrift.PutResponseMessage;
import org.sdnplatform.sync.thrift.RegisterResponseMessage;
/**
* Implement the client side of the RPC service for the
* {@link RemoteSyncManager}
* @see RemoteSyncManager
* @author readams
*/
public class RemoteSyncChannelHandler extends AbstractRPCChannelHandler {
RemoteSyncManager syncManager;
public RemoteSyncChannelHandler(RemoteSyncManager syncManager) {
super();
this.syncManager = syncManager;
}
// ****************************
// IdleStateAwareChannelHandler
// ****************************
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
syncManager.cg.add(ctx.channel());
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
this.syncManager.channel = null;
syncManager.ready = false;
syncManager.channelDisconnected(null);
super.channelInactive(ctx);
}
// ******************************************
// AbstractRPCChannelHandler message handlers
// ******************************************
@Override
protected void handleHello(HelloMessage hello, Channel channel) {
syncManager.remoteNodeId = hello.getNodeId();
syncManager.ready = true;
synchronized (syncManager.readyNotify) {
syncManager.notifyAll();
}
}
@Override
protected void handleGetResponse(GetResponseMessage response,
Channel channel) {
List<Versioned<byte[]>> values =
TProtocolUtil.getVersionedList(response.getValues());
SyncReply reply = new SyncReply(values, null, true, null, 0);
syncManager.dispatchReply(response.getHeader().getTransactionId(),
reply);
}
@Override
protected void handlePutResponse(PutResponseMessage response,
Channel channel) {
SyncReply reply = new SyncReply(null, null, true, null, 0);
syncManager.dispatchReply(response.getHeader().getTransactionId(),
reply);
}
@Override
protected void handleDeleteResponse(DeleteResponseMessage response,
Channel channel) {
SyncReply reply = new SyncReply(null, null,
response.isDeleted(), null, 0);
syncManager.dispatchReply(response.getHeader().getTransactionId(),
reply);
}
@Override
protected void handleCursorResponse(CursorResponseMessage response,
Channel channel) {
SyncReply reply = new SyncReply(null, response.getValues(), true,
null, response.getCursorId());
syncManager.dispatchReply(response.getHeader().getTransactionId(),
reply);
}
@Override
protected void handleRegisterResponse(RegisterResponseMessage response,
Channel channel) {
SyncReply reply = new SyncReply(null, null,
true, null, 0);
syncManager.dispatchReply(response.getHeader().getTransactionId(),
reply);
}
@Override
protected void handleError(ErrorMessage error, Channel channel) {
ErrorType errType = ErrorType.GENERIC;
for (ErrorType e : ErrorType.values()) {
if (e.getValue() == error.getError().getErrorCode()) {
errType = e;
break;
}
}
SyncException ex =
SyncException.newInstance(errType,
error.getError().getMessage(),
null);
if (ChannelState.CONNECTED.equals(channelState) ||
ChannelState.OPEN.equals(channelState) ||
ErrorType.AUTH.equals(errType)) {
syncManager.channelDisconnected(ex);
channel.close();
} else {
SyncReply reply = new SyncReply(null, null, false, ex, 0);
syncManager.dispatchReply(error.getHeader().getTransactionId(),
reply);
}
}
// *************************
// AbstractRPCChannelHandler
// *************************
@Override
protected Short getRemoteNodeId() {
return syncManager.remoteNodeId;
}
@Override
protected Short getLocalNodeId() {
return null;
}
@Override
protected String getLocalNodeIdString() {
return "client";
}
@Override
protected int getTransactionId() {
return syncManager.getTransactionId();
}
@Override
protected AuthScheme getAuthScheme() {
return syncManager.authScheme;
}
@Override
protected byte[] getSharedSecret() throws AuthException {
try {
return CryptoUtil.getSharedSecret(syncManager.keyStorePath,
syncManager.keyStorePassword);
} catch (Exception e) {
throw new AuthException("Could not read challenge/response " +
"shared secret from key store " +
syncManager.keyStorePath, e);
}
}
}