Skip to content

Commit

Permalink
[FAB-7101] Resource Management Client - Install CC
Browse files Browse the repository at this point in the history
Change-Id: Ic1944f769b9888541c20f3254f385236dd232300
Signed-off-by: Sandra Vrtikapa <sandra.vrtikapa@securekey.com>
  • Loading branch information
sandrask committed Nov 27, 2017
1 parent e9fa53a commit dd63d01
Show file tree
Hide file tree
Showing 19 changed files with 627 additions and 249 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,6 @@ populate-clean:

clean:
-$(GO_CMD) clean
-rm -Rf /tmp/enroll_user /tmp/msp /tmp/keyvaluestore /tmp/hfc-kvs
-rm -Rf /tmp/enroll_user /tmp/msp /tmp/keyvaluestore /tmp/hfc-kvs /tmp/state
-rm -f integration-report.xml report.xml
-FIXTURE_PROJECT_NAME=$(FIXTURE_PROJECT_NAME) DOCKER_REMOVE_FORCE=$(FIXTURE_DOCKER_REMOVE_FORCE) test/scripts/clean_integration.sh
22 changes: 21 additions & 1 deletion api/apifabclient/fabricclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type FabricClient interface {
CryptoSuite() apicryptosuite.CryptoSuite
SaveUserToStateStore(user User, skipPersistence bool) error
LoadUserFromStateStore(name string) (User, error)
InstallChaincode(chaincodeName string, chaincodePath string, chaincodeVersion string, chaincodePackage []byte, targets []txn.ProposalProcessor) ([]*txn.TransactionProposalResponse, string, error)
InstallChaincode(request InstallChaincodeRequest) ([]*txn.TransactionProposalResponse, string, error)
QueryChannels(peer Peer) (*pb.ChannelQueryResponse, error)
QueryInstalledChaincodes(peer Peer) (*pb.ChaincodeQueryResponse, error)
UserContext() User
Expand Down Expand Up @@ -75,3 +75,23 @@ type CreateChannelRequest struct {
// This request struct also has the field for consistency but perhaps it should be removed.
TxnID txn.TransactionID
}

// InstallChaincodeRequest requests chaincode installation on the network
type InstallChaincodeRequest struct {
// required - name of the chaincode
Name string
// required - path to the location of chaincode sources (path from GOPATH/src folder)
Path string
// chaincodeVersion: required - version of the chaincode
Version string
// required - package (chaincode package type and bytes)
Package *CCPackage
// required - proposal processor list
Targets []txn.ProposalProcessor
}

// CCPackage contains package type and bytes required to create CDS
type CCPackage struct {
Type pb.ChaincodeSpec_Type
Code []byte
}
28 changes: 28 additions & 0 deletions api/apitxn/resmgmtclient/resmgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,37 @@ type JoinChannelOpts struct {
TargetFilter TargetFilter // peer filter
}

// InstallCCRequest contains install chaincode request parameters
type InstallCCRequest struct {
Name string
Path string
Version string
Package *fab.CCPackage
}

// InstallCCResponse contains install chaincode response status
type InstallCCResponse struct {
Target string
Status int32
Info string
Err error
}

// InstallCCOpts contains options for installing chaincode
type InstallCCOpts struct {
Targets []fab.Peer // target peers
TargetFilter TargetFilter // target filter
}

// ResourceMgmtClient is responsible for managing resources: peers joining channels, and installing and instantiating chaincodes(TODO).
type ResourceMgmtClient interface {

// InstallCC - install chaincode
InstallCC(req InstallCCRequest) ([]InstallCCResponse, error)

// InstallCCWithOpts installs chaincode with custom options (specific peers, filtered peers)
InstallCCWithOpts(req InstallCCRequest, opts InstallCCOpts) ([]InstallCCResponse, error)

// JoinChannel allows for peers to join existing channel
JoinChannel(channelID string) error

Expand Down
2 changes: 1 addition & 1 deletion def/fabapi/context/defprovider/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (f *SessionClientFactory) NewChannelMgmtClient(sdk context.SDK, session con
return chmgmtImpl.NewChannelMgmtClient(client, config)
}

// NewResourceMgmtClient returns a client that manager resources
// NewResourceMgmtClient returns a client that manages resources
func (f *SessionClientFactory) NewResourceMgmtClient(sdk context.SDK, session context.Session, config apiconfig.Config, filter resmgmt.TargetFilter) (resmgmt.ResourceMgmtClient, error) {

// For now settings are the same as for system client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package packager
package gopackager

import (
"archive/tar"
Expand All @@ -18,6 +18,9 @@ import (

"github.com/hyperledger/fabric-sdk-go/pkg/errors"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"

fab "github.com/hyperledger/fabric-sdk-go/api/apifabclient"
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
)

// Descriptor ...
Expand All @@ -33,34 +36,44 @@ var keep = []string{".go", ".c", ".h"}

var logger = logging.NewLogger("fabric_sdk_go")

// PackageGoLangCC ...
func PackageGoLangCC(chaincodePath string) ([]byte, error) {
// NewCCPackage creates new go lang chaincode package
func NewCCPackage(chaincodePath string, goPath string) (*fab.CCPackage, error) {

if chaincodePath == "" {
return nil, errors.New("chaincode path must be provided")
}

// Determine the user's $GOPATH
goPath := os.Getenv("GOPATH")
if goPath == "" {
return nil, errors.New("GOPATH not defined")
var projDir string
gp := goPath
if gp == "" {
// TODO: for now use env variable
gp = os.Getenv("GOPATH")
if gp == "" {
return nil, errors.New("GOPATH not defined")
}
logger.Debugf("Default GOPATH=%s", gp)
}
logger.Debugf("GOPATH environment variable=%s", goPath)

// Compose the path to the chaincode project directory
projDir := path.Join(goPath, "src", chaincodePath)
projDir = path.Join(gp, "src", chaincodePath)

logger.Debugf("projDir variable=%s", projDir)

// We generate the tar in two phases: First grab a list of descriptors,
// and then pack them into an archive. While the two phases aren't
// strictly necessary yet, they pave the way for the future where we
// will need to assemble sources from multiple packages
descriptors, err := findSource(goPath, projDir)
descriptors, err := findSource(gp, projDir)
if err != nil {
return nil, err
}
tarBytes, err := generateTarGz(descriptors)
if err != nil {
return nil, err
}
return tarBytes, nil

ccPkg := &fab.CCPackage{Type: pb.ChaincodeSpec_GOLANG, Code: tarBytes}

return ccPkg, nil
}

// -------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package packager
package gopackager

import (
"archive/tar"
Expand All @@ -17,19 +17,18 @@ import (
)

// Test golang ChainCode packaging
func TestPackageGoLangCC(t *testing.T) {
func TestNewCCPackage(t *testing.T) {
pwd, err := os.Getwd()
if err != nil {
t.Fatalf("error from os.Getwd %v", err)
}
os.Setenv("GOPATH", path.Join(pwd, "../../../test/fixtures/testdata"))

ccPackage, err := PackageGoLangCC("github.com")
ccPackage, err := NewCCPackage("github.com", path.Join(pwd, "../../../../test/fixtures/testdata"))
if err != nil {
t.Fatalf("error from PackageGoLangCC %v", err)
t.Fatalf("error from Create %v", err)
}

r := bytes.NewReader(ccPackage)
r := bytes.NewReader(ccPackage.Code)
gzf, err := gzip.NewReader(r)
if err != nil {
t.Fatalf("error from gzip.NewReader %v", err)
Expand Down Expand Up @@ -61,9 +60,9 @@ func TestPackageGoLangCC(t *testing.T) {
}

// Test Package Go ChainCode
func TestEmptyPackageGoLangCC(t *testing.T) {
os.Setenv("GOPATH", "")
_, err := PackageGoLangCC("")
func TestEmptyCreate(t *testing.T) {

_, err := NewCCPackage("", "")
if err == nil {
t.Fatalf("Package Empty GoLang CC must return an error.")
}
Expand All @@ -75,11 +74,10 @@ func TestBadPackagePathGoLangCC(t *testing.T) {
if err != nil {
t.Fatalf("error from os.Getwd %v", err)
}
os.Setenv("GOPATH", path.Join(pwd, "../../../test/fixturesABC"))

_, err = PackageGoLangCC("github.com")
_, err = NewCCPackage("github.com", path.Join(pwd, "../../../../test/fixturesABC"))
if err == nil {
t.Fatalf("error expected from PackageGoLangCC %v", err)
t.Fatalf("error expected from Create %v", err)
}
}

Expand Down
31 changes: 12 additions & 19 deletions pkg/fabric-client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity"
fc "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal"
"github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal/txnproc"
packager "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/packager"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
)

Expand Down Expand Up @@ -480,31 +479,25 @@ func (c *Client) QueryInstalledChaincodes(peer fab.Peer) (*pb.ChaincodeQueryResp
}

// InstallChaincode sends an install proposal to one or more endorsing peers.
func (c *Client) InstallChaincode(chaincodeName string, chaincodePath string, chaincodeVersion string,
chaincodePackage []byte, targets []apitxn.ProposalProcessor) ([]*apitxn.TransactionProposalResponse, string, error) {
func (c *Client) InstallChaincode(req fab.InstallChaincodeRequest) ([]*apitxn.TransactionProposalResponse, string, error) {

if chaincodeName == "" {
return nil, "", errors.New("chaincodeName required")
if req.Name == "" {
return nil, "", errors.New("chaincode name required")
}
if chaincodePath == "" {
return nil, "", errors.New("chaincodePath required")
if req.Path == "" {
return nil, "", errors.New("chaincode path required")
}
if chaincodeVersion == "" {
return nil, "", errors.New("chaincodeVersion required")
if req.Version == "" {
return nil, "", errors.New("chaincode version required")
}

if chaincodePackage == nil {
var err error
chaincodePackage, err = packager.PackageCC(chaincodePath, "")
if err != nil {
return nil, "", errors.WithMessage(err, "PackageCC failed")
}
if req.Package == nil {
return nil, "", errors.New("chaincode package is required")
}

now := time.Now()
cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: chaincodeName, Path: chaincodePath, Version: chaincodeVersion}},
CodePackage: chaincodePackage, EffectiveDate: &google_protobuf.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())}}
Type: req.Package.Type, ChaincodeId: &pb.ChaincodeID{Name: req.Name, Path: req.Path, Version: req.Version}},
CodePackage: req.Package.Code, EffectiveDate: &google_protobuf.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())}}

if c.userContext == nil {
return nil, "", errors.New("user context required")
Expand Down Expand Up @@ -546,7 +539,7 @@ func (c *Client) InstallChaincode(chaincodeName string, chaincodePath string, ch
SignedProposal: signedProposal,
Proposal: proposal,
TxnID: txnID,
}, targets)
}, req.Targets)

return transactionProposalResponse, txID, err
}
Expand Down
27 changes: 21 additions & 6 deletions pkg/fabric-client/mocks/mockclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,31 @@ func (c *MockClient) QueryChannels(peer fab.Peer) (*pb.ChannelQueryResponse, err
return nil, errors.New("Not implemented yet")
}

//QueryInstalledChaincodes ...
//QueryInstalledChaincodes mocks query installed chaincodes
func (c *MockClient) QueryInstalledChaincodes(peer fab.Peer) (*pb.ChaincodeQueryResponse, error) {
return nil, errors.New("Not implemented yet")
if peer == nil {
return nil, errors.New("Generate Error")
}
ci := &pb.ChaincodeInfo{Name: "name", Version: "version", Path: "path"}
response := &pb.ChaincodeQueryResponse{Chaincodes: []*pb.ChaincodeInfo{ci}}
return response, nil
}

// InstallChaincode ...
func (c *MockClient) InstallChaincode(chaincodeName string, chaincodePath string, chaincodeVersion string,
chaincodePackage []byte, targets []apitxn.ProposalProcessor) ([]*apitxn.TransactionProposalResponse, string, error) {
return nil, "", errors.New("Not implemented yet")
// InstallChaincode mocks install chaincode
func (c *MockClient) InstallChaincode(req fab.InstallChaincodeRequest) ([]*apitxn.TransactionProposalResponse, string, error) {
if req.Name == "error" {
return nil, "", errors.New("Generate Error")
}

if req.Name == "errorInResponse" {
result := apitxn.TransactionProposalResult{Endorser: "http://peer1.com", Status: 10}
response := &apitxn.TransactionProposalResponse{TransactionProposalResult: result, Err: errors.New("Generate Response Error")}
return []*apitxn.TransactionProposalResponse{response}, "1234", nil
}

result := apitxn.TransactionProposalResult{Endorser: "http://peer1.com", Status: 0}
response := &apitxn.TransactionProposalResponse{TransactionProposalResult: result}
return []*apitxn.TransactionProposalResponse{response}, "1234", nil
}

// UserContext ...
Expand Down
35 changes: 0 additions & 35 deletions pkg/fabric-client/packager/packager.go

This file was deleted.

Loading

0 comments on commit dd63d01

Please sign in to comment.