github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/peer/config.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     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  // The 'viper' package for configuration handling is very flexible, but has
    18  // been found to have extremely poor performance when configuration values are
    19  // accessed repeatedly. The function CacheConfiguration() defined here caches
    20  // all configuration values that are accessed frequently.  These parameters
    21  // are now presented as function calls that access local configuration
    22  // variables.  This seems to be the most robust way to represent these
    23  // parameters in the face of the numerous ways that configuration files are
    24  // loaded and used (e.g, normal usage vs. test cases).
    25  
    26  // The CacheConfiguration() function is allowed to be called globally to
    27  // ensure that the correct values are always cached; See for example how
    28  // certain parameters are forced in 'ChaincodeDevMode' in main.go.
    29  
    30  package peer
    31  
    32  import (
    33  	"fmt"
    34  	"io/ioutil"
    35  	"net"
    36  
    37  	"github.com/spf13/viper"
    38  
    39  	"github.com/hyperledger/fabric/core/comm"
    40  	"github.com/hyperledger/fabric/core/config"
    41  	pb "github.com/hyperledger/fabric/protos/peer"
    42  )
    43  
    44  // Is the configuration cached?
    45  var configurationCached = false
    46  
    47  // Cached values and error values of the computed constants getLocalAddress(),
    48  // getValidatorStreamAddress(), and getPeerEndpoint()
    49  var localAddress string
    50  var localAddressError error
    51  var peerEndpoint *pb.PeerEndpoint
    52  var peerEndpointError error
    53  
    54  // Cached values of commonly used configuration constants.
    55  var syncStateSnapshotChannelSize int
    56  var syncStateDeltasChannelSize int
    57  var syncBlocksChannelSize int
    58  
    59  // Note: There is some kind of circular import issue that prevents us from
    60  // importing the "core" package into the "peer" package. The
    61  // 'peer.SecurityEnabled' bit is a duplicate of the 'core.SecurityEnabled'
    62  // bit.
    63  var securityEnabled bool
    64  
    65  // CacheConfiguration computes and caches commonly-used constants and
    66  // computed constants as package variables. Routines which were previously
    67  // global have been embedded here to preserve the original abstraction.
    68  func CacheConfiguration() (err error) {
    69  
    70  	// getLocalAddress returns the address:port the local peer is operating on.  Affected by env:peer.addressAutoDetect
    71  	getLocalAddress := func() (peerAddress string, err error) {
    72  		if viper.GetBool("peer.addressAutoDetect") {
    73  			// Need to get the port from the peer.address setting, and append to the determined host IP
    74  			_, port, err := net.SplitHostPort(viper.GetString("peer.address"))
    75  			if err != nil {
    76  				err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
    77  				return "", err
    78  			}
    79  			peerAddress = net.JoinHostPort(GetLocalIP(), port)
    80  			peerLogger.Infof("Auto detected peer address: %s", peerAddress)
    81  		} else {
    82  			peerAddress = viper.GetString("peer.address")
    83  		}
    84  		return
    85  	}
    86  
    87  	// getPeerEndpoint returns the PeerEndpoint for this Peer instance.  Affected by env:peer.addressAutoDetect
    88  	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
    89  		var peerAddress string
    90  		peerAddress, err := getLocalAddress()
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress}, nil
    95  	}
    96  
    97  	localAddress, localAddressError = getLocalAddress()
    98  	peerEndpoint, peerEndpointError = getPeerEndpoint()
    99  
   100  	syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize")
   101  	syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize")
   102  	syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize")
   103  
   104  	securityEnabled = true
   105  
   106  	configurationCached = true
   107  
   108  	if localAddressError != nil {
   109  		return localAddressError
   110  	} else if peerEndpointError != nil {
   111  		return peerEndpointError
   112  	}
   113  	return
   114  }
   115  
   116  // cacheConfiguration logs an error if error checks have failed.
   117  func cacheConfiguration() {
   118  	if err := CacheConfiguration(); err != nil {
   119  		peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
   120  	}
   121  }
   122  
   123  //Functional forms
   124  
   125  // GetLocalAddress returns the peer.address property
   126  func GetLocalAddress() (string, error) {
   127  	if !configurationCached {
   128  		cacheConfiguration()
   129  	}
   130  	return localAddress, localAddressError
   131  }
   132  
   133  // GetPeerEndpoint returns peerEndpoint from cached configuration
   134  func GetPeerEndpoint() (*pb.PeerEndpoint, error) {
   135  	if !configurationCached {
   136  		cacheConfiguration()
   137  	}
   138  	return peerEndpoint, peerEndpointError
   139  }
   140  
   141  // SyncStateSnapshotChannelSize returns the peer.sync.state.snapshot.channelSize property
   142  func SyncStateSnapshotChannelSize() int {
   143  	if !configurationCached {
   144  		cacheConfiguration()
   145  	}
   146  	return syncStateSnapshotChannelSize
   147  }
   148  
   149  // SyncStateDeltasChannelSize returns the peer.sync.state.deltas.channelSize property
   150  func SyncStateDeltasChannelSize() int {
   151  	if !configurationCached {
   152  		cacheConfiguration()
   153  	}
   154  	return syncStateDeltasChannelSize
   155  }
   156  
   157  // SyncBlocksChannelSize returns the peer.sync.blocks.channelSize property
   158  func SyncBlocksChannelSize() int {
   159  	if !configurationCached {
   160  		cacheConfiguration()
   161  	}
   162  	return syncBlocksChannelSize
   163  }
   164  
   165  // SecurityEnabled returns the securityEnabled property from cached configuration
   166  func SecurityEnabled() bool {
   167  	if !configurationCached {
   168  		cacheConfiguration()
   169  	}
   170  	return securityEnabled
   171  }
   172  
   173  // GetSecureConfig returns the secure server configuration for the peer
   174  func GetSecureConfig() (comm.SecureServerConfig, error) {
   175  	secureConfig := comm.SecureServerConfig{
   176  		UseTLS: viper.GetBool("peer.tls.enabled"),
   177  	}
   178  	if secureConfig.UseTLS {
   179  		// get the certs from the file system
   180  		serverKey, err := ioutil.ReadFile(config.GetPath("peer.tls.key.file"))
   181  		serverCert, err := ioutil.ReadFile(config.GetPath("peer.tls.cert.file"))
   182  		// must have both key and cert file
   183  		if err != nil {
   184  			return secureConfig, fmt.Errorf("Error loading TLS key and/or certificate (%s)", err)
   185  		}
   186  		secureConfig.ServerCertificate = serverCert
   187  		secureConfig.ServerKey = serverKey
   188  		// check for root cert
   189  		if config.GetPath("peer.tls.rootcert.file") != "" {
   190  			rootCert, err := ioutil.ReadFile(config.GetPath("peer.tls.rootcert.file"))
   191  			if err != nil {
   192  				return secureConfig, fmt.Errorf("Error loading TLS root certificate (%s)", err)
   193  			}
   194  			secureConfig.ServerRootCAs = [][]byte{rootCert}
   195  		}
   196  		return secureConfig, nil
   197  	}
   198  	return secureConfig, nil
   199  }