Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit a4ce2c4

Browse files
FABJ-487: 1.4 and 2.0 compatible test Java chaincode
The gradle plugin dependencies used for chaincode deployed to Fabric 1.4 and 2.0 are different. Change integration tests to use a suitable version of the Java sample chaincode for testing depending on which Fabric runtime version is being used. Change-Id: I6929b3cc27d141ab92c9fbcc297cbd9f91e70b32 Signed-off-by: Mark S. Lewis <mark_lewis@uk.ibm.com>
1 parent 8f236ad commit a4ce2c4

File tree

19 files changed

+279
-72
lines changed

19 files changed

+279
-72
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
plugins {
2+
id 'com.github.johnrengelman.shadow' version '2.0.3'
3+
id 'java'
4+
}
5+
6+
group 'org.hyperledger.fabric-chaincode-java'
7+
version '1.0-SNAPSHOT'
8+
9+
sourceCompatibility = 1.8
10+
11+
repositories {
12+
mavenLocal()
13+
mavenCentral()
14+
}
15+
16+
dependencies {
17+
compile group: 'org.hyperledger.fabric-chaincode-java', name: 'fabric-chaincode-shim', version: '1.+'
18+
}
19+
20+
shadowJar {
21+
baseName = 'chaincode'
22+
version = null
23+
classifier = null
24+
25+
manifest {
26+
attributes 'Main-Class': 'org.hyperledger.fabric.example.SimpleChaincode'
27+
}
28+
}

src/test/fixture/sdkintegration/javacc/sample1/settings.gradle renamed to src/test/fixture/sdkintegration/javacc/1.4/sample1/settings.gradle

File renamed without changes.

src/test/fixture/sdkintegration/javacc/sample1/src/main/java/org/hyperledger/fabric/example/SimpleChaincode.java renamed to src/test/fixture/sdkintegration/javacc/1.4/sample1/src/main/java/org/hyperledger/fabric/example/SimpleChaincode.java

File renamed without changes.

src/test/fixture/sdkintegration/javacc/sample1/build.gradle renamed to src/test/fixture/sdkintegration/javacc/2.0/sample1/build.gradle

