Skip to content

Commit

Permalink
remove duplicated code in peer/chaincode
Browse files Browse the repository at this point in the history
The chaincode specification code creation was repeated line by line
for the deploy and invoke/query commands of the peer.
The code is now placed in a function called "getChaincodeSpecification".

Change-Id: Iae60d8c3640562049a1fad140dd06f32a8af8bfb
Signed-off-by: Ivan Puddu <puddui@student.ethz.ch>
  • Loading branch information
dn0sar committed Aug 16, 2016
1 parent 2443643 commit 8ce0169
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 113 deletions.
74 changes: 38 additions & 36 deletions peer/chaincode/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,59 +38,43 @@ type container struct {
Args []string
}

// chaincodeInvokeOrQuery invokes or queries the chaincode. If successful, the
// INVOKE form prints the transaction ID on STDOUT, and the QUERY form prints
// the query result on STDOUT. A command-line flag (-r, --raw) determines
// whether the query result is output as raw bytes, or as a printable string.
// The printable form is optionally (-x, --hex) a hexadecimal representation
// of the query response. If the query response is NIL, nothing is output.
func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool) (err error) {

if err = checkChaincodeCmdParams(cmd); err != nil {
return
func getChaincodeSpecification(cmd *cobra.Command) (*pb.ChaincodeSpec, error) {
spec := &pb.ChaincodeSpec{}
if err := checkChaincodeCmdParams(cmd); err != nil {
return spec, err
}

if chaincodeName == "" {
err = errors.New("Name not given for invoke/query")
return
}

devopsClient, err := common.GetDevopsClient(cmd)
if err != nil {
err = fmt.Errorf("Error building %s: %s", chainFuncName, err)
return
}
// Build the spec
input := &pb.ChaincodeInput{}
inputc := container{}
if err = json.Unmarshal([]byte(chaincodeCtorJSON), &inputc); err != nil {
err = fmt.Errorf("Chaincode argument error: %s", err)
return
if err := json.Unmarshal([]byte(chaincodeCtorJSON), &inputc); err != nil {
return spec, fmt.Errorf("Chaincode argument error: %s", err)
}
input = &pb.ChaincodeInput{Args: shim.ToChaincodeArgs(inputc.Args...)}
input := &pb.ChaincodeInput{Args: shim.ToChaincodeArgs(inputc.Args...)}

var attributes []string
if err = json.Unmarshal([]byte(chaincodeAttributesJSON), &attributes); err != nil {
err = fmt.Errorf("Chaincode argument error: %s", err)
return
if err := json.Unmarshal([]byte(chaincodeAttributesJSON), &attributes); err != nil {
return spec, fmt.Errorf("Chaincode argument error: %s", err)
}

chaincodeLang = strings.ToUpper(chaincodeLang)
spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]),
ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, CtorMsg: input, Attributes: attributes}

spec = &pb.ChaincodeSpec{
Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]),
ChaincodeID: &pb.ChaincodeID{Path: chaincodePath, Name: chaincodeName},
CtorMsg: input,
Attributes: attributes,
}
// If security is enabled, add client login token
if core.SecurityEnabled() {
if chaincodeUsr == common.UndefinedParamValue {
err = errors.New("Must supply username for chaincode when security is enabled")
return
return spec, errors.New("Must supply username for chaincode when security is enabled")
}

// Retrieve the CLI data storage path
// Returns /var/openchain/production/client/
localStore := util.GetCliFilePath()

// Check if the user is logged in before sending transaction
if _, err = os.Stat(localStore + "loginToken_" + chaincodeUsr); err == nil {
if _, err := os.Stat(localStore + "loginToken_" + chaincodeUsr); err == nil {
logger.Infof("Local user '%s' is already logged in. Retrieving login token.\n", chaincodeUsr)

// Read in the login token
Expand All @@ -110,8 +94,7 @@ func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool) (err
} else {
// Check if the token is not there and fail
if os.IsNotExist(err) {
err = fmt.Errorf("User '%s' not logged in. Use the 'login' command to obtain a security token.", chaincodeUsr)
return
return spec, fmt.Errorf("User '%s' not logged in. Use the 'login' command to obtain a security token.", chaincodeUsr)
}
// Unexpected error
panic(fmt.Errorf("Fatal error when checking for client login token: %s\n", err))
Expand All @@ -124,6 +107,25 @@ func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool) (err
panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
}
}
return spec, nil
}

