github.com/ewagmig/fabric@v2.1.1+incompatible/common/channelconfig/bundlesource.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package channelconfig
     8  
     9  import (
    10  	"sync/atomic"
    11  
    12  	"github.com/hyperledger/fabric/common/configtx"
    13  	"github.com/hyperledger/fabric/common/policies"
    14  	"github.com/hyperledger/fabric/msp"
    15  )
    16  
    17  // BundleSource stores a reference to the current configuration bundle
    18  // It also provides a method to update this bundle.  The assorted methods
    19  // largely pass through to the underlying bundle, but do so through an atomic pointer
    20  // so that gross go-routine reads are not vulnerable to out-of-order execution memory
    21  // type bugs.
    22  type BundleSource struct {
    23  	bundle    atomic.Value
    24  	callbacks []BundleActor
    25  }
    26  
    27  // BundleActor performs an operation based on the given bundle
    28  type BundleActor func(bundle *Bundle)
    29  
    30  // NewBundleSource creates a new BundleSource with an initial Bundle value
    31  // The callbacks will be invoked whenever the Update method is called for the
    32  // BundleSource.  Note, these callbacks are called immediately before this function
    33  // returns.
    34  func NewBundleSource(bundle *Bundle, callbacks ...BundleActor) *BundleSource {
    35  	bs := &BundleSource{
    36  		callbacks: callbacks,
    37  	}
    38  	bs.Update(bundle)
    39  	return bs
    40  }
    41  
    42  // Update sets a new bundle as the bundle source and calls any registered callbacks
    43  func (bs *BundleSource) Update(newBundle *Bundle) {
    44  	bs.bundle.Store(newBundle)
    45  	for _, callback := range bs.callbacks {
    46  		callback(newBundle)
    47  	}
    48  }
    49  
    50  // StableBundle returns a pointer to a stable Bundle.
    51  // It is stable because calls to its assorted methods will always return the same
    52  // result, as the underlying data structures are immutable.  For instance, calling
    53  // BundleSource.Orderer() and BundleSource.MSPManager() to get first the list of orderer
    54  // orgs, then querying the MSP for those org definitions could result in a bug because an
    55  // update might replace the underlying Bundle in between.  Therefore, for operations
    56  // which require consistency between the Bundle calls, the caller should first retrieve
    57  // a StableBundle, then operate on it.
    58  func (bs *BundleSource) StableBundle() *Bundle {
    59  	return bs.bundle.Load().(*Bundle)
    60  }
    61  
    62  // PolicyManager returns the policy manager constructed for this config
    63  func (bs *BundleSource) PolicyManager() policies.Manager {
    64  	return bs.StableBundle().PolicyManager()
    65  }
    66  
    67  // MSPManager returns the MSP manager constructed for this config
    68  func (bs *BundleSource) MSPManager() msp.MSPManager {
    69  	return bs.StableBundle().MSPManager()
    70  }
    71  
    72  // ChannelConfig returns the config.Channel for the chain
    73  func (bs *BundleSource) ChannelConfig() Channel {
    74  	return bs.StableBundle().ChannelConfig()
    75  }
    76  
    77  // OrdererConfig returns the config.Orderer for the channel
    78  // and whether the Orderer config exists
    79  func (bs *BundleSource) OrdererConfig() (Orderer, bool) {
    80  	return bs.StableBundle().OrdererConfig()
    81  }
    82  
    83  // ConsortiumsConfig() returns the config.Consortiums for the channel
    84  // and whether the consortiums config exists
    85  func (bs *BundleSource) ConsortiumsConfig() (Consortiums, bool) {
    86  	return bs.StableBundle().ConsortiumsConfig()
    87  }
    88  
    89  // ApplicationConfig returns the Application config for the channel
    90  // and whether the Application config exists
    91  func (bs *BundleSource) ApplicationConfig() (Application, bool) {
    92  	return bs.StableBundle().ApplicationConfig()
    93  }
    94  
    95  // ConfigtxValidator returns the configtx.Validator for the channel
    96  func (bs *BundleSource) ConfigtxValidator() configtx.Validator {
    97  	return bs.StableBundle().ConfigtxValidator()
    98  }
    99  
   100  // ValidateNew passes through to the current bundle
   101  func (bs *BundleSource) ValidateNew(resources Resources) error {
   102  	return bs.StableBundle().ValidateNew(resources)
   103  }