Skip to content

Commit adebfad

Browse files
author
Luis Sanchez
committed
[FAB-2718] Enable Java chaincode invoke
- ChaincodeBase updates: - query() method removed - run() return type changed to Reponse to mirror golang chaincode. - updated SimpleSample java chaincode - deleted bdd - introduce example02 'clone' in Java - Parameterized TestExecuteInvokeTransaction so that is runs w/ both Java and Go chaincode. - Added TestChaincodeInitializeInitError test. NOTES: - more cleanup is still needed, but this gets Java chaincode deployment going. - the other java chain samples need cleanup - there might be some features in the shim copy in fabric-sdk-java that should be merged into this version. Change-Id: Ie254a1430d53e4ca037ae4b3d2e51747e668752b Signed-off-by: Luis Sanchez <[email protected]>
1 parent cacb292 commit adebfad

File tree

19 files changed

+1185
-695
lines changed

19 files changed

+1185
-695
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ orderer-docker: build/image/orderer/$(DUMMY)
114114
configtxgen: GO_TAGS+= nopkcs11
115115
configtxgen: build/bin/configtxgen
116116

117+
javaenv: build/image/javaenv/$(DUMMY)
118+
117119
buildenv: build/image/buildenv/$(DUMMY)
118120

119121
build/image/testenv/$(DUMMY): build/image/buildenv/$(DUMMY)

core/chaincode/chaincodetest.yaml

+19-3
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ logging:
139139
status: warning
140140
stop: warning
141141
login: warning
142-
vm: warning
143-
chaincode: warning
142+
vm: debug
143+
chaincode: debug
144144

145145

146146
###############################################################################
@@ -331,7 +331,7 @@ vm:
331331
file: /path/to/ca.pem
332332
key:
333333
file: /path/to/server-key.pem
334-
334+
attachStdout: true
335335
###############################################################################
336336
#
337337
# Chaincode section
@@ -361,10 +361,24 @@ chaincode:
361361
# of platforms are expanded. For now, we can just use baseos
362362
runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
363363

364+
java:
365+
# This is an image based on java:openjdk-8 with addition compiler
366+
# tools added for java shim layer packaging.
367+
# This image is packed with shim layer libraries that are necessary
368+
# for Java chaincode runtime.
369+
Dockerfile: |
370+
from $(DOCKER_NS)/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION)
371+
364372
# timeout in millisecs for starting up a container and waiting for Register
365373
# to come through. 1sec should be plenty for chaincode unit tests
366374
startuptimeout: 1000
367375

376+
# timeout in millisecs for invokes and initialize commands
377+
# this timeout is used by all chaincodes in all the channels including
378+
# system chaincodes. Default is 30000ms (30 seconds)
379+
executetimeout: 30000
380+
381+
368382
#timeout in millisecs for deploying chaincode from a remote repository.
369383
deploytimeout: 60000
370384

@@ -393,6 +407,8 @@ chaincode:
393407
escc: enable
394408
vscc: enable
395409

410+
logLevel: debug
411+
396412
###############################################################################
397413
#
398414
# Ledger section - ledger configuration encompases both the blockchain

core/chaincode/exectransaction_test.go

+133-25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package chaincode
1919
import (
2020
"encoding/json"
2121
"fmt"
22+
"math/rand"
2223
"net"
2324
"os"
2425
"path/filepath"
@@ -317,7 +318,7 @@ func deploy2(ctx context.Context, cccid *ccprovider.CCContext, chaincodeDeployme
317318

318319
// Invoke a chaincode.
319320
func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec, blockNumber uint64) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
320-
return invokeWithVersion(ctx, chainID, "0", spec, blockNumber)
321+
return invokeWithVersion(ctx, chainID, spec.GetChaincodeId().Version, spec, blockNumber)
321322
}
322323

323324
// Invoke a chaincode with version (needed for upgrade)
@@ -569,13 +570,13 @@ func checkFinalState(cccid *ccprovider.CCContext) error {
569570
}
570571

571572
// Invoke chaincode_example02
572-
func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, args []string, destroyImage bool) error {
573+
func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, chaincodeType pb.ChaincodeSpec_Type, args []string, destroyImage bool) error {
573574

574575
var nextBlockNumber uint64
575576

576577
f := "init"
577578
argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
578-
spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
579+
spec := &pb.ChaincodeSpec{Type: chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
579580
_, err := deploy(ctxt, cccid, spec, nextBlockNumber)
580581
nextBlockNumber++
581582
ccID := spec.ChaincodeId.Name
@@ -598,7 +599,7 @@ func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContex
598599

599600
f = "invoke"
600601
invokeArgs := append([]string{f}, args...)
601-
spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
602+
spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
602603
_, uuid, _, err := invoke(ctxt, cccid.ChainID, spec, nextBlockNumber)
603604
nextBlockNumber++
604605
if err != nil {
@@ -614,7 +615,7 @@ func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContex
614615
// Test for delete state
615616
f = "delete"
616617
delArgs := util.ToChaincodeArgs(f, "a")
617-
spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}}
618+
spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}}
618619
_, _, _, err = invoke(ctxt, cccid.ChainID, spec, nextBlockNumber)
619620
if err != nil {
620621
return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err)
@@ -623,34 +624,56 @@ func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContex
623624
return nil
624625
}
625626

