diff --git a/scripts/third_party_pins/fabric/apply_fabric_external_utils.sh b/scripts/third_party_pins/fabric/apply_fabric_external_utils.sh new file mode 100755 index 0000000000..fbb56bab73 --- /dev/null +++ b/scripts/third_party_pins/fabric/apply_fabric_external_utils.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright SecureKey Technologies Inc. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This script pins the BCCSP package family from Hyperledger Fabric into the SDK +# These files are checked into internal paths. +# Note: This script must be adjusted as upstream makes adjustments + +IMPORT_SUBSTS=($IMPORT_SUBSTS) + +declare -a PKGS=( + "common/flogging" +) + +declare -a FILES=( + "common/flogging/logging.go" +) + +echo 'Removing current upstream project from working directory ...' +rm -Rf "${INTERNAL_PATH}/common/flogging" +mkdir -p "${INTERNAL_PATH}/common/flogging" + +# Create directory structure for packages +for i in "${PKGS[@]}" +do + mkdir -p $INTERNAL_PATH/${i} +done + +# Apply global import patching +echo "Patching import paths on upstream project ..." +for i in "${FILES[@]}" +do + for subst in "${IMPORT_SUBSTS[@]}" + do + sed -i '' -e $subst $TMP_PROJECT_PATH/${i} + done + goimports -w $TMP_PROJECT_PATH/${i} +done + +# Copy patched project into internal paths +echo "Copying patched upstream project into working directory ..." +for i in "${FILES[@]}" +do + TARGET_PATH=`dirname $INTERNAL_PATH/${i}` + cp $TMP_PROJECT_PATH/${i} $TARGET_PATH +done diff --git a/scripts/third_party_pins/fabric/apply_upstream.sh b/scripts/third_party_pins/fabric/apply_upstream.sh index 745f8f48fe..c181d52bf9 100755 --- a/scripts/third_party_pins/fabric/apply_upstream.sh +++ b/scripts/third_party_pins/fabric/apply_upstream.sh @@ -14,8 +14,9 @@ UPSTREAM_BRANCH="master" SCRIPTS_PATH="scripts/third_party_pins/fabric" PATCHES_PATH="${SCRIPTS_PATH}/patches" -THIRDPARTY_FABRIC_API_PATH='api/third_party/fabric' -THIRDPARTY_FABRIC_BCCSP_PKG_PATH='pkg/third_party' +THIRDPARTY_FABRIC_PATH='third_party/github.com/hyperledger/fabric' +THIRDPARTY_FABRIC_API_PATH=$THIRDPARTY_FABRIC_PATH +THIRDPARTY_FABRIC_BCCSP_PKG_PATH=$THIRDPARTY_FABRIC_PATH THIRDPARTY_INTERNAL_FABRIC_PATH='internal/github.com/hyperledger/fabric' #### @@ -43,24 +44,37 @@ cd $CWD # fabric client utils echo "Pinning and patching fabric client utils..." declare -a CLIENT_UTILS_IMPORT_SUBSTS=( - 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g' - 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g' + 's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g' + 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g' + 's/\"github.com\/hyperledger\/fabric\/protos\/utils/\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\/protos\/utils/g' + 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g' 's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g' ) eval "INTERNAL_PATH=$THIRDPARTY_INTERNAL_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${CLIENT_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_client_utils.sh" +# external utils +echo "Pinning and patching fabric external utils ..." +declare -a EXTERNAL_UTILS_IMPORT_SUBSTS=( + 's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g' +) +eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${EXTERNAL_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_external_utils.sh" + + # bccsp echo "Pinning and patching bccsp ..." declare -a BCCSP_IMPORT_SUBSTS=( - 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g' + 's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g' + 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g' + 's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g' ) eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_BCCSP_PKG_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${BCCSP_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_bccsp.sh" # protos echo "Pinning and patching protos ..." declare -a PROTOS_IMPORT_SUBSTS=( - 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g' - 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g' + 's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g' + 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g' + 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g' 's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g' ) eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_API_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTOS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_protos.sh" @@ -68,11 +82,12 @@ eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_API_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PA # proto utils echo "Pinning and patching proto utils..." declare -a PROTO_UTILS_IMPORT_SUBSTS=( - 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/pkg\/third_party\/bccsp/g' - 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/api\/third_party\/fabric\/protos\//g' + 's/\"github.com\/hyperledger\/fabric\/common\/flogging/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/common\/flogging/g' + 's/\"github.com\/hyperledger\/fabric\/bccsp/\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/bccsp/g' + 's/\"github.com\/hyperledger\/fabric\/protos\//\"github.com\/hyperledger\/fabric-sdk-go\/third_party\/github.com\/hyperledger\/fabric\/protos\//g' 's/\"github.com\/hyperledger\/fabric\//\"github.com\/hyperledger\/fabric-sdk-go\/internal\/github.com\/hyperledger\/fabric\//g' ) -eval "INTERNAL_PATH=$THIRDPARTY_FABRIC_API_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTO_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_proto_utils.sh" +eval "INTERNAL_PATH=$THIRDPARTY_INTERNAL_FABRIC_PATH TMP_PROJECT_PATH=$TMP_PROJECT_PATH IMPORT_SUBSTS=\"${PROTO_UTILS_IMPORT_SUBSTS[*]}\" $SCRIPTS_PATH/apply_fabric_proto_utils.sh" # Cleanup temporary files from patch application echo "Removing temporary files ..." diff --git a/scripts/third_party_pins/fabric/patches/0002-Update-package-flogging-for-vendoring.patch b/scripts/third_party_pins/fabric/patches/0002-Update-package-flogging-for-vendoring.patch new file mode 100644 index 0000000000..1ede5b5372 --- /dev/null +++ b/scripts/third_party_pins/fabric/patches/0002-Update-package-flogging-for-vendoring.patch @@ -0,0 +1,28 @@ +From 81c8693fad42fa98ab38c8946fbb79d355e08392 Mon Sep 17 00:00:00 2001 +From: Troy Ronda +Date: Tue, 19 Sep 2017 11:29:58 -0400 +Subject: [PATCH] Update package flogging for vendoring + +Copyright SecureKey Technologies Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 + +Signed-off-by: Troy Ronda +--- + common/flogging/logging.go | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/common/flogging/logging.go b/common/flogging/logging.go +index 841aed7a..f4f0b8d7 100644 +--- a/common/flogging/logging.go ++++ b/common/flogging/logging.go +@@ -47,7 +47,6 @@ var ( + func init() { + logger = logging.MustGetLogger(pkgLogID) + Reset() +- initgrpclogger() + } + + // Reset sets to logging to the defaults defined in this package. +-- +2.14.1 + diff --git a/test/scripts/unit.sh b/test/scripts/unit.sh index afaaa606e6..be274239bd 100755 --- a/test/scripts/unit.sh +++ b/test/scripts/unit.sh @@ -16,7 +16,7 @@ REPO="github.com/hyperledger/fabric-sdk-go" PKGS=`go list $REPO... 2> /dev/null | \ grep -v ^$REPO/api/ | \ grep -v ^$REPO/pkg/fabric-ca-client/mocks | grep -v ^$REPO/pkg/fabric-client/mocks | \ - grep -v ^$REPO/internal/github.com/ | grep -v ^$REPO/pkg/third_party/ | \ + grep -v ^$REPO/internal/github.com/ | grep -v ^$REPO/third_party/ | \ grep -v ^$REPO/vendor/ | grep -v ^$REPO/test/` echo "Running unit tests..." diff --git a/third_party/github.com/hyperledger/fabric/common/flogging/logging.go b/third_party/github.com/hyperledger/fabric/common/flogging/logging.go new file mode 100644 index 0000000000..f4f0b8d751 --- /dev/null +++ b/third_party/github.com/hyperledger/fabric/common/flogging/logging.go @@ -0,0 +1,232 @@ +/* +Copyright IBM Corp. 2017 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flogging + +import ( + "io" + "os" + "regexp" + "strings" + "sync" + + "github.com/op/go-logging" +) + +const ( + pkgLogID = "flogging" + defaultFormat = "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}" + defaultLevel = logging.INFO +) + +var ( + logger *logging.Logger + + defaultOutput *os.File + + modules map[string]string // Holds the map of all modules and their respective log level + peerStartModules map[string]string + + lock sync.RWMutex + once sync.Once +) + +func init() { + logger = logging.MustGetLogger(pkgLogID) + Reset() +} + +// Reset sets to logging to the defaults defined in this package. +func Reset() { + modules = make(map[string]string) + lock = sync.RWMutex{} + + defaultOutput = os.Stderr + InitBackend(SetFormat(defaultFormat), defaultOutput) + InitFromSpec("") +} + +// SetFormat sets the logging format. +func SetFormat(formatSpec string) logging.Formatter { + if formatSpec == "" { + formatSpec = defaultFormat + } + return logging.MustStringFormatter(formatSpec) +} + +// InitBackend sets up the logging backend based on +// the provided logging formatter and I/O writer. +func InitBackend(formatter logging.Formatter, output io.Writer) { + backend := logging.NewLogBackend(output, "", 0) + backendFormatter := logging.NewBackendFormatter(backend, formatter) + logging.SetBackend(backendFormatter).SetLevel(defaultLevel, "") +} + +// DefaultLevel returns the fallback value for loggers to use if parsing fails. +func DefaultLevel() string { + return defaultLevel.String() +} + +// GetModuleLevel gets the current logging level for the specified module. +func GetModuleLevel(module string) string { + // logging.GetLevel() returns the logging level for the module, if defined. + // Otherwise, it returns the default logging level, as set by + // `flogging/logging.go`. + level := logging.GetLevel(module).String() + return level +} + +// SetModuleLevel sets the logging level for the modules that match the supplied +// regular expression. Can be used to dynamically change the log level for the +// module. +func SetModuleLevel(moduleRegExp string, level string) (string, error) { + return setModuleLevel(moduleRegExp, level, true, false) +} + +func setModuleLevel(moduleRegExp string, level string, isRegExp bool, revert bool) (string, error) { + var re *regexp.Regexp + logLevel, err := logging.LogLevel(level) + if err != nil { + logger.Warningf("Invalid logging level '%s' - ignored", level) + } else { + if !isRegExp || revert { + logging.SetLevel(logLevel, moduleRegExp) + logger.Debugf("Module '%s' logger enabled for log level '%s'", moduleRegExp, level) + } else { + re, err = regexp.Compile(moduleRegExp) + if err != nil { + logger.Warningf("Invalid regular expression: %s", moduleRegExp) + return "", err + } + lock.Lock() + defer lock.Unlock() + for module := range modules { + if re.MatchString(module) { + logging.SetLevel(logging.Level(logLevel), module) + modules[module] = logLevel.String() + logger.Debugf("Module '%s' logger enabled for log level '%s'", module, logLevel) + } + } + } + } + return logLevel.String(), err +} + +// MustGetLogger is used in place of `logging.MustGetLogger` to allow us to +// store a map of all modules and submodules that have loggers in the system. +func MustGetLogger(module string) *logging.Logger { + l := logging.MustGetLogger(module) + lock.Lock() + defer lock.Unlock() + modules[module] = GetModuleLevel(module) + return l +} + +// InitFromSpec initializes the logging based on the supplied spec. It is +// exposed externally so that consumers of the flogging package may parse their +// own logging specification. The logging specification has the following form: +// [[,...]=][:[[,...]=]...] +func InitFromSpec(spec string) string { + levelAll := defaultLevel + var err error + + if spec != "" { + fields := strings.Split(spec, ":") + for _, field := range fields { + split := strings.Split(field, "=") + switch len(split) { + case 1: + if levelAll, err = logging.LogLevel(field); err != nil { + logger.Warningf("Logging level '%s' not recognized, defaulting to '%s': %s", field, defaultLevel, err) + levelAll = defaultLevel // need to reset cause original value was overwritten + } + case 2: + // [,...]= + levelSingle, err := logging.LogLevel(split[1]) + if err != nil { + logger.Warningf("Invalid logging level in '%s' ignored", field) + continue + } + + if split[0] == "" { + logger.Warningf("Invalid logging override specification '%s' ignored - no module specified", field) + } else { + modules := strings.Split(split[0], ",") + for _, module := range modules { + logger.Debugf("Setting logging level for module '%s' to '%s'", module, levelSingle) + logging.SetLevel(levelSingle, module) + } + } + default: + logger.Warningf("Invalid logging override '%s' ignored - missing ':'?", field) + } + } + } + + logging.SetLevel(levelAll, "") // set the logging level for all modules + + // iterate through modules to reload their level in the modules map based on + // the new default level + for k := range modules { + MustGetLogger(k) + } + // register flogging logger in the modules map + MustGetLogger(pkgLogID) + + return levelAll.String() +} + +// SetPeerStartupModulesMap saves the modules and their log levels. +// this function should only be called at the end of peer startup. +func SetPeerStartupModulesMap() { + lock.Lock() + defer lock.Unlock() + + once.Do(func() { + peerStartModules = make(map[string]string) + for k, v := range modules { + peerStartModules[k] = v + } + }) +} + +// GetPeerStartupLevel returns the peer startup level for the specified module. +// It will return an empty string if the input parameter is empty or the module +// is not found +func GetPeerStartupLevel(module string) string { + if module != "" { + if level, ok := peerStartModules[module]; ok { + return level + } + } + + return "" +} + +// RevertToPeerStartupLevels reverts the log levels for all modules to the level +// defined at the end of peer startup. +func RevertToPeerStartupLevels() error { + lock.RLock() + defer lock.RUnlock() + for key := range peerStartModules { + _, err := setModuleLevel(key, peerStartModules[key], false, true) + if err != nil { + return err + } + } + logger.Info("Log levels reverted to the levels defined at the end of peer startup") + return nil +}