vitess.io/vitess@v0.16.2/go/vt/binlog/grpcbinlogplayer/player.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package grpcbinlogplayer 18 19 import ( 20 "context" 21 22 "github.com/spf13/pflag" 23 "google.golang.org/grpc" 24 25 "vitess.io/vitess/go/netutil" 26 "vitess.io/vitess/go/vt/binlog/binlogplayer" 27 "vitess.io/vitess/go/vt/grpcclient" 28 binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" 29 binlogservicepb "vitess.io/vitess/go/vt/proto/binlogservice" 30 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 31 "vitess.io/vitess/go/vt/servenv" 32 ) 33 34 var cert, key, ca, crl, name string 35 36 func init() { 37 servenv.OnParseFor("vtcombo", registerFlags) 38 servenv.OnParseFor("vttablet", registerFlags) 39 } 40 41 func registerFlags(fs *pflag.FlagSet) { 42 fs.StringVar(&cert, "binlog_player_grpc_cert", cert, "the cert to use to connect") 43 fs.StringVar(&key, "binlog_player_grpc_key", key, "the key to use to connect") 44 fs.StringVar(&ca, "binlog_player_grpc_ca", ca, "the server ca to use to validate servers when connecting") 45 fs.StringVar(&crl, "binlog_player_grpc_crl", crl, "the server crl to use to validate server certificates when connecting") 46 fs.StringVar(&name, "binlog_player_grpc_server_name", name, "the server name to use to validate server certificate") 47 } 48 49 // client implements a Client over go rpc 50 type client struct { 51 cc *grpc.ClientConn 52 c binlogservicepb.UpdateStreamClient 53 } 54 55 func (client *client) Dial(tablet *topodatapb.Tablet) error { 56 addr := netutil.JoinHostPort(tablet.Hostname, tablet.PortMap["grpc"]) 57 var err error 58 opt, err := grpcclient.SecureDialOption(cert, key, ca, crl, name) 59 if err != nil { 60 return err 61 } 62 client.cc, err = grpcclient.Dial(addr, grpcclient.FailFast(true), opt) 63 if err != nil { 64 return err 65 } 66 client.c = binlogservicepb.NewUpdateStreamClient(client.cc) 67 return nil 68 } 69 70 func (client *client) Close() { 71 client.cc.Close() 72 } 73 74 type serveStreamKeyRangeAdapter struct { 75 stream binlogservicepb.UpdateStream_StreamKeyRangeClient 76 } 77 78 func (s *serveStreamKeyRangeAdapter) Recv() (*binlogdatapb.BinlogTransaction, error) { 79 r, err := s.stream.Recv() 80 if err != nil { 81 return nil, err 82 } 83 return r.BinlogTransaction, nil 84 } 85 86 func (client *client) StreamKeyRange(ctx context.Context, position string, keyRange *topodatapb.KeyRange, charset *binlogdatapb.Charset) (binlogplayer.BinlogTransactionStream, error) { 87 query := &binlogdatapb.StreamKeyRangeRequest{ 88 Position: position, 89 KeyRange: keyRange, 90 Charset: charset, 91 } 92 stream, err := client.c.StreamKeyRange(ctx, query) 93 if err != nil { 94 return nil, err 95 } 96 return &serveStreamKeyRangeAdapter{stream}, nil 97 } 98 99 type serveStreamTablesAdapter struct { 100 stream binlogservicepb.UpdateStream_StreamTablesClient 101 } 102 103 func (s *serveStreamTablesAdapter) Recv() (*binlogdatapb.BinlogTransaction, error) { 104 r, err := s.stream.Recv() 105 if err != nil { 106 return nil, err 107 } 108 return r.BinlogTransaction, nil 109 } 110 111 func (client *client) StreamTables(ctx context.Context, position string, tables []string, charset *binlogdatapb.Charset) (binlogplayer.BinlogTransactionStream, error) { 112 query := &binlogdatapb.StreamTablesRequest{ 113 Position: position, 114 Tables: tables, 115 Charset: charset, 116 } 117 stream, err := client.c.StreamTables(ctx, query) 118 if err != nil { 119 return nil, err 120 } 121 return &serveStreamTablesAdapter{stream}, nil 122 } 123 124 // Registration as a factory 125 func init() { 126 binlogplayer.RegisterClientFactory("grpc", func() binlogplayer.Client { 127 return &client{} 128 }) 129 }