dubbo.apache.org/dubbo-go/v3@v3.1.1/cluster/cluster/mock.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package cluster
    19  
    20  import (
    21  	"context"
    22  )
    23  
    24  import (
    25  	"github.com/dubbogo/gost/log/logger"
    26  
    27  	perrors "github.com/pkg/errors"
    28  )
    29  
    30  import (
    31  	"dubbo.apache.org/dubbo-go/v3/cluster/directory"
    32  	"dubbo.apache.org/dubbo-go/v3/common"
    33  	"dubbo.apache.org/dubbo-go/v3/protocol"
    34  )
    35  
    36  var Count int
    37  
    38  type Rest struct {
    39  	Tried   int
    40  	Success bool
    41  }
    42  
    43  type mockCluster struct{}
    44  
    45  // NewMockCluster returns a mock cluster instance.
    46  //
    47  // Mock cluster is usually used for service degradation, such as an authentication service.
    48  // When the service provider is completely hung up, the client does not throw an exception,
    49  // return an authorization failure through the Mock data instead.
    50  func NewMockCluster() Cluster {
    51  	return &mockCluster{}
    52  }
    53  
    54  func (cluster *mockCluster) Join(directory directory.Directory) protocol.Invoker {
    55  	return BuildInterceptorChain(protocol.NewBaseInvoker(directory.GetURL()))
    56  }
    57  
    58  type MockInvoker struct {
    59  	url       *common.URL
    60  	available bool
    61  	destroyed bool
    62  
    63  	successCount int
    64  }
    65  
    66  func NewMockInvoker(url *common.URL, successCount int) *MockInvoker {
    67  	return &MockInvoker{
    68  		url:          url,
    69  		available:    true,
    70  		destroyed:    false,
    71  		successCount: successCount,
    72  	}
    73  }
    74  
    75  func (bi *MockInvoker) GetURL() *common.URL {
    76  	return bi.url
    77  }
    78  
    79  func (bi *MockInvoker) IsAvailable() bool {
    80  	return bi.available
    81  }
    82  
    83  func (bi *MockInvoker) IsDestroyed() bool {
    84  	return bi.destroyed
    85  }
    86  
    87  func (bi *MockInvoker) Invoke(c context.Context, invocation protocol.Invocation) protocol.Result {
    88  	Count++
    89  	var (
    90  		success bool
    91  		err     error
    92  	)
    93  	if Count >= bi.successCount {
    94  		success = true
    95  	} else {
    96  		err = perrors.New("error")
    97  	}
    98  	result := &protocol.RPCResult{Err: err, Rest: Rest{Tried: Count, Success: success}}
    99  
   100  	return result
   101  }
   102  
   103  func (bi *MockInvoker) Destroy() {
   104  	logger.Infof("Destroy invoker: %v", bi.GetURL().String())
   105  	bi.destroyed = true
   106  	bi.available = false
   107  }