github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/cluster/service.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package cluster
     8  
     9  import (
    10  	"context"
    11  	"io"
    12  	"time"
    13  
    14  	"github.com/hechain20/hechain/common/flogging"
    15  	"github.com/hechain20/hechain/common/util"
    16  	"github.com/hyperledger/fabric-protos-go/orderer"
    17  	"go.uber.org/zap"
    18  	"google.golang.org/grpc"
    19  )
    20  
    21  //go:generate mockery -dir . -name Dispatcher -case underscore -output ./mocks/
    22  
    23  // Dispatcher dispatches requests
    24  type Dispatcher interface {
    25  	DispatchSubmit(ctx context.Context, request *orderer.SubmitRequest) error
    26  	DispatchConsensus(ctx context.Context, request *orderer.ConsensusRequest) error
    27  }
    28  
    29  //go:generate mockery -dir . -name StepStream -case underscore -output ./mocks/
    30  
    31  // StepStream defines the gRPC stream for sending
    32  // transactions, and receiving corresponding responses
    33  type StepStream interface {
    34  	Send(response *orderer.StepResponse) error
    35  	Recv() (*orderer.StepRequest, error)
    36  	grpc.ServerStream
    37  }
    38  
    39  // Service defines the raft Service
    40  type Service struct {
    41  	StreamCountReporter              *StreamCountReporter
    42  	Dispatcher                       Dispatcher
    43  	Logger                           *flogging.FabricLogger
    44  	StepLogger                       *flogging.FabricLogger
    45  	MinimumExpirationWarningInterval time.Duration
    46  	CertExpWarningThreshold          time.Duration
    47  }
    48  
    49  // Step passes an implementation-specific message to another cluster member.
    50  func (s *Service) Step(stream orderer.Cluster_StepServer) error {
    51  	s.StreamCountReporter.Increment()
    52  	defer s.StreamCountReporter.Decrement()
    53  
    54  	addr := util.ExtractRemoteAddress(stream.Context())
    55  	commonName := commonNameFromContext(stream.Context())
    56  	exp := s.initializeExpirationCheck(stream, addr, commonName)
    57  	s.Logger.Debugf("Connection from %s(%s)", commonName, addr)
    58  	defer s.Logger.Debugf("Closing connection from %s(%s)", commonName, addr)
    59  	for {
    60  		err := s.handleMessage(stream, addr, exp)
    61  		if err == io.EOF {
    62  			s.Logger.Debugf("%s(%s) disconnected", commonName, addr)
    63  			return nil
    64  		}
    65  		if err != nil {
    66  			return err
    67  		}
    68  		// Else, no error occurred, so we continue to the next iteration
    69  	}
    70  }
    71  
    72  func (s *Service) handleMessage(stream StepStream, addr string, exp *certificateExpirationCheck) error {
    73  	request, err := stream.Recv()
    74  	if err == io.EOF {
    75  		return err
    76  	}
    77  	if err != nil {
    78  		s.Logger.Warningf("Stream read from %s failed: %v", addr, err)
    79  		return err
    80  	}
    81  
    82  	exp.checkExpiration(time.Now(), extractChannel(request))
    83  
    84  	if s.StepLogger.IsEnabledFor(zap.DebugLevel) {
    85  		nodeName := commonNameFromContext(stream.Context())
    86  		s.StepLogger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
    87  	}
    88  
    89  	if submitReq := request.GetSubmitRequest(); submitReq != nil {
    90  		nodeName := commonNameFromContext(stream.Context())
    91  		s.Logger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
    92  		return s.handleSubmit(submitReq, stream, addr)
    93  	}
    94  
    95  	// Else, it's a consensus message.
    96  	return s.Dispatcher.DispatchConsensus(stream.Context(), request.GetConsensusRequest())
    97  }
    98  
    99  func (s *Service) handleSubmit(request *orderer.SubmitRequest, stream StepStream, addr string) error {
   100  	err := s.Dispatcher.DispatchSubmit(stream.Context(), request)
   101  	if err != nil {
   102  		s.Logger.Warningf("Handling of Submit() from %s failed: %v", addr, err)
   103  		return err
   104  	}
   105  	return err
   106  }
   107  
   108  func (s *Service) initializeExpirationCheck(stream orderer.Cluster_StepServer, endpoint, nodeName string) *certificateExpirationCheck {
   109  	return &certificateExpirationCheck{
   110  		minimumExpirationWarningInterval: s.MinimumExpirationWarningInterval,
   111  		expirationWarningThreshold:       s.CertExpWarningThreshold,
   112  		expiresAt:                        expiresAt(stream),
   113  		endpoint:                         endpoint,
   114  		nodeName:                         nodeName,
   115  		alert: func(template string, args ...interface{}) {
   116  			s.Logger.Warningf(template, args...)
   117  		},
   118  	}
   119  }
   120  
   121  func expiresAt(stream orderer.Cluster_StepServer) time.Time {
   122  	cert := util.ExtractCertificateFromContext(stream.Context())
   123  	if cert == nil {
   124  		return time.Time{}
   125  	}
   126  	return cert.NotAfter
   127  }
   128  
   129  func extractChannel(msg *orderer.StepRequest) string {
   130  	if consReq := msg.GetConsensusRequest(); consReq != nil {
   131  		return consReq.Channel
   132  	}
   133  
   134  	if submitReq := msg.GetSubmitRequest(); submitReq != nil {
   135  		return submitReq.Channel
   136  	}
   137  
   138  	return ""
   139  }