Search in sources :

Example 1 with ClientAck

use of com.alibaba.otter.canal.protocol.CanalPacket.ClientAck in project canal by alibaba.

the class SimpleCanalConnector method ack.

public void ack(long batchId) throws CanalClientException {
    waitClientRunning();
    ClientAck ca = ClientAck.newBuilder().setDestination(clientIdentity.getDestination()).setClientId(String.valueOf(clientIdentity.getClientId())).setBatchId(batchId).build();
    try {
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTACK).setBody(ca.toByteString()).build().toByteArray());
    } catch (IOException e) {
        throw new CanalClientException(e);
    }
}
Also used : CanalClientException(com.alibaba.otter.canal.protocol.exception.CanalClientException) IOException(java.io.IOException) ClientAck(com.alibaba.otter.canal.protocol.CanalPacket.ClientAck)

Example 2 with ClientAck

use of com.alibaba.otter.canal.protocol.CanalPacket.ClientAck in project canal by alibaba.

the class SessionHandler method messageReceived.

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    logger.info("message receives in session handler...");
    ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
    Packet packet = Packet.parseFrom(buffer.readBytes(buffer.readableBytes()).array());
    ClientIdentity clientIdentity = null;
    try {
        switch(packet.getType()) {
            case SUBSCRIPTION:
                Sub sub = Sub.parseFrom(packet.getBody());
                if (StringUtils.isNotEmpty(sub.getDestination()) && StringUtils.isNotEmpty(sub.getClientId())) {
                    clientIdentity = new ClientIdentity(sub.getDestination(), Short.valueOf(sub.getClientId()), sub.getFilter());
                    MDC.put("destination", clientIdentity.getDestination());
                    // 尝试启动,如果已经启动,忽略
                    if (!embeddedServer.isStart(clientIdentity.getDestination())) {
                        ServerRunningMonitor runningMonitor = ServerRunningMonitors.getRunningMonitor(clientIdentity.getDestination());
                        if (!runningMonitor.isStart()) {
                            runningMonitor.start();
                        }
                    }
                    embeddedServer.subscribe(clientIdentity);
                    // 设置状态数据
                    ctx.setAttachment(clientIdentity);
                    NettyUtils.ack(ctx.getChannel(), null);
                } else {
                    NettyUtils.error(401, MessageFormatter.format("destination or clientId is null", sub.toString()).getMessage(), ctx.getChannel(), null);
                }
                break;
            case UNSUBSCRIPTION:
                Unsub unsub = Unsub.parseFrom(packet.getBody());
                if (StringUtils.isNotEmpty(unsub.getDestination()) && StringUtils.isNotEmpty(unsub.getClientId())) {
                    clientIdentity = new ClientIdentity(unsub.getDestination(), Short.valueOf(unsub.getClientId()), unsub.getFilter());
                    MDC.put("destination", clientIdentity.getDestination());
                    embeddedServer.unsubscribe(clientIdentity);
                    // 尝试关闭
                    stopCanalInstanceIfNecessary(clientIdentity);
                    NettyUtils.ack(ctx.getChannel(), null);
                } else {
                    NettyUtils.error(401, MessageFormatter.format("destination or clientId is null", unsub.toString()).getMessage(), ctx.getChannel(), null);
                }
                break;
            case GET:
                Get get = CanalPacket.Get.parseFrom(packet.getBody());
                if (StringUtils.isNotEmpty(get.getDestination()) && StringUtils.isNotEmpty(get.getClientId())) {
                    clientIdentity = new ClientIdentity(get.getDestination(), Short.valueOf(get.getClientId()));
                    MDC.put("destination", clientIdentity.getDestination());
                    Message message = null;
                    // } else {
                    if (get.getTimeout() == -1) {
                        // 是否是初始值
                        message = embeddedServer.getWithoutAck(clientIdentity, get.getFetchSize());
                    } else {
                        TimeUnit unit = convertTimeUnit(get.getUnit());
                        message = embeddedServer.getWithoutAck(clientIdentity, get.getFetchSize(), get.getTimeout(), unit);
                    }
                    // }
                    Packet.Builder packetBuilder = CanalPacket.Packet.newBuilder();
                    packetBuilder.setType(PacketType.MESSAGES);
                    Messages.Builder messageBuilder = CanalPacket.Messages.newBuilder();
                    messageBuilder.setBatchId(message.getId());
                    if (message.getId() != -1 && !CollectionUtils.isEmpty(message.getEntries())) {
                        for (Entry entry : message.getEntries()) {
                            messageBuilder.addMessages(entry.toByteString());
                        }
                    }
                    packetBuilder.setBody(messageBuilder.build().toByteString());
                    // 输出数据
                    NettyUtils.write(ctx.getChannel(), packetBuilder.build().toByteArray(), null);
                } else {
                    NettyUtils.error(401, MessageFormatter.format("destination or clientId is null", get.toString()).getMessage(), ctx.getChannel(), null);
                }
                break;
            case CLIENTACK:
                ClientAck ack = CanalPacket.ClientAck.parseFrom(packet.getBody());
                MDC.put("destination", ack.getDestination());
                if (StringUtils.isNotEmpty(ack.getDestination()) && StringUtils.isNotEmpty(ack.getClientId())) {
                    if (ack.getBatchId() == 0L) {
                        NettyUtils.error(402, MessageFormatter.format("batchId should assign value", ack.toString()).getMessage(), ctx.getChannel(), null);
                    } else if (ack.getBatchId() == -1L) {
                    // -1代表上一次get没有数据,直接忽略之
                    // donothing
                    } else {
                        clientIdentity = new ClientIdentity(ack.getDestination(), Short.valueOf(ack.getClientId()));
                        embeddedServer.ack(clientIdentity, ack.getBatchId());
                    }
                } else {
                    NettyUtils.error(401, MessageFormatter.format("destination or clientId is null", ack.toString()).getMessage(), ctx.getChannel(), null);
                }
                break;
            case CLIENTROLLBACK:
                ClientRollback rollback = CanalPacket.ClientRollback.parseFrom(packet.getBody());
                MDC.put("destination", rollback.getDestination());
                if (StringUtils.isNotEmpty(rollback.getDestination()) && StringUtils.isNotEmpty(rollback.getClientId())) {
                    clientIdentity = new ClientIdentity(rollback.getDestination(), Short.valueOf(rollback.getClientId()));
                    if (rollback.getBatchId() == 0L) {
                        // 回滚所有批次
                        embeddedServer.rollback(clientIdentity);
                    } else {
                        // 只回滚单个批次
                        embeddedServer.rollback(clientIdentity, rollback.getBatchId());
                    }
                } else {
                    NettyUtils.error(401, MessageFormatter.format("destination or clientId is null", rollback.toString()).getMessage(), ctx.getChannel(), null);
                }
                break;
            default:
                NettyUtils.error(400, MessageFormatter.format("packet type={} is NOT supported!", packet.getType()).getMessage(), ctx.getChannel(), null);
                break;
        }
    } catch (Throwable exception) {
        NettyUtils.error(400, MessageFormatter.format("something goes wrong with channel:{}, exception={}", ctx.getChannel(), ExceptionUtils.getStackTrace(exception)).getMessage(), ctx.getChannel(), null);
    } finally {
        MDC.remove("destination");
    }
}
Also used : CanalPacket(com.alibaba.otter.canal.protocol.CanalPacket) Packet(com.alibaba.otter.canal.protocol.CanalPacket.Packet) Sub(com.alibaba.otter.canal.protocol.CanalPacket.Sub) Messages(com.alibaba.otter.canal.protocol.CanalPacket.Messages) Message(com.alibaba.otter.canal.protocol.Message) Unsub(com.alibaba.otter.canal.protocol.CanalPacket.Unsub) ClientAck(com.alibaba.otter.canal.protocol.CanalPacket.ClientAck) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) Entry(com.alibaba.otter.canal.protocol.CanalEntry.Entry) ClientIdentity(com.alibaba.otter.canal.protocol.ClientIdentity) ClientRollback(com.alibaba.otter.canal.protocol.CanalPacket.ClientRollback) Get(com.alibaba.otter.canal.protocol.CanalPacket.Get) TimeUnit(java.util.concurrent.TimeUnit) ServerRunningMonitor(com.alibaba.otter.canal.common.zookeeper.running.ServerRunningMonitor)

Aggregations

ClientAck (com.alibaba.otter.canal.protocol.CanalPacket.ClientAck)2 ServerRunningMonitor (com.alibaba.otter.canal.common.zookeeper.running.ServerRunningMonitor)1 Entry (com.alibaba.otter.canal.protocol.CanalEntry.Entry)1 CanalPacket (com.alibaba.otter.canal.protocol.CanalPacket)1 ClientRollback (com.alibaba.otter.canal.protocol.CanalPacket.ClientRollback)1 Get (com.alibaba.otter.canal.protocol.CanalPacket.Get)1 Messages (com.alibaba.otter.canal.protocol.CanalPacket.Messages)1 Packet (com.alibaba.otter.canal.protocol.CanalPacket.Packet)1 Sub (com.alibaba.otter.canal.protocol.CanalPacket.Sub)1 Unsub (com.alibaba.otter.canal.protocol.CanalPacket.Unsub)1 ClientIdentity (com.alibaba.otter.canal.protocol.ClientIdentity)1 Message (com.alibaba.otter.canal.protocol.Message)1 CanalClientException (com.alibaba.otter.canal.protocol.exception.CanalClientException)1 IOException (java.io.IOException)1 TimeUnit (java.util.concurrent.TimeUnit)1 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)1