Search in sources :

Example 1 with ClientAuth

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

the class CanalServerWithNettyTest method testAuth.

@Test
public void testAuth() {
    try {
        SocketChannel channel = SocketChannel.open();
        channel.connect(new InetSocketAddress("127.0.0.1", 1088));
        Packet p = Packet.parseFrom(readNextPacket(channel));
        if (p.getVersion() != 1) {
            throw new Exception("unsupported version at this client.");
        }
        if (p.getType() != PacketType.HANDSHAKE) {
            throw new Exception("expect handshake but found other type.");
        }
        //
        Handshake handshake = Handshake.parseFrom(p.getBody());
        System.out.println(handshake.getSupportedCompressionsList());
        //
        ClientAuth ca = ClientAuth.newBuilder().setUsername("").setNetReadTimeout(10000).setNetWriteTimeout(10000).build();
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTAUTHENTICATION).setBody(ca.toByteString()).build().toByteArray());
        //
        p = Packet.parseFrom(readNextPacket(channel));
        if (p.getType() != PacketType.ACK) {
            throw new Exception("unexpected packet type when ack is expected");
        }
        Ack ack = Ack.parseFrom(p.getBody());
        if (ack.getErrorCode() > 0) {
            throw new Exception("something goes wrong when doing authentication: " + ack.getErrorMessage());
        }
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.SUBSCRIPTION).setBody(Sub.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
        //
        p = Packet.parseFrom(readNextPacket(channel));
        ack = Ack.parseFrom(p.getBody());
        if (ack.getErrorCode() > 0) {
            throw new Exception("failed to subscribe with reason: " + ack.getErrorMessage());
        }
        for (int i = 0; i < 10; i++) {
            writeWithHeader(channel, Packet.newBuilder().setType(PacketType.GET).setBody(Get.newBuilder().setDestination(DESTINATION).setClientId("1").setFetchSize(10).build().toByteString()).build().toByteArray());
            p = Packet.parseFrom(readNextPacket(channel));
            long batchId = -1L;
            switch(p.getType()) {
                case MESSAGES:
                    {
                        Messages messages = Messages.parseFrom(p.getBody());
                        batchId = messages.getBatchId();
                        break;
                    }
                case ACK:
                    {
                        ack = Ack.parseFrom(p.getBody());
                        if (ack.getErrorCode() > 0) {
                            throw new Exception("failed to subscribe with reason: " + ack.getErrorMessage());
                        }
                        break;
                    }
                default:
                    {
                        throw new Exception("unexpected packet type: " + p.getType());
                    }
            }
            System.out.println("!!!!!!!!!!!!!!!!! " + batchId);
            Thread.sleep(1000L);
            writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTACK).setBody(ClientAck.newBuilder().setDestination(DESTINATION).setClientId("1").setBatchId(batchId).build().toByteString()).build().toByteArray());
        }
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTROLLBACK).setBody(ClientRollback.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.UNSUBSCRIPTION).setBody(Unsub.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) Packet(com.alibaba.otter.canal.protocol.CanalPacket.Packet) Messages(com.alibaba.otter.canal.protocol.CanalPacket.Messages) InetSocketAddress(java.net.InetSocketAddress) Ack(com.alibaba.otter.canal.protocol.CanalPacket.Ack) ClientAck(com.alibaba.otter.canal.protocol.CanalPacket.ClientAck) ClientAuth(com.alibaba.otter.canal.protocol.CanalPacket.ClientAuth) IOException(java.io.IOException) Handshake(com.alibaba.otter.canal.protocol.CanalPacket.Handshake) Test(org.junit.Test)

Example 2 with ClientAuth

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

the class SimpleCanalConnector method doConnect.