File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rootProject.name = 'fabric-chaincode-example-gradle'
2+
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package org.hyperledger.fabric.example;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import com.google.protobuf.ByteString;
7+
import io.netty.handler.ssl.OpenSsl;
8+
import org.apache.commons.logging.Log;
9+
import org.apache.commons.logging.LogFactory;
10+
import org.hyperledger.fabric.shim.ChaincodeBase;
11+
import org.hyperledger.fabric.shim.ChaincodeStub;
12+
13+
import static java.nio.charset.StandardCharsets.UTF_8;
14+
15+
public class SimpleChaincode extends ChaincodeBase {
16+
17+
private static Log _logger = LogFactory.getLog(SimpleChaincode.class);
18+
19+
@Override
20+
public Response init(ChaincodeStub stub) {
21+
try {
22+
_logger.info("Init java simple chaincode");
23+
String func = stub.getFunction();
24+
25+
if (!func.equals("init")) {
26+
return newErrorResponse("function other than init is not supported");
27+
}
28+
List<String> args = stub.getParameters();
29+
if (args.size() != 4) {
30+
newErrorResponse("Incorrect number of arguments. Expecting 4");
31+
}
32+
// Initialize the chaincode
33+
String account1Key = args.get(0);
34+
int account1Value = Integer.parseInt(args.get(1));
35+
String account2Key = args.get(2);
36+
int account2Value = Integer.parseInt(args.get(3));
37+
38+
_logger.info(String.format("account %s, value = %s; account %s, value %s", account1Key, account1Value, account2Key, account2Value));
39+
stub.putStringState(account1Key, args.get(1));
40+
stub.putStringState(account2Key, args.get(3));
41+
42+
return newSuccessResponse();
43+
} catch (Throwable e) {
44+
return newErrorResponse(e);
45+
}
46+
}
47+
48+
@Override
49+
public Response invoke(ChaincodeStub stub) {
50+
try {
51+
_logger.info("Invoke java simple chaincode");
52+
String func = stub.getFunction();
53+
List<String> params = stub.getParameters();
54+
if (func.equals("move")) {
55+
return move(stub, params);
56+
}
57+
if (func.equals("delete")) {
58+
return delete(stub, params);
59+
}
60+
if (func.equals("query")) {
61+
return query(stub, params);
62+
}
63+
return newErrorResponse("Invalid invoke function name. Expecting one of: [\"move\", \"delete\", \"query\"]");
64+
} catch (Throwable e) {
65+
return newErrorResponse(e);
66+
}
67+
}
68+
69+
private Response move(ChaincodeStub stub, List<String> args) {
70+
if (args.size() != 3) {
71+
return newErrorResponse("Incorrect number of arguments. Expecting 3");
72+
}
73+
String accountFromKey = args.get(0);
74+
String accountToKey = args.get(1);
75+
76+
String accountFromValueStr = stub.getStringState(accountFromKey);
77+
if (accountFromValueStr == null) {
78+
return newErrorResponse(String.format("Entity %s not found", accountFromKey));
79+
}
80+
int accountFromValue = Integer.parseInt(accountFromValueStr);
81+
82+
String accountToValueStr = stub.getStringState(accountToKey);
83+
if (accountToValueStr == null) {
84+
return newErrorResponse(String.format("Entity %s not found", accountToKey));
85+
}
86+
int accountToValue = Integer.parseInt(accountToValueStr);
87+
88+
int amount = Integer.parseInt(args.get(2));
89+
90+
if (amount > accountFromValue) {
91+
return newErrorResponse(String.format("not enough money in account %s", accountFromKey));
92+
}
93+
94+
accountFromValue -= amount;
95+
accountToValue += amount;
96+
97+
_logger.info(String.format("new value of A: %s", accountFromValue));
98+
_logger.info(String.format("new value of B: %s", accountToValue));
99+
100+
stub.putStringState(accountFromKey, Integer.toString(accountFromValue));
101+
stub.putStringState(accountToKey, Integer.toString(accountToValue));
102+
103+
_logger.info("Transfer complete");
104+
105+
Map<String, byte[]> transientMap = stub.getTransient();
106+
if (null != transientMap) {
107+
if (transientMap.containsKey("event") && transientMap.get("event") != null) {
108+
stub.setEvent("event", transientMap.get("event"));
109+
}
110+
if (transientMap.containsKey("result") && transientMap.get("result") != null) {
111+
return newSuccessResponse(transientMap.get("result"));
112+
}
113+
}
114+
return newSuccessResponse();
115+
// return newSuccessResponse("invoke finished successfully", ByteString.copyFrom(accountFromKey + ": " + accountFromValue + " " + accountToKey + ": " + accountToValue, UTF_8).
116+
//
117+
// toByteArray());
118+
}
119+
120+
// Deletes an entity from state
121+
private Response delete(ChaincodeStub stub, List<String> args) {
122+
if (args.size() != 1) {
123+
return newErrorResponse("Incorrect number of arguments. Expecting 1");
124+
}
125+
String key = args.get(0);
126+
// Delete the key from the state in ledger
127+
stub.delState(key);
128+
return newSuccessResponse();
129+
}
130+
131+
// query callback representing the query of a chaincode
132+
private Response query(ChaincodeStub stub, List<String> args) {
133+
if (args.size() != 1) {
134+
return newErrorResponse("Incorrect number of arguments. Expecting name of the person to query");
135+
}
136+
String key = args.get(0);
137+
//byte[] stateBytes
138+
String val = stub.getStringState(key);
139+
if (val == null) {
140+
return newErrorResponse(String.format("Error: state for %s is null", key));
141+
}
142+
_logger.info(String.format("Query Response:\nName: %s, Amount: %s\n", key, val));
143+
return newSuccessResponse(val, ByteString.copyFrom(val, UTF_8).toByteArray());
144+
}
145+
146+
public static void main(String[] args) {
147+
System.out.println("OpenSSL avaliable: " + OpenSsl.isAvailable());
148+
new SimpleChaincode().start(args);
149+
}
150+
151+
}