627+
const (
628+
chaincodeExample02GolangPath = "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
629+
chaincodeExample02JavaPath = "../../examples/chaincode/java/chaincode_example02"
630+
chaincodeExample06JavaPath = "../../examples/chaincode/java/chaincode_example06"
631+
)
632+
626633
func TestExecuteInvokeTransaction(t *testing.T) {
627-
chainID := util.GetTestChainID()
628634

629-
lis, err := initPeer(chainID)
630-
if err != nil {
631-
t.Fail()
632-
t.Logf("Error creating peer: %s", err)
635+
testCases := []struct {
636+
chaincodeType pb.ChaincodeSpec_Type
637+
chaincodePath string
638+
}{
639+
{pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath},
640+
{pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath},
633641
}
634642

635-
defer finitPeer(lis, chainID)
643+
for _, tc := range testCases {
644+
t.Run(tc.chaincodeType.String(), func(t *testing.T) {
636645

637-
var ctxt = context.Background()
646+
chainID := util.GetTestChainID()
638647

639-
cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
640-
url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
641-
ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"}
648+
lis, err := initPeer(chainID)
649+
if err != nil {
650+
t.Fail()
651+
t.Logf("Error creating peer: %s", err)
652+
}
642653

643-
args := []string{"a", "b", "10"}
644-
err = invokeExample02Transaction(ctxt, cccid, ccID, args, true)
645-
if err != nil {
646-
t.Fail()
647-
t.Logf("Error invoking transaction: %s", err)
648-
} else {
649-
fmt.Print("Invoke test passed\n")
650-
t.Log("Invoke test passed")
654+
defer finitPeer(lis, chainID)
655+
656+
var ctxt = context.Background()
657+
chaincodeName := generateChaincodeName(tc.chaincodeType)
658+
chaincodeVersion := "1.0.0.0"
659+
cccid := ccprovider.NewCCContext(chainID, chaincodeName, chaincodeVersion, "", false, nil, nil)
660+
ccID := &pb.ChaincodeID{Name: chaincodeName, Path: tc.chaincodePath, Version: chaincodeVersion}
661+
662+
args := []string{"a", "b", "10"}
663+
err = invokeExample02Transaction(ctxt, cccid, ccID, tc.chaincodeType, args, true)
664+
if err != nil {
665+
t.Fail()
666+
t.Logf("Error invoking transaction: %s", err)
667+
} else {
668+
fmt.Print("Invoke test passed\n")
669+
t.Log("Invoke test passed")
670+
}
671+
672+
theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
673+
674+
})
651675
}
652676

653-
theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
654677
}
655678

656679
// Test the execution of an invalid transaction.
@@ -674,7 +697,7 @@ func TestExecuteInvokeInvalidTransaction(t *testing.T) {
674697

675698
//FAIL, FAIL!
676699
args := []string{"x", "-1"}
677-
err = invokeExample02Transaction(ctxt, cccid, ccID, args, false)
700+
err = invokeExample02Transaction(ctxt, cccid, ccID, pb.ChaincodeSpec_GOLANG, args, false)
678701

679702
//this HAS to fail with expectedDeltaStringPrefix
680703
if err != nil {
@@ -1509,6 +1532,76 @@ func TestChaincodeInvokesSystemChaincode(t *testing.T) {
15091532
theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
15101533
}
15111534

1535+
func TestChaincodeInitializeInitError(t *testing.T) {
1536+
testCases := []struct {
1537+
name string
1538+
chaincodeType pb.ChaincodeSpec_Type
1539+
chaincodePath string
1540+
args []string
1541+
}{
1542+
{"NotSuccessResponse", pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath, []string{"init", "not", "enough", "args"}},
1543+
{"NotSuccessResponse", pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath, []string{"init", "not", "enough", "args"}},
1544+
{"RuntimeException", pb.ChaincodeSpec_JAVA, chaincodeExample06JavaPath, []string{"runtimeException"}},
1545+
}
1546+
1547+
channelID := util.GetTestChainID()
1548+
1549+
for _, tc := range testCases {
1550+
t.Run(tc.name+"_"+tc.chaincodeType.String(), func(t *testing.T) {
1551+
1552+
// initialize peer
1553+
if listener, err := initPeer(channelID); err != nil {
1554+
t.Errorf("Error creating peer: %s", err)
1555+
} else {
1556+
defer finitPeer(listener, channelID)
1557+
}
1558+
1559+
var nextBlockNumber uint64
1560+
1561+
// the chaincode to install and instanciate
1562+
chaincodeName := generateChaincodeName(tc.chaincodeType)
1563+
chaincodePath := tc.chaincodePath
1564+
chaincodeVersion := "1.0.0.0"
1565+
chaincodeType := tc.chaincodeType
1566+
chaincodeDeployArgs := util.ArrayToChaincodeArgs(tc.args)
1567+
1568+
// new chaincode context for passing around parameters
1569+
chaincodeCtx := ccprovider.NewCCContext(channelID, chaincodeName, chaincodeVersion, "", false, nil, nil)
1570+
1571+
// attempt to deploy chaincode
1572+
_, err := deployChaincode(context.Background(), chaincodeCtx, chaincodeType, chaincodePath, chaincodeDeployArgs, nextBlockNumber)
1573+
1574+
// deploy should of failed
1575+
if err == nil {
1576+
t.Fatal("Deployment should have failed.")
1577+
}
1578+
t.Log(err)
1579+
1580+
})
1581+
}
1582+
}
1583+
1584+
func deployChaincode(ctx context.Context, chaincodeCtx *ccprovider.CCContext, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, nextBlockNumber uint64) ([]byte, error) {
1585+
1586+
chaincodeSpec := &pb.ChaincodeSpec{
1587+
ChaincodeId: &pb.ChaincodeID{
1588+
Name: chaincodeCtx.Name,
1589+
Version: chaincodeCtx.Version,
1590+
Path: path,
1591+
},
1592+
Type: chaincodeType,
1593+
Input: &pb.ChaincodeInput{
1594+
Args: args,
1595+
},
1596+
}
1597+
1598+
result, err := deploy(ctx, chaincodeCtx, chaincodeSpec, nextBlockNumber)
1599+
if err != nil {
1600+
return nil, fmt.Errorf("Error deploying <%s:%s>: %s", chaincodeSpec.ChaincodeId.Name, chaincodeSpec.ChaincodeId.Version, err)
1601+
}
1602+
return result, nil
1603+
}
1604+
15121605
var signer msp.SigningIdentity
15131606

15141607
func TestMain(m *testing.M) {
@@ -1527,3 +1620,18 @@ func TestMain(m *testing.M) {
15271620
SetupTestConfig()
15281621
os.Exit(m.Run())
15291622
}
1623+
1624+
var rng *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
1625+
1626+
func generateChaincodeName(chaincodeType pb.ChaincodeSpec_Type) string {
1627+
prefix := "cc_"
1628+
switch chaincodeType {
1629+
case pb.ChaincodeSpec_GOLANG:
1630+
prefix = "cc_go_"
1631+
case pb.ChaincodeSpec_JAVA:
1632+
prefix = "cc_java_"
1633+
case pb.ChaincodeSpec_NODE:
1634+
prefix = "cc_js_"
1635+
}
1636+
return fmt.Sprintf("%s%06d", prefix, rng.Intn(999999))
1637+
}

core/chaincode/multichains_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestExecuteInvokeOnManyChains(t *testing.T) {
4444
args := []string{"a", "b", "10"}
4545
for _, c := range chains {
4646
cccid := ccprovider.NewCCContext(c, "example02", "0", "", false, nil, nil)
47-
err = invokeExample02Transaction(ctxt, cccid, chaincodeID, args, false)
47+
err = invokeExample02Transaction(ctxt, cccid, chaincodeID, pb.ChaincodeSpec_GOLANG, args, false)
4848
if err != nil {
4949
t.Fail()
5050
t.Logf("Error invoking transaction: %s", err)

core/chaincode/shim/java/build.gradle

+16-10
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,21 @@ task copyToLib(type: Copy) {
8989

9090

9191
task copyProtos(type:Copy){
92-
93-
from ("${rootDir}/protos/peer"){
94-
include '**/chaincode_event.proto'
95-
include '**/chaincode.proto'
96-
include '**/chaincode_shim.proto'
97-
include '**/proposal.proto'
98-
include '**/proposal_response.proto'
99-
}
100-
into "${projectDir}/src/main/proto/peer"
101-
92+
into "peer", {
93+
from ("${rootDir}/protos/peer"){
94+
include 'chaincode_event.proto'
95+
include 'chaincode.proto'
96+
include 'chaincode_shim.proto'
97+
include 'proposal.proto'
98+
include 'proposal_response.proto'
99+
}
100+
}
101+
into "common", {
102+
from ("${rootDir}/protos/common"){
103+
include 'common.proto'
104+
}
105+
}
106+
into "${projectDir}/src/main/proto"
102107
}
103108

104109
tasks['build'].mustRunAfter tasks['copyProtos']
@@ -108,6 +113,7 @@ build.finalizedBy(publishToMavenLocal)
108113

109114
dependencies {
110115
compile 'com.google.protobuf:protobuf-java:3.0.0'
116+
compile 'com.google.protobuf:protobuf-java-util:3.0.0'
111117
compile 'io.grpc:grpc-all:0.13.2'
112118
compile 'commons-cli:commons-cli:1.3.1'
113119
compile 'io.netty:netty-tcnative-boringssl-static:1.1.33.Fork21:' + tcnative_classifier

0 commit comments

Comments
 (0)