private InetSocketAddress doConnect() throws CanalClientException {
    try {
        channel = SocketChannel.open();
        channel.socket().setSoTimeout(soTimeout);
        SocketAddress address = getAddress();
        if (address == null) {
            address = getNextAddress();
        }
        channel.connect(address);
        readableChannel = Channels.newChannel(channel.socket().getInputStream());
        writableChannel = Channels.newChannel(channel.socket().getOutputStream());
        Packet p = Packet.parseFrom(readNextPacket());
        if (p.getVersion() != 1) {
            throw new CanalClientException("unsupported version at this client.");
        }
        if (p.getType() != PacketType.HANDSHAKE) {
            throw new CanalClientException("expect handshake but found other type.");
        }
        // 
        Handshake handshake = Handshake.parseFrom(p.getBody());
        supportedCompressions.add(handshake.getSupportedCompressions());
        // 
        // seed for auth
        ByteString seed = handshake.getSeeds();
        String newPasswd = password;
        if (password != null) {
            // encode passwd
            newPasswd = SecurityUtil.byte2HexStr(SecurityUtil.scramble411(password.getBytes(), seed.toByteArray()));
        }
        ClientAuth ca = ClientAuth.newBuilder().setUsername(username != null ? username : "").setPassword(ByteString.copyFromUtf8(newPasswd != null ? newPasswd : "")).setNetReadTimeout(idleTimeout).setNetWriteTimeout(idleTimeout).build();
        writeWithHeader(Packet.newBuilder().setType(PacketType.CLIENTAUTHENTICATION).setBody(ca.toByteString()).build().toByteArray());
        // 
        Packet ack = Packet.parseFrom(readNextPacket());
        if (ack.getType() != PacketType.ACK) {
            throw new CanalClientException("unexpected packet type when ack is expected");
        }
        Ack ackBody = Ack.parseFrom(ack.getBody());
        if (ackBody.getErrorCode() > 0) {
            throw new CanalClientException("something goes wrong when doing authentication: " + ackBody.getErrorMessage());
        }
        connected = true;
        return new InetSocketAddress(channel.socket().getLocalAddress(), channel.socket().getLocalPort());
    } catch (IOException | NoSuchAlgorithmException e) {
        throw new CanalClientException(e);
    }
}
Also used : Packet(com.alibaba.otter.canal.protocol.CanalPacket.Packet) CanalClientException(com.alibaba.otter.canal.protocol.exception.CanalClientException) ByteString(com.google.protobuf.ByteString) InetSocketAddress(java.net.InetSocketAddress) Ack(com.alibaba.otter.canal.protocol.CanalPacket.Ack) ClientAck(com.alibaba.otter.canal.protocol.CanalPacket.ClientAck) ByteString(com.google.protobuf.ByteString) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) ClientAuth(com.alibaba.otter.canal.protocol.CanalPacket.ClientAuth) Handshake(com.alibaba.otter.canal.protocol.CanalPacket.Handshake)

Example 3 with ClientAuth

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

the class ClientAuthenticationHandler method messageReceived.