// chaincodeInvokeOrQuery invokes or queries the chaincode. If successful, the
// INVOKE form prints the transaction ID on STDOUT, and the QUERY form prints
// the query result on STDOUT. A command-line flag (-r, --raw) determines
// whether the query result is output as raw bytes, or as a printable string.
// The printable form is optionally (-x, --hex) a hexadecimal representation
// of the query response. If the query response is NIL, nothing is output.
func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool) (err error) {
spec, err := getChaincodeSpecification(cmd)
if err != nil {
return err
}

devopsClient, err := common.GetDevopsClient(cmd)
if err != nil {
return fmt.Errorf("Error building %s: %s", chainFuncName, err)
}

// Build the ChaincodeInvocationSpec message
invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
Expand Down
80 changes: 3 additions & 77 deletions peer/chaincode/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,12 @@ limitations under the License.
package chaincode

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

"golang.org/x/net/context"

"github.com/hyperledger/fabric/core"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/peer/common"
"github.com/hyperledger/fabric/peer/util"
pb "github.com/hyperledger/fabric/protos"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// Cmd returns the cobra command for Chaincode Deploy
Expand All @@ -54,79 +44,15 @@ var chaincodeDeployCmd = &cobra.Command{
// (hash) is printed to STDOUT for use by subsequent chaincode-related CLI
// commands.
func chaincodeDeploy(cmd *cobra.Command, args []string) error {
if err := checkChaincodeCmdParams(cmd); err != nil {
spec, err := getChaincodeSpecification(cmd)
if err != nil {
return err
}

devopsClient, err := common.GetDevopsClient(cmd)
if err != nil {
return fmt.Errorf("Error building %s: %s", chainFuncName, err)
}
// Build the spec
input := &pb.ChaincodeInput{}
inputc := container{}
if err = json.Unmarshal([]byte(chaincodeCtorJSON), &inputc); err != nil {
return fmt.Errorf("Chaincode argument error: %s", err)
}
input = &pb.ChaincodeInput{Args: shim.ToChaincodeArgs(inputc.Args...)}

var attributes []string
if err := json.Unmarshal([]byte(chaincodeAttributesJSON), &attributes); err != nil {
return fmt.Errorf("Chaincode argument error: %s", err)
}

chaincodeLang = strings.ToUpper(chaincodeLang)
spec := &pb.ChaincodeSpec{
Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]),
ChaincodeID: &pb.ChaincodeID{Path: chaincodePath, Name: chaincodeName},
CtorMsg: input,
Attributes: attributes,
}

// If security is enabled, add client login token
if core.SecurityEnabled() {
logger.Debug("Security is enabled. Include security context in deploy spec")
if chaincodeUsr == common.UndefinedParamValue {
return errors.New("Must supply username for chaincode when security is enabled")
}

// Retrieve the CLI data storage path
// Returns /var/openchain/production/client/
localStore := util.GetCliFilePath()

// Check if the user is logged in before sending transaction
if _, err = os.Stat(localStore + "loginToken_" + chaincodeUsr); err == nil {
logger.Infof("Local user '%s' is already logged in. Retrieving login token.\n", chaincodeUsr)

// Read in the login token
token, err := ioutil.ReadFile(localStore + "loginToken_" + chaincodeUsr)
if err != nil {
panic(fmt.Errorf("Fatal error when reading client login token: %s\n", err))
}

// Add the login token to the chaincodeSpec
spec.SecureContext = string(token)

// If privacy is enabled, mark chaincode as confidential
if viper.GetBool("security.privacy") {
logger.Info("Set confidentiality level to CONFIDENTIAL.\n")
spec.ConfidentialityLevel = pb.ConfidentialityLevel_CONFIDENTIAL
}
} else {
// Check if the token is not there and fail
if os.IsNotExist(err) {
return fmt.Errorf("User '%s' not logged in. Use the 'login' command to obtain a security token.", chaincodeUsr)
}
// Unexpected error
panic(fmt.Errorf("Fatal error when checking for client login token: %s\n", err))
}
} else {
if chaincodeUsr != common.UndefinedParamValue {
logger.Warning("Username supplied but security is disabled.")
}
if viper.GetBool("security.privacy") {
panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
}
}

chaincodeDeploymentSpec, err := devopsClient.Deploy(context.Background(), spec)
if err != nil {
Expand Down

0 comments on commit 8ce0169

Please sign in to comment.