github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/peer/common/common.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  package common
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  
    23  	"github.com/hyperledger/fabric/bccsp/factory"
    24  	"github.com/hyperledger/fabric/common/configtx"
    25  	configtxapi "github.com/hyperledger/fabric/common/configtx/api"
    26  	"github.com/hyperledger/fabric/common/errors"
    27  	"github.com/hyperledger/fabric/common/flogging"
    28  	"github.com/hyperledger/fabric/common/viperutil"
    29  	"github.com/hyperledger/fabric/core/config"
    30  	"github.com/hyperledger/fabric/core/peer"
    31  	"github.com/hyperledger/fabric/core/scc/cscc"
    32  	"github.com/hyperledger/fabric/msp"
    33  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    34  	pcommon "github.com/hyperledger/fabric/protos/common"
    35  	pb "github.com/hyperledger/fabric/protos/peer"
    36  	putils "github.com/hyperledger/fabric/protos/utils"
    37  	"github.com/op/go-logging"
    38  	"github.com/spf13/viper"
    39  	"golang.org/x/net/context"
    40  )
    41  
    42  // UndefinedParamValue defines what undefined parameters in the command line will initialise to
    43  const UndefinedParamValue = ""
    44  
    45  var (
    46  	// These function variables (xyzFnc) can be used to invoke corresponding xyz function
    47  	// this will allow the invoking packages to mock these functions in their unit test cases
    48  
    49  	// GetEndorserClientFnc is a function that returns a new endorser client connection,
    50  	// by default it is set to GetEndorserClient function
    51  	GetEndorserClientFnc func() (pb.EndorserClient, error)
    52  
    53  	// GetDefaultSignerFnc is a function that returns a default Signer(Default/PERR)
    54  	// by default it is set to GetDefaultSigner function
    55  	GetDefaultSignerFnc func() (msp.SigningIdentity, error)
    56  
    57  	// GetBroadcastClientFnc returns an instance of the BroadcastClient interface
    58  	// by default it is set to GetBroadcastClient function
    59  	GetBroadcastClientFnc func(orderingEndpoint string, tlsEnabled bool,
    60  		caFile string) (BroadcastClient, error)
    61  
    62  	// GetOrdererEndpointOfChainFnc returns orderer endpoints of given chain
    63  	// by default it is set to GetOrdererEndpointOfChain function
    64  	GetOrdererEndpointOfChainFnc func(chainID string, signer msp.SigningIdentity,
    65  		endorserClient pb.EndorserClient) ([]string, error)
    66  )
    67  
    68  func init() {
    69  	GetEndorserClientFnc = GetEndorserClient
    70  	GetDefaultSignerFnc = GetDefaultSigner
    71  	GetBroadcastClientFnc = GetBroadcastClient
    72  	GetOrdererEndpointOfChainFnc = GetOrdererEndpointOfChain
    73  }
    74  
    75  //InitConfig initializes viper config
    76  func InitConfig(cmdRoot string) error {
    77  	config.InitViper(nil, cmdRoot)
    78  
    79  	err := viper.ReadInConfig() // Find and read the config file
    80  	if err != nil {             // Handle errors reading the config file
    81  		return fmt.Errorf("Error when reading %s config file: %s", cmdRoot, err)
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  //InitCrypto initializes crypto for this peer
    88  func InitCrypto(mspMgrConfigDir string, localMSPID string) error {
    89  	var err error
    90  	// Check whenever msp folder exists
    91  	_, err = os.Stat(mspMgrConfigDir)
    92  	if os.IsNotExist(err) {
    93  		// No need to try to load MSP from folder which is not available
    94  		return fmt.Errorf("cannot init crypto, missing %s folder", mspMgrConfigDir)
    95  	}
    96  
    97  	// Init the BCCSP
    98  	var bccspConfig *factory.FactoryOpts
    99  	err = viperutil.EnhancedExactUnmarshalKey("peer.BCCSP", &bccspConfig)
   100  	if err != nil {
   101  		return fmt.Errorf("could not parse YAML config [%s]", err)
   102  	}
   103  
   104  	err = mspmgmt.LoadLocalMsp(mspMgrConfigDir, bccspConfig, localMSPID)
   105  	if err != nil {
   106  		return fmt.Errorf("error when setting up MSP from directory %s: err %s", mspMgrConfigDir, err)
   107  	}
   108  
   109  	return nil
   110  }
   111  
   112  // GetEndorserClient returns a new endorser client connection for this peer
   113  func GetEndorserClient() (pb.EndorserClient, error) {
   114  	clientConn, err := peer.NewPeerClientConnection()
   115  	if err != nil {
   116  		err = errors.ErrorWithCallstack("PER", "404", "Error trying to connect to local peer").WrapError(err)
   117  		return nil, err
   118  	}
   119  	endorserClient := pb.NewEndorserClient(clientConn)
   120  	return endorserClient, nil
   121  }
   122  
   123  // GetAdminClient returns a new admin client connection for this peer
   124  func GetAdminClient() (pb.AdminClient, error) {
   125  	clientConn, err := peer.NewPeerClientConnection()
   126  	if err != nil {
   127  		err = errors.ErrorWithCallstack("PER", "404", "Error trying to connect to local peer").WrapError(err)
   128  		return nil, err
   129  	}
   130  	adminClient := pb.NewAdminClient(clientConn)
   131  	return adminClient, nil
   132  }
   133  
   134  // GetDefaultSigner return a default Signer(Default/PERR) for cli
   135  func GetDefaultSigner() (msp.SigningIdentity, error) {
   136  	signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   137  	if err != nil {
   138  		return nil, fmt.Errorf("Error obtaining the default signing identity, err %s", err)
   139  	}
   140  
   141  	return signer, err
   142  }
   143  
   144  // GetOrdererEndpointOfChain returns orderer endpoints of given chain
   145  func GetOrdererEndpointOfChain(chainID string, signer msp.SigningIdentity, endorserClient pb.EndorserClient) ([]string, error) {
   146  
   147  	// query cscc for chain config block
   148  	invocation := &pb.ChaincodeInvocationSpec{
   149  		ChaincodeSpec: &pb.ChaincodeSpec{
   150  			Type:        pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]),
   151  			ChaincodeId: &pb.ChaincodeID{Name: "cscc"},
   152  			Input:       &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.GetConfigBlock), []byte(chainID)}},
   153  		},
   154  	}
   155  
   156  	creator, err := signer.Serialize()
   157  	if err != nil {
   158  		return nil, fmt.Errorf("Error serializing identity for %s: %s", signer.GetIdentifier(), err)
   159  	}
   160  
   161  	prop, _, err := putils.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator)
   162  	if err != nil {
   163  		return nil, fmt.Errorf("Error creating GetConfigBlock proposal: %s", err)
   164  	}
   165  
   166  	signedProp, err := putils.GetSignedProposal(prop, signer)
   167  	if err != nil {
   168  		return nil, fmt.Errorf("Error creating signed GetConfigBlock proposal: %s", err)
   169  	}
   170  
   171  	proposalResp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   172  	if err != nil {
   173  		return nil, fmt.Errorf("Error endorsing GetConfigBlock: %s", err)
   174  	}
   175  
   176  	if proposalResp == nil {
   177  		return nil, fmt.Errorf("Error nil proposal response: %s", err)
   178  	}
   179  
   180  	if proposalResp.Response.Status != 0 && proposalResp.Response.Status != 200 {
   181  		return nil, fmt.Errorf("Error bad proposal response %d", proposalResp.Response.Status)
   182  	}
   183  
   184  	// parse config block
   185  	block, err := putils.GetBlockFromBlockBytes(proposalResp.Response.Payload)
   186  	if err != nil {
   187  		return nil, fmt.Errorf("Error unmarshaling config block: %s", err)
   188  	}
   189  
   190  	envelopeConfig, err := putils.ExtractEnvelope(block, 0)
   191  	if err != nil {
   192  		return nil, fmt.Errorf("Error extracting config block envelope: %s", err)
   193  	}
   194  	configtxInitializer := configtx.NewInitializer()
   195  	configtxManager, err := configtx.NewManagerImpl(
   196  		envelopeConfig,
   197  		configtxInitializer,
   198  		[]func(cm configtxapi.Manager){},
   199  	)
   200  	if err != nil {
   201  		return nil, fmt.Errorf("Error loadding config block: %s", err)
   202  	}
   203  
   204  	return configtxManager.ChannelConfig().OrdererAddresses(), nil
   205  }
   206  
   207  // SetLogLevelFromViper sets the log level for 'module' logger to the value in
   208  // core.yaml
   209  func SetLogLevelFromViper(module string) error {
   210  	var err error
   211  	if module == "" {
   212  		return fmt.Errorf("log level not set, no module name provided")
   213  	}
   214  	logLevelFromViper := viper.GetString("logging." + module)
   215  	err = CheckLogLevel(logLevelFromViper)
   216  	if err != nil {
   217  		return err
   218  	}
   219  	_, err = flogging.SetModuleLevel(module, logLevelFromViper)
   220  	return err
   221  }
   222  
   223  // CheckLogLevel checks that a given log level string is valid
   224  func CheckLogLevel(level string) error {
   225  	_, err := logging.LogLevel(level)
   226  	if err != nil {
   227  		err = errors.ErrorWithCallstack("LOG", "400", "Invalid log level provided - %s", level)
   228  	}
   229  	return err
   230  }