public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
    final Packet packet = Packet.parseFrom(buffer.readBytes(buffer.readableBytes()).array());
    switch(packet.getVersion()) {
        case SUPPORTED_VERSION:
        default:
            final ClientAuth clientAuth = ClientAuth.parseFrom(packet.getBody());
            if (seed == null) {
                byte[] errorBytes = NettyUtils.errorPacket(400, MessageFormatter.format("auth failed for seed is null", clientAuth.getUsername()).getMessage());
                NettyUtils.write(ctx.getChannel(), errorBytes, null);
            }
            if (!embeddedServer.auth(clientAuth.getUsername(), clientAuth.getPassword().toStringUtf8(), seed)) {
                byte[] errorBytes = NettyUtils.errorPacket(400, MessageFormatter.format("auth failed for user:{}", clientAuth.getUsername()).getMessage());
                NettyUtils.write(ctx.getChannel(), errorBytes, null);
            }
            // 如果存在订阅信息
            if (StringUtils.isNotEmpty(clientAuth.getDestination()) && StringUtils.isNotEmpty(clientAuth.getClientId())) {
                ClientIdentity clientIdentity = new ClientIdentity(clientAuth.getDestination(), Short.valueOf(clientAuth.getClientId()), clientAuth.getFilter());
                try {
                    MDC.put("destination", clientIdentity.getDestination());
                    embeddedServer.subscribe(clientIdentity);
                    // 尝试启动,如果已经启动,忽略
                    if (!embeddedServer.isStart(clientIdentity.getDestination())) {
                        ServerRunningMonitor runningMonitor = ServerRunningMonitors.getRunningMonitor(clientIdentity.getDestination());
                        if (!runningMonitor.isStart()) {
                            runningMonitor.start();
                        }
                    }
                } finally {
                    MDC.remove("destination");
                }
            }
            // 鉴权一次性,暂不统计
            NettyUtils.ack(ctx.getChannel(), future -> {
                logger.info("remove unused channel handlers after authentication is done successfully.");
                ctx.getPipeline().remove(HandshakeInitializationHandler.class.getName());
                ctx.getPipeline().remove(ClientAuthenticationHandler.class.getName());
                int readTimeout = defaultSubscriptorDisconnectIdleTimeout;
                int writeTimeout = defaultSubscriptorDisconnectIdleTimeout;
                if (clientAuth.getNetReadTimeout() > 0) {
                    readTimeout = clientAuth.getNetReadTimeout();
                }
                if (clientAuth.getNetWriteTimeout() > 0) {
                    writeTimeout = clientAuth.getNetWriteTimeout();
                }
                // fix bug: soTimeout parameter's unit from connector is
                // millseconds.
                IdleStateHandler idleStateHandler = new IdleStateHandler(NettyUtils.hashedWheelTimer, readTimeout, writeTimeout, 0, TimeUnit.MILLISECONDS);
                ctx.getPipeline().addBefore(SessionHandler.class.getName(), IdleStateHandler.class.getName(), idleStateHandler);
                IdleStateAwareChannelHandler idleStateAwareChannelHandler = new IdleStateAwareChannelHandler() {

                    public void channelIdle(ChannelHandlerContext ctx1, IdleStateEvent e1) throws Exception {
                        logger.warn("channel:{} idle timeout exceeds, close channel to save server resources...", ctx1.getChannel());
                        ctx1.getChannel().close();
                    }
                };
                ctx.getPipeline().addBefore(SessionHandler.class.getName(), IdleStateAwareChannelHandler.class.getName(), idleStateAwareChannelHandler);
            });
            break;
    }
}
Also used : Packet(com.alibaba.otter.canal.protocol.CanalPacket.Packet) ChannelHandlerContext(org.jboss.netty.channel.ChannelHandlerContext) ClientAuth(com.alibaba.otter.canal.protocol.CanalPacket.ClientAuth) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) IdleStateEvent(org.jboss.netty.handler.timeout.IdleStateEvent) ClientIdentity(com.alibaba.otter.canal.protocol.ClientIdentity) IdleStateHandler(org.jboss.netty.handler.timeout.IdleStateHandler) ServerRunningMonitor(com.alibaba.otter.canal.common.zookeeper.running.ServerRunningMonitor) IdleStateAwareChannelHandler(org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler)

Example 4 with ClientAuth

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

the class CanalServerTest method testAuth.