src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.io.File;
1818
import java.net.MalformedURLException;
19+
import java.nio.file.Path;
1920
import java.nio.file.Paths;
2021
import java.util.ArrayList;
2122
import java.util.Collection;
@@ -74,6 +75,7 @@
7475
import static org.junit.Assert.assertFalse;
7576
import static org.junit.Assert.assertNotNull;
7677
import static org.junit.Assert.assertNull;
78+
import static org.junit.Assert.assertSame;
7779
import static org.junit.Assert.assertTrue;
7880
import static org.junit.Assert.fail;
7981

@@ -87,18 +89,16 @@ public class End2endAndBackAgainIT {
8789
private static final boolean IS_FABRIC_V10 = testConfig.isRunningAgainstFabric10();
8890
private static final String TEST_ADMIN_NAME = "admin";
8991
private static final String TESTUSER_1_NAME = "user1";
90-
private static final String TEST_FIXTURES_PATH = "src/test/fixture";
9192

9293
private static final String FOO_CHANNEL_NAME = "foo";
9394
private static final String BAR_CHANNEL_NAME = "bar";
9495
private final TestConfigHelper configHelper = new TestConfigHelper();
95-
String testTxID = null; // save the CC invoke TxID and use in queries
9696
SampleStore sampleStore;
9797
private Collection<SampleOrg> testSampleOrgs;
9898

9999
String testName = "End2endAndBackAgainIT";
100100

101-
String CHAIN_CODE_FILEPATH = "sdkintegration/gocc/sample_11";
101+
Path CHAIN_CODE_FILEPATH = IntegrationSuite.getGoChaincodePath("sample_11");
102102
String CHAIN_CODE_NAME = "example_cc_go";
103103
String CHAIN_CODE_PATH = "github.com/example_cc";
104104
String CHAIN_CODE_VERSION_11 = "11";
@@ -364,7 +364,7 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int
364364
InstallProposalRequest installProposalRequest = client.newInstallProposalRequest();
365365
installProposalRequest.setChaincodeID(chaincodeID);
366366
////For GO language and serving just a single user, chaincodeSource is mostly likely the users GOPATH
367-
installProposalRequest.setChaincodeSourceLocation(Paths.get(TEST_FIXTURES_PATH, CHAIN_CODE_FILEPATH).toFile());
367+
installProposalRequest.setChaincodeSourceLocation(CHAIN_CODE_FILEPATH.toFile());
368368
installProposalRequest.setChaincodeVersion(CHAIN_CODE_VERSION_11);
369369
installProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime());
370370
installProposalRequest.setChaincodeLanguage(CHAIN_CODE_LANG);
@@ -421,7 +421,9 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int
421421
ChaincodeEndorsementPolicy chaincodeEndorsementPolicy;
422422

423423
chaincodeEndorsementPolicy = new ChaincodeEndorsementPolicy();
424-
chaincodeEndorsementPolicy.fromYamlFile(new File(TEST_FIXTURES_PATH + "/sdkintegration/chaincodeendorsementpolicy.yaml"));
424+
Path endorsementPolicyPath = Paths.get("sdkintegration", "chaincodeendorsementpolicy.yaml");
425+
File endorsementPolicyFile = IntegrationSuite.TEST_FIXTURE_PATH.resolve(endorsementPolicyPath).toFile();
426+
chaincodeEndorsementPolicy.fromYamlFile(endorsementPolicyFile);
425427

