Commit e862c99f authored by Yacov Manevich's avatar Yacov Manevich Committed by Gerrit Code Review
Browse files

Merge "FAB-10823 Refactor platforms to instance"

parents 99f7d1a0 ff969353
......@@ -40,7 +40,7 @@ func (vm *VM) BuildChaincodeContainer(spec *pb.ChaincodeSpec) error {
}
cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage}
dockerSpec, err := platforms.GenerateDockerBuild(cds)
dockerSpec, err := platforms.NewRegistry().GenerateDockerBuild(cds)
if err != nil {
return fmt.Errorf("Error getting chaincode docker image: %s", err)
}
......
......@@ -11,12 +11,9 @@ import (
"compress/gzip"
"fmt"
"io"
"os"
"strings"
"io/ioutil"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/metadata"
"github.com/hyperledger/fabric/core/chaincode/platforms/car"
......@@ -24,10 +21,8 @@ import (
"github.com/hyperledger/fabric/core/chaincode/platforms/golang"
"github.com/hyperledger/fabric/core/chaincode/platforms/java"
"github.com/hyperledger/fabric/core/chaincode/platforms/node"
"github.com/hyperledger/fabric/core/config"
cutil "github.com/hyperledger/fabric/core/container/util"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/spf13/viper"
)
// Interface for validating the specification and and writing the package for
......@@ -43,19 +38,48 @@ type Platform interface {
var logger = flogging.MustGetLogger("chaincode-platform")
// XXX Temporary singleton hack to allow tests to continue to work
var r = NewRegistry()
// Added for unit testing purposes
var _Find = Find
var _GetPath = config.GetPath
var _VGetBool = viper.GetBool
var _OSStat = os.Stat
var _IOUtilReadFile = ioutil.ReadFile
var _Find = find
var _CUtilWriteBytesToPackage = cutil.WriteBytesToPackage
var _generateDockerfile = generateDockerfile
var _generateDockerBuild = generateDockerBuild
var _generateDockerfile = r.generateDockerfile
var _generateDockerBuild = r.generateDockerBuild
type Registry struct{}
// TODO, ultimately this should take the platforms as parameters
func NewRegistry() *Registry {
return &Registry{}
}
func (r *Registry) ValidateSpec(spec *pb.ChaincodeSpec) error {
p, err := _Find(spec.Type)
if err != nil {
return err
}
return p.ValidateSpec(spec)
}
// Find returns the platform interface for the given platform type
func Find(chaincodeType pb.ChaincodeSpec_Type) (Platform, error) {
func (r *Registry) ValidateDeploymentSpec(spec *pb.ChaincodeDeploymentSpec) error {
p, err := _Find(spec.ChaincodeSpec.Type)
if err != nil {
return err
}
return p.ValidateDeploymentSpec(spec)
}
func (r *Registry) GetMetadataProvider(spec *pb.ChaincodeDeploymentSpec) (ccmetadata.MetadataProvider, error) {
p, err := _Find(spec.ChaincodeSpec.Type)
if err != nil {
return nil, err
}
return p.GetMetadataProvider(spec), nil
}
// find returns the platform interface for the given platform type
func find(chaincodeType pb.ChaincodeSpec_Type) (Platform, error) {
switch chaincodeType {
case pb.ChaincodeSpec_GOLANG:
return &golang.Platform{}, nil
......@@ -68,10 +92,9 @@ func Find(chaincodeType pb.ChaincodeSpec_Type) (Platform, error) {
default:
return nil, fmt.Errorf("Unknown chaincodeType: %s", chaincodeType)
}
}
func GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
func (r *Registry) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
platform, err := _Find(spec.Type)
if err != nil {
return nil, err
......@@ -80,7 +103,7 @@ func GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
return platform.GetDeploymentPayload(spec)
}
func generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentSpec) ([]byte, error) {
func (r *Registry) generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentSpec) ([]byte, error) {
var buf []string
......@@ -118,7 +141,7 @@ func generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentSpec) ([]b
type InputFiles map[string][]byte
func generateDockerBuild(platform Platform, cds *pb.ChaincodeDeploymentSpec, inputFiles InputFiles, tw *tar.Writer) error {
func (r *Registry) generateDockerBuild(platform Platform, cds *pb.ChaincodeDeploymentSpec, inputFiles InputFiles, tw *tar.Writer) error {
var err error
......@@ -143,7 +166,7 @@ func generateDockerBuild(platform Platform, cds *pb.ChaincodeDeploymentSpec, inp
return nil
}
func GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec) (io.Reader, error) {
func (r *Registry) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec) (io.Reader, error) {
inputFiles := make(InputFiles)
......
......@@ -24,7 +24,7 @@ import (
// START Find tests
func TestFind(t *testing.T) {
response, err := Find(pb.ChaincodeSpec_GOLANG)
response, err := find(pb.ChaincodeSpec_GOLANG)
_, ok := response.(Platform)
if !ok {
t.Error("Assertion error")
......@@ -32,7 +32,7 @@ func TestFind(t *testing.T) {
assert.NotNil(t, response, "Response should have been set")
assert.Nil(t, err, "Error should have been nil")
response, err = Find(pb.ChaincodeSpec_CAR)
response, err = find(pb.ChaincodeSpec_CAR)
_, ok = response.(Platform)
if !ok {
t.Error("Assertion error")
......@@ -40,7 +40,7 @@ func TestFind(t *testing.T) {
assert.NotNil(t, response, "Response should have been set")
assert.Nil(t, err, "Error should have been nil")
response, err = Find(pb.ChaincodeSpec_JAVA)
response, err = find(pb.ChaincodeSpec_JAVA)
_, ok = response.(Platform)
if !ok {
t.Error("Assertion error")
......@@ -48,7 +48,7 @@ func TestFind(t *testing.T) {
assert.NotNil(t, response, "Response should have been set")
assert.Nil(t, err, "Error should have been nil")
response, err = Find(pb.ChaincodeSpec_UNDEFINED)
response, err = find(pb.ChaincodeSpec_UNDEFINED)
_, ok = response.(Platform)
assert.Nil(t, response, "Response should have been nil")
assert.NotNil(t, err, "Error should have been set")
......@@ -84,7 +84,7 @@ func TestGetDeplotmentPayload(t *testing.T) {
fake := pb.ChaincodeSpec{
Type: pb.ChaincodeSpec_GOLANG,
}
response, err := GetDeploymentPayload(&fake)
response, err := r.GetDeploymentPayload(&fake)
fmt.Println(err)
......@@ -93,7 +93,7 @@ func TestGetDeplotmentPayload(t *testing.T) {
_Find = FakeFindErr
response, err = GetDeploymentPayload(&fake)
response, err = r.GetDeploymentPayload(&fake)
fmt.Println(err)
......@@ -159,12 +159,12 @@ func TestGenerateDockerfile(t *testing.T) {
},
},
}
response, err := generateDockerfile(mockPlatform, fakeChaincodeSpec)
response, err := r.generateDockerfile(mockPlatform, fakeChaincodeSpec)
assert.NotNil(t, err, "Error should have been set")
assert.Nil(t, response, "Response should not have been set")
mockPlatformOk := &FakePlatformOk{}
response, err = generateDockerfile(mockPlatformOk, fakeChaincodeSpec)
response, err = r.generateDockerfile(mockPlatformOk, fakeChaincodeSpec)
assert.Nil(t, err, "Error should not have been set")
assert.NotNil(t, response, "Response should not have been set")
......@@ -185,7 +185,7 @@ func TestGenerateDockerfile(t *testing.T) {
"Should return the correct values when TLS is not enabled",
)
response, err = generateDockerfile(mockPlatformOk, fakeChaincodeSpec)
response, err = r.generateDockerfile(mockPlatformOk, fakeChaincodeSpec)
contents = strings.Join(buf, "\n")
assert.Equal(
t,
......@@ -241,16 +241,16 @@ func TestGenerateDockerBuild1(t *testing.T) {
// No errors
_CUtilWriteBytesToPackage = CUtilWriteBytesToPackageOk
err := generateDockerBuild(mockPlatformOk, fakeChaincodeSpec, inputFiles, mockTw)
err := r.generateDockerBuild(mockPlatformOk, fakeChaincodeSpec, inputFiles, mockTw)
assert.Nil(t, err, "err should not have been set")
// Error from cutil.WriteBytesToPackage
_CUtilWriteBytesToPackage = CUtilWriteBytesToPackageErr
err = generateDockerBuild(mockPlatformOk, fakeChaincodeSpec, inputFiles, mockTw)
err = r.generateDockerBuild(mockPlatformOk, fakeChaincodeSpec, inputFiles, mockTw)
assert.NotNil(t, err, "err should have been set")
// Error from platform.GenerateDockerBuild
_CUtilWriteBytesToPackage = CUtilWriteBytesToPackageOk
err = generateDockerBuild(mockPlatformErr, fakeChaincodeSpec, inputFiles, mockTw)
err = r.generateDockerBuild(mockPlatformErr, fakeChaincodeSpec, inputFiles, mockTw)
assert.NotNil(t, err, "err should have been set")
}
......@@ -302,20 +302,20 @@ func TestGenerateDockerBuild2(t *testing.T) {
}
// No error
io, err := GenerateDockerBuild(fakeChaincodeSpec)
io, err := r.GenerateDockerBuild(fakeChaincodeSpec)
assert.NotNil(t, io, "io should not be nil")
assert.Nil(t, err, "error should be nil")
// Error from Find
_Find = FindErr
io, err = GenerateDockerBuild(fakeChaincodeSpec)
io, err = r.GenerateDockerBuild(fakeChaincodeSpec)
assert.Nil(t, io, "io should be nil")
assert.NotNil(t, err, "error should not be nil")
// Error from generateDockerfile
_Find = oldFind
_generateDockerfile = generateDockerfileErr
io, err = GenerateDockerBuild(fakeChaincodeSpec)
io, err = r.GenerateDockerBuild(fakeChaincodeSpec)
assert.Nil(t, io, "io should be nil")
assert.NotNil(t, err, "error should not be nil")
......@@ -323,7 +323,7 @@ func TestGenerateDockerBuild2(t *testing.T) {
_Find = oldFind
_generateDockerfile = oldGenerateDockerfile
_generateDockerBuild = generateDockerBuildErr
io, err = GenerateDockerBuild(fakeChaincodeSpec)
io, err = r.GenerateDockerBuild(fakeChaincodeSpec)
assert.NotNil(t, io, "io should not be nil")
assert.Nil(t, err, "error should be nil")
}
......
......@@ -50,12 +50,11 @@ func ExtractStatedbArtifactsForChaincode(ccname, ccversion string) (installed bo
// This function is called during chaincode instantiate/upgrade (from above), and from install, so that statedb artifacts can be created.
func ExtractStatedbArtifactsFromCCPackage(ccpackage CCPackage) (statedbArtifactsTar []byte, err error) {
cds := ccpackage.GetDepSpec()
pform, err := platforms.Find(cds.ChaincodeSpec.Type)
metaprov, err := platforms.NewRegistry().GetMetadataProvider(cds)
if err != nil {
ccproviderLogger.Infof("invalid deployment spec (bad platform type:%s)", cds.ChaincodeSpec.Type)
ccproviderLogger.Infof("invalid deployment spec: %s", err)
return nil, fmt.Errorf("invalid deployment spec")
}
metaprov := pform.GetMetadataProvider(cds)
return metaprov.GetMetadataAsTarEntries()
}
......
......@@ -132,7 +132,7 @@ type PlatformBuilder struct {
// Build a tar stream based on the CDS
func (b *PlatformBuilder) Build() (io.Reader, error) {
return platforms.GenerateDockerBuild(b.DeploymentSpec)
return platforms.NewRegistry().GenerateDockerBuild(b.DeploymentSpec)
}
func (si StartContainerReq) Do(ctxt context.Context, v VM) error {
......@@ -200,5 +200,5 @@ func GetChaincodePackageBytes(spec *pb.ChaincodeSpec) ([]byte, error) {
return nil, fmt.Errorf("invalid chaincode spec")
}
return platforms.GetDeploymentPayload(spec)
return platforms.NewRegistry().GetDeploymentPayload(spec)
}
......@@ -119,13 +119,13 @@ func Test_Start(t *testing.T) {
ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: chaincodePath},
Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")},
}
codePackage, err := platforms.GetDeploymentPayload(spec)
codePackage, err := platforms.NewRegistry().GetDeploymentPayload(spec)
if err != nil {
t.Fatal()
}
cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage}
bldr := &mockBuilder{
buildFunc: func() (io.Reader, error) { return platforms.GenerateDockerBuild(cds) },
buildFunc: func() (io.Reader, error) { return platforms.NewRegistry().GenerateDockerBuild(cds) },
}
// case 4: start called with builder and dockerClient.CreateContainer returns
......
......@@ -44,12 +44,7 @@ func checkSpec(spec *pb.ChaincodeSpec) error {
return errors.New("expected chaincode specification, nil received")
}
platform, err := platforms.Find(spec.Type)
if err != nil {
return errors.WithMessage(err, "failed to determine platform type")
}
return platform.ValidateSpec(spec)
return platforms.NewRegistry().ValidateSpec(spec)
}
// getChaincodeDeploymentSpec get chaincode deployment spec given the chaincode spec
......
......@@ -156,13 +156,7 @@ func GetChaincodeDeploymentSpec(code []byte) (*peer.ChaincodeDeploymentSpec, err
}
// FAB-2122: Validate the CDS according to platform specific requirements
platform, err := platforms.Find(cds.ChaincodeSpec.Type)
if err != nil {
return nil, err
}
err = platform.ValidateDeploymentSpec(cds)
return cds, err
return cds, platforms.NewRegistry().ValidateDeploymentSpec(cds)
}
// GetChaincodeAction gets the ChaincodeAction given chaicnode action bytes
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment