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  }