@Test
public void testAuth() {
    try {
        SocketChannel channel = SocketChannel.open();
        channel.connect(new InetSocketAddress("127.0.0.1", 1088));
        Packet p = Packet.parseFrom(readNextPacket(channel));
        if (p.getVersion() != 1) {
            throw new Exception("unsupported version at this client.");
        }
        if (p.getType() != PacketType.HANDSHAKE) {
            throw new Exception("expect handshake but found other type.");
        }
        // 
        Handshake handshake = Handshake.parseFrom(p.getBody());
        System.out.println(handshake.getSupportedCompressions());
        // 
        ClientAuth ca = ClientAuth.newBuilder().setUsername("").setNetReadTimeout(10000).setNetWriteTimeout(10000).build();
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTAUTHENTICATION).setVersion(NettyUtils.VERSION).setBody(ca.toByteString()).build().toByteArray());
        // 
        p = Packet.parseFrom(readNextPacket(channel));
        if (p.getType() != PacketType.ACK) {
            throw new Exception("unexpected packet type when ack is expected");
        }
        Ack ack = Ack.parseFrom(p.getBody());
        if (ack.getErrorCode() > 0) {
            throw new Exception("something goes wrong when doing authentication: " + ack.getErrorMessage());
        }
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.SUBSCRIPTION).setVersion(NettyUtils.VERSION).setBody(Sub.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
        // 
        p = Packet.parseFrom(readNextPacket(channel));
        ack = Ack.parseFrom(p.getBody());
        if (ack.getErrorCode() > 0) {
            throw new Exception("failed to subscribe with reason: " + ack.getErrorMessage());
        }
        for (int i = 0; i < 10; i++) {
            writeWithHeader(channel, Packet.newBuilder().setType(PacketType.GET).setVersion(NettyUtils.VERSION).setBody(Get.newBuilder().setDestination(DESTINATION).setClientId("1").setFetchSize(10).build().toByteString()).build().toByteArray());
            p = Packet.parseFrom(readNextPacket(channel));
            long batchId = -1L;
            switch(p.getType()) {
                case MESSAGES:
                    {
                        Messages messages = Messages.parseFrom(p.getBody());
                        batchId = messages.getBatchId();
                        break;
                    }
                case ACK:
                    {
                        ack = Ack.parseFrom(p.getBody());
                        if (ack.getErrorCode() > 0) {
                            throw new Exception("failed to subscribe with reason: " + ack.getErrorMessage());
                        }
                        break;
                    }
                default:
                    {
                        throw new Exception("unexpected packet type: " + p.getType());
                    }
            }
            System.out.println("!!!!!!!!!!!!!!!!! " + batchId);
            Thread.sleep(1000L);
            writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTACK).setVersion(NettyUtils.VERSION).setBody(ClientAck.newBuilder().setDestination(DESTINATION).setClientId("1").setBatchId(batchId).build().toByteString()).build().toByteArray());
        }
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.CLIENTROLLBACK).setVersion(NettyUtils.VERSION).setBody(ClientRollback.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
        writeWithHeader(channel, Packet.newBuilder().setType(PacketType.UNSUBSCRIPTION).setVersion(NettyUtils.VERSION).setBody(Unsub.newBuilder().setDestination(DESTINATION).setClientId("1").build().toByteString()).build().toByteArray());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) Packet(com.alibaba.otter.canal.protocol.CanalPacket.Packet) Messages(com.alibaba.otter.canal.protocol.CanalPacket.Messages) InetSocketAddress(java.net.InetSocketAddress) Ack(com.alibaba.otter.canal.protocol.CanalPacket.Ack) ClientAck(com.alibaba.otter.canal.protocol.CanalPacket.ClientAck) ClientAuth(com.alibaba.otter.canal.protocol.CanalPacket.ClientAuth) IOException(java.io.IOException) Handshake(com.alibaba.otter.canal.protocol.CanalPacket.Handshake) Test(org.junit.Test)

Aggregations

ClientAuth (com.alibaba.otter.canal.protocol.CanalPacket.ClientAuth)4 Packet (com.alibaba.otter.canal.protocol.CanalPacket.Packet)4 Ack (com.alibaba.otter.canal.protocol.CanalPacket.Ack)3 ClientAck (com.alibaba.otter.canal.protocol.CanalPacket.ClientAck)3 Handshake (com.alibaba.otter.canal.protocol.CanalPacket.Handshake)3 IOException (java.io.IOException)3 InetSocketAddress (java.net.InetSocketAddress)3 Messages (com.alibaba.otter.canal.protocol.CanalPacket.Messages)2 SocketChannel (java.nio.channels.SocketChannel)2 Test (org.junit.Test)2 ServerRunningMonitor (com.alibaba.otter.canal.common.zookeeper.running.ServerRunningMonitor)1 ClientIdentity (com.alibaba.otter.canal.protocol.ClientIdentity)1 CanalClientException (com.alibaba.otter.canal.protocol.exception.CanalClientException)1 ByteString (com.google.protobuf.ByteString)1 SocketAddress (java.net.SocketAddress)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)1 ChannelHandlerContext (org.jboss.netty.channel.ChannelHandlerContext)1 IdleStateAwareChannelHandler (org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler)1 IdleStateEvent (org.jboss.netty.handler.timeout.IdleStateEvent)1