426428
upgradeProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
427429
Map<String, byte[]> tmap = new HashMap<>();
@@ -668,8 +670,8 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
668670
}
669671

670672
//Just some sanity check tests
671-
assertTrue(newChannel == client.getChannel(name));
672-
assertTrue(client == TestUtils.getField(newChannel, "client"));
673+
assertSame(newChannel, client.getChannel(name));
674+
assertSame(client, TestUtils.getField(newChannel, "client"));
673675
assertEquals(name, newChannel.getName());
674676
assertEquals(2, newChannel.getPeers().size());
675677
assertEquals(1, newChannel.getOrderers().size());

src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainNodeIT.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package org.hyperledger.fabric.sdkintegration;
22

3-
43
import org.hyperledger.fabric.sdk.ChaincodeID;
54
import org.hyperledger.fabric.sdk.TransactionRequest.Type;
6-
import org.hyperledger.fabric.sdk.security.CryptoSuite;
75
import org.junit.Test;
86

9-
107
// This runs a version of end2endAndBackAgainIT but with Node chaincode.s
118
public class End2endAndBackAgainNodeIT extends End2endAndBackAgainIT {
129

@@ -16,7 +13,7 @@ public class End2endAndBackAgainNodeIT extends End2endAndBackAgainIT {
1613
testName = "End2endAndBackAgainNodeIT";
1714

1815
// this is relative to src/test/fixture and is where the Node chaincode source is.
19-
CHAIN_CODE_FILEPATH = "sdkintegration/nodecc/sample_11"; //override path to Node code
16+
CHAIN_CODE_FILEPATH = IntegrationSuite.getNodeChaincodePath("sample_11"); //override path to Node code
2017
CHAIN_CODE_PATH = null; //This is used only for GO.
2118
CHAIN_CODE_NAME = "example_cc_node"; // chaincode namFCAAffiliationTest.javae.
2219
CHAIN_CODE_LANG = Type.NODE; //language is Node.

src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.File;
1818
import java.io.IOException;
1919
import java.net.MalformedURLException;
20+
import java.nio.file.Path;
2021
import java.nio.file.Paths;
2122
import java.util.Collection;
2223
import java.util.Collections;
@@ -93,7 +94,6 @@ public class End2endIT {
9394

9495
private static final TestConfig testConfig = TestConfig.getConfig();
9596
static final String TEST_ADMIN_NAME = "admin";
96-
private static final String TEST_FIXTURES_PATH = "src/test/fixture";
9797

9898
private static Random random = new Random();
9999

@@ -108,7 +108,7 @@ public class End2endIT {
108108

109109
String testName = "End2endIT";
110110

111-
String CHAIN_CODE_FILEPATH = "sdkintegration/gocc/sample1";
111+
Path CHAIN_CODE_FILEPATH = IntegrationSuite.getGoChaincodePath("sample1");
112112
String CHAIN_CODE_NAME = "example_cc_go";
113113
String CHAIN_CODE_PATH = "github.com/example_cc";
114114
String CHAIN_CODE_VERSION = "1";
@@ -419,7 +419,7 @@ class ChaincodeEventCapture { //A test class to capture chaincode events
419419
// on foo chain install from directory.
420420

421421
////For GO language and serving just a single user, chaincodeSource is mostly likely the users GOPATH
422-
installProposalRequest.setChaincodeSourceLocation(Paths.get(TEST_FIXTURES_PATH, CHAIN_CODE_FILEPATH).toFile());
422+
installProposalRequest.setChaincodeSourceLocation(CHAIN_CODE_FILEPATH.toFile());
423423

424424
if (testConfig.isFabricVersionAtOrAfter("1.1")) { // Fabric 1.1 added support for META-INF in the chaincode image.
425425

@@ -434,13 +434,13 @@ class ChaincodeEventCapture { //A test class to capture chaincode events
434434
// The SDK does not change anything in the stream.
435435

436436
if (CHAIN_CODE_LANG.equals(Type.GO_LANG)) {
437-
437+
Path chaincodeSrcPath = Paths.get("src", CHAIN_CODE_PATH);
438438
installProposalRequest.setChaincodeInputStream(Util.generateTarGzInputStream(
439-
(Paths.get(TEST_FIXTURES_PATH, CHAIN_CODE_FILEPATH, "src", CHAIN_CODE_PATH).toFile()),
440-
Paths.get("src", CHAIN_CODE_PATH).toString()));
439+
CHAIN_CODE_FILEPATH.resolve(chaincodeSrcPath).toFile(),
440+
chaincodeSrcPath.toString()));
441441
} else {
442442
installProposalRequest.setChaincodeInputStream(Util.generateTarGzInputStream(
443-
(Paths.get(TEST_FIXTURES_PATH, CHAIN_CODE_FILEPATH).toFile()),
443+
CHAIN_CODE_FILEPATH.toFile(),
444444
"src"));
445445
}
446446
}
@@ -504,7 +504,9 @@ policy OR(Org1MSP.member, Org2MSP.member) meaning 1 signature from someone in ei
504504
See README.md Chaincode endorsement policies section for more details.
505505
*/
506506
ChaincodeEndorsementPolicy chaincodeEndorsementPolicy = new ChaincodeEndorsementPolicy();
507-
chaincodeEndorsementPolicy.fromYamlFile(new File(TEST_FIXTURES_PATH + "/sdkintegration/chaincodeendorsementpolicy.yaml"));
507+
Path endorsementPolicyPath = Paths.get("sdkintegration", "chaincodeendorsementpolicy.yaml");
508+
File endorsementPolicyFile = IntegrationSuite.TEST_FIXTURE_PATH.resolve(endorsementPolicyPath).toFile();
509+
chaincodeEndorsementPolicy.fromYamlFile(endorsementPolicyFile);
508510
instantiateProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
509511

510512
out("Sending instantiateProposalRequest to all peers with arguments: a and b set to 100 and %s respectively", String.valueOf(200 + delta));
@@ -840,8 +842,9 @@ Channel constructChannel(String name, HFClient client, SampleOrg sampleOrg) thro
840842
Orderer anOrderer = orderers.iterator().next();
841843
orderers.remove(anOrderer);
842844

843-
String path = TEST_FIXTURES_PATH + "/sdkintegration/e2e-2Orgs/" + testConfig.getFabricConfigGenVers() + "/" + name + ".tx";
844-
ChannelConfiguration channelConfiguration = new ChannelConfiguration(new File(path));
845+
Path configTxPath = Paths.get("sdkintegration", "e2e-2Orgs", testConfig.getFabricConfigGenVers(), name + ".tx");
846+
File configTxFile = IntegrationSuite.TEST_FIXTURE_PATH.resolve(configTxPath).toFile();
847+
ChannelConfiguration channelConfiguration = new ChannelConfiguration(configTxFile);
845848

846849
//Create channel that has only one signer that is this orgs peer admin. If channel creation policy needed more signature they would need to be added too.
847850
Channel newChannel = client.newChannel(name, anOrderer, channelConfiguration, client.getChannelConfigurationSignature(channelConfiguration, peerAdmin));

src/test/java/org/hyperledger/fabric/sdkintegration/End2endIdemixIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
public class End2endIdemixIT extends End2endIT {
3333

3434
{
35-
CHAIN_CODE_FILEPATH = "sdkintegration/gocc/sampleIdemix";
35+
CHAIN_CODE_FILEPATH = IntegrationSuite.getGoChaincodePath("sampleIdemix");
3636
testName = "End2endIdemixIT"; //Just print out what test is really running.
3737
CHAIN_CODE_NAME = "idemix_example_go";
3838
CHAIN_CODE_LANG = TransactionRequest.Type.GO_LANG;

0 commit comments

Comments
 (0)