diff --git a/pom.xml b/pom.xml
index 512f7d00..a97c7891 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
fabric-sdk-java-1.0
- 1.14.0
+ 1.15.0
3.6.1
1.60
4.5.6
diff --git a/src/main/java/org/hyperledger/fabric/sdk/Channel.java b/src/main/java/org/hyperledger/fabric/sdk/Channel.java
index a408711d..b86e486a 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/Channel.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/Channel.java
@@ -139,6 +139,7 @@ public class Channel implements Serializable {
private static final long serialVersionUID = -3266164166893832538L;
private static final Log logger = LogFactory.getLog(Channel.class);
private static final boolean IS_DEBUG_LEVEL = logger.isDebugEnabled();
+ private static final boolean IS_WARN_LEVEL = logger.isWarnEnabled();
private static final boolean IS_TRACE_LEVEL = logger.isTraceEnabled();
private static final Config config = Config.getConfig();
@@ -5663,7 +5664,7 @@ boolean sweepMe() { // Sweeps DO NOT fire future. user needs to put timeout on t
final boolean ret = sweepTime < System.currentTimeMillis() || fired.get() || future.isDone();
- if (IS_DEBUG_LEVEL && ret) {
+ if (IS_WARN_LEVEL && ret) {
StringBuilder sb = new StringBuilder(10000);
sb.append("Non reporting event hubs:");
@@ -5683,11 +5684,10 @@ boolean sweepMe() { // Sweeps DO NOT fire future. user needs to put timeout on t
sep = ",";
}
- logger.debug(format("Force removing transaction listener after %d ms for transaction %s. %s" +
+ logger.warn(format("Force removing transaction listener after %d ms for transaction %s. %s" +
". sweep timeout: %b, fired: %b, future done:%b",
System.currentTimeMillis() - createTime, txID, sb.toString(),
sweepTime < System.currentTimeMillis(), fired.get(), future.isDone()));
-
}
return ret;
diff --git a/src/main/java/org/hyperledger/fabric/sdk/ChannelConfiguration.java b/src/main/java/org/hyperledger/fabric/sdk/ChannelConfiguration.java
index 189def04..4eca4bae 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/ChannelConfiguration.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/ChannelConfiguration.java
@@ -20,11 +20,19 @@
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
+
+import static java.lang.String.format;
+import static org.hyperledger.fabric.sdk.helper.Utils.toHexString;
/**
* A wrapper for the Hyperledger Channel configuration
*/
public class ChannelConfiguration {
+ private static final Log logger = LogFactory.getLog(ChannelConfiguration.class);
+ private static final boolean IS_TRACE_LEVEL = logger.isTraceEnabled();
private byte[] configBytes = null;
/**
@@ -41,9 +49,15 @@ public ChannelConfiguration() {
* @param configFile The file containing the channel configuration.
* @throws IOException
*/
- public ChannelConfiguration(File configFile) throws IOException {
- InputStream is = new FileInputStream(configFile);
- configBytes = IOUtils.toByteArray(is);
+ public ChannelConfiguration(File configFile) throws IOException, InvalidArgumentException {
+ if (configFile == null) {
+ throw new InvalidArgumentException("ChannelConfiguration configFile must be non-null");
+ }
+ logger.trace(format("Creating ChannelConfiguration from file %s", configFile.getAbsolutePath()));
+
+ try (InputStream is = new FileInputStream(configFile)) {
+ configBytes = IOUtils.toByteArray(is);
+ }
}
/**
@@ -51,7 +65,11 @@ public ChannelConfiguration(File configFile) throws IOException {
*
* @param configAsBytes the byte array containing the serialized channel configuration
*/
- public ChannelConfiguration(byte[] configAsBytes) {
+ public ChannelConfiguration(byte[] configAsBytes) throws InvalidArgumentException {
+ if (configAsBytes == null) {
+ throw new InvalidArgumentException("ChannelConfiguration configAsBytes must be non-null");
+ }
+ logger.trace("Creating ChannelConfiguration from bytes");
this.configBytes = configAsBytes;
}
@@ -60,7 +78,11 @@ public ChannelConfiguration(byte[] configAsBytes) {
*
* @param channelConfigurationAsBytes the byte array containing the serialized channel configuration
*/
- public void setChannelConfiguration(byte[] channelConfigurationAsBytes) {
+ public void setChannelConfiguration(byte[] channelConfigurationAsBytes) throws InvalidArgumentException {
+ if (channelConfigurationAsBytes == null) {
+ throw new InvalidArgumentException("ChannelConfiguration channelConfigurationAsBytes must be non-null");
+ }
+ logger.trace("Creating setChannelConfiguration from bytes");
this.configBytes = channelConfigurationAsBytes;
}
@@ -68,6 +90,11 @@ public void setChannelConfiguration(byte[] channelConfigurationAsBytes) {
* @return the channel configuration serialized per protobuf and ready for inclusion into channel configuration
*/
public byte[] getChannelConfigurationAsBytes() {
- return this.configBytes;
+ if (configBytes == null) {
+ logger.error("ChannelConfiguration configBytes is null!");
+ } else if (IS_TRACE_LEVEL) {
+ logger.trace(format("getChannelConfigurationAsBytes: %s", toHexString(configBytes)));
+ }
+ return configBytes;
}
}
diff --git a/src/main/java/org/hyperledger/fabric/sdk/UpdateChannelConfiguration.java b/src/main/java/org/hyperledger/fabric/sdk/UpdateChannelConfiguration.java
index f9504f29..69bec76d 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/UpdateChannelConfiguration.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/UpdateChannelConfiguration.java
@@ -22,11 +22,20 @@
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
+
+import static java.lang.String.format;
+import static org.hyperledger.fabric.sdk.helper.Utils.toHexString;
/**
* A wrapper for the Hyperledger Channel update configuration
*/
public class UpdateChannelConfiguration {
+ private static final Log logger = LogFactory.getLog(UpdateChannelConfiguration.class);
+ private static final boolean IS_TRACE_LEVEL = logger.isTraceEnabled();
+
private byte[] configBytes = null;
/**
@@ -43,9 +52,15 @@ public UpdateChannelConfiguration() {
* @param configFile The file containing the channel configuration.
* @throws IOException
*/
- public UpdateChannelConfiguration(File configFile) throws IOException {
- InputStream is = new FileInputStream(configFile);
- configBytes = IOUtils.toByteArray(is);
+ public UpdateChannelConfiguration(File configFile) throws IOException, InvalidArgumentException {
+ if (configFile == null) {
+ throw new InvalidArgumentException("UpdateChannelConfiguration configFile must be non-null");
+ }
+ logger.trace(format("Creating UpdateChannelConfiguration from file %s", configFile.getAbsolutePath()));
+
+ try (InputStream is = new FileInputStream(configFile)) {
+ configBytes = IOUtils.toByteArray(is);
+ }
}
/**
@@ -53,8 +68,12 @@ public UpdateChannelConfiguration(File configFile) throws IOException {
*
* @param configAsBytes the byte array containing the serialized channel configuration
*/
- public UpdateChannelConfiguration(byte[] configAsBytes) {
- this.configBytes = configAsBytes;
+ public UpdateChannelConfiguration(byte[] configAsBytes) throws InvalidArgumentException {
+ if (configAsBytes == null) {
+ throw new InvalidArgumentException("UpdateChannelConfiguration configAsBytes must be non-null");
+ }
+ logger.trace("Creating UpdateChannelConfiguration from bytes");
+ configBytes = configAsBytes;
}
/**
@@ -62,14 +81,23 @@ public UpdateChannelConfiguration(byte[] configAsBytes) {
*
* @param updateChannelConfigurationAsBytes the byte array containing the serialized channel configuration
*/
- public void setUpdateChannelConfiguration(byte[] updateChannelConfigurationAsBytes) {
- this.configBytes = updateChannelConfigurationAsBytes;
+ public void setUpdateChannelConfiguration(byte[] updateChannelConfigurationAsBytes) throws InvalidArgumentException {
+ if (updateChannelConfigurationAsBytes == null) {
+ throw new InvalidArgumentException("UpdateChannelConfiguration updateChannelConfigurationAsBytes must be non-null");
+ }
+ logger.trace("Creating setUpdateChannelConfiguration from bytes");
+ configBytes = updateChannelConfigurationAsBytes;
}
/**
* @return the channel configuration serialized per protobuf and ready for inclusion into channel configuration
*/
public byte[] getUpdateChannelConfigurationAsBytes() {
- return this.configBytes;
+ if (configBytes == null) {
+ logger.error("UpdateChannelConfiguration configBytes is null!");
+ } else if (IS_TRACE_LEVEL) {
+ logger.trace(format("getUpdateChannelConfigurationAsBytes: %s", toHexString(configBytes)));
+ }
+ return configBytes;
}
}
diff --git a/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java b/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java
index d8e27f63..00703f0b 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java
@@ -196,7 +196,7 @@ public static ByteString getSignatureHeaderAsByteString(User user, TransactionCo
Enrollment enrollment = user.getEnrollment();
String cert = enrollment.getCert();
- logger.debug(format(" User: %s Certificate:\n%s", user.getName(), cert));
+ logger.debug(format(" User: %s Certificate: %s", user.getName(), cert == null ? "null" : toHexString(cert.getBytes(UTF_8))));
if (enrollment instanceof X509Enrollment) {
if (null == suite) {
diff --git a/src/test/cirun.sh b/src/test/cirun.sh
index 238350e5..08d132c0 100755
--- a/src/test/cirun.sh
+++ b/src/test/cirun.sh
@@ -31,6 +31,8 @@ export ORG_HYPERLEDGER_FABRIC_SDKTEST_INVOKEWAITTIME=300000
export ORG_HYPERLEDGER_FABRIC_SDKTEST_DEPLOYWAITTIME=1300000
export ORG_HYPERLEDGER_FABRIC_SDKTEST_PROPOSALWAITTIME=300000
+export ORG_HYPERLEDGER_FABRIC_SDKTEST_RUNIDEMIXMTTEST=true
+
ORG_HYPERLEDGER_FABRIC_SDKTEST_VERSION=${ORG_HYPERLEDGER_FABRIC_SDKTEST_VERSION:-}
if [ "$ORG_HYPERLEDGER_FABRIC_SDKTEST_VERSION" == "1.0.0" ]; then
diff --git a/src/test/fixture/meta-infs/end2endit/META-INF/statedb/couchdb/indexes/IndexA.json b/src/test/fixture/meta-infs/end2endit/META-INF/statedb/couchdb/indexes/IndexA.json
new file mode 100644
index 00000000..03367ced
--- /dev/null
+++ b/src/test/fixture/meta-infs/end2endit/META-INF/statedb/couchdb/indexes/IndexA.json
@@ -0,0 +1,10 @@
+{
+ "ddoc": "indexADDoc",
+ "index": {
+ "fields": [
+ "a"
+ ]
+ },
+ "name": "indexA",
+ "type": "json"
+}
\ No newline at end of file
diff --git a/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/build-artifacts.sh b/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/build-artifacts.sh
deleted file mode 100755
index fe6f91cc..00000000
--- a/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/build-artifacts.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-configtxgen -outputBlock orderer.block -profile TwoOrgsOrdererGenesis_v13
-configtxgen -outputCreateChannelTx foo.tx -profile TwoOrgsChannel_v13 -channelID foo
-configtxgen -outputCreateChannelTx bar.tx -profile TwoOrgsChannel_v13 -channelID bar
diff --git a/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/configtx.yaml b/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/configtx.yaml
index 8f8e41d6..e5929ccb 100644
--- a/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/configtx.yaml
+++ b/src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/configtx.yaml
@@ -78,12 +78,6 @@ Organizations:
msptype: idemix
mspdir: crypto-config/peerOrganizations/org3.example.com
- anchorpeers:
- # anchorpeers defines the location of peers which can be used
- # for cross org gossip communication. note, this value is only
- # encoded in the genesis block in the application section context
- - host: peer0.org3.example.com
- port: 7051
- &Org2Idemix
# defaultorg defines the organization which is used in the sampleconfig
@@ -96,12 +90,6 @@ Organizations:
msptype: idemix
mspdir: crypto-config/peerOrganizations/org4.example.com
- anchorpeers:
- # anchorpeers defines the location of peers which can be used
- # for cross org gossip communication. note, this value is only
- # encoded in the genesis block in the application section context
- - host: peer0.org4.example.com
- port: 8051
################################################################################
#
# ORDERER
diff --git a/src/test/java/org/hyperledger/fabric/sdk/ChannelConfigurationTest.java b/src/test/java/org/hyperledger/fabric/sdk/ChannelConfigurationTest.java
index 9e60f016..fe7a26e0 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/ChannelConfigurationTest.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/ChannelConfigurationTest.java
@@ -22,7 +22,7 @@ public class ChannelConfigurationTest {
private static final String TEST_BYTES_2 = "00112233445566778899";
@Test
- public void testChannelConfigurationByeArray() {
+ public void testChannelConfigurationByeArray() throws Exception {
// Test empty constructor
new ChannelConfiguration();
diff --git a/src/test/java/org/hyperledger/fabric/sdk/idemix/IdemixTest.java b/src/test/java/org/hyperledger/fabric/sdk/idemix/IdemixTest.java
index 8ea21bd9..9d37086e 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/idemix/IdemixTest.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/idemix/IdemixTest.java
@@ -24,11 +24,13 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+
import org.apache.milagro.amcl.FP256BN.BIG;
import org.apache.milagro.amcl.FP256BN.ECP;
import org.apache.milagro.amcl.RAND;
import org.hyperledger.fabric.protos.idemix.Idemix;
import org.hyperledger.fabric.sdk.exception.CryptoException;
+import org.hyperledger.fabric.sdk.testutils.TestConfig;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
@@ -46,8 +48,11 @@ public class IdemixTest {
@Test
public void idemixTest() throws ExecutionException, InterruptedException {
- ExecutorService serviceSingleTask = Executors.newFixedThreadPool(THREAD_POOL);
- ExecutorService serviceMultiTask = Executors.newFixedThreadPool(THREAD_POOL);
+ if (!TestConfig.getConfig().getRunIdemixMTTest()) {
+ return;
+ }
+ ExecutorService serviceSingleTask = Executors.newFixedThreadPool(THREAD_POOL);
+ ExecutorService serviceMultiTask = Executors.newFixedThreadPool(THREAD_POOL);
// Select attribute names and generate a Idemix Setup
String[] attributeNames = {"Attr1", "Attr2", "Attr3", "Attr4", "Attr5"};
@@ -64,7 +69,7 @@ public void idemixTest() throws ExecutionException, InterruptedException {
IdemixTask taskM = new IdemixTask(setup);
results.add(serviceMultiTask.submit(taskM));
}
- for (Future f: results) {
+ for (Future f : results) {
assertTrue(f.get());
}
}
@@ -190,7 +195,7 @@ private void test() throws CryptoException {
assertFalse(signature.verify(disclosure, setup.key.getIpk(), msg, setup.attrs, 0, setup.revocationKeyPair.getPublic(), epoch));
// test signature verification with different issuer public key
- assertFalse(signature.verify(disclosure2, new IdemixIssuerKey(new String[]{"Attr1, Attr2, Attr3, Attr4, Attr5"}).getIpk(), msg, setup.attrs, 0, setup.revocationKeyPair.getPublic(), epoch));
+ assertFalse(signature.verify(disclosure2, new IdemixIssuerKey(new String[] {"Attr1, Attr2, Attr3, Attr4, Attr5"}).getIpk(), msg, setup.attrs, 0, setup.revocationKeyPair.getPublic(), epoch));
// test signature verification with different message
byte[] msg2 = {1, 1, 1};
diff --git a/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java b/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
index d7b6ce06..3611cf3b 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
@@ -62,6 +62,7 @@ public class TestConfig {
private static final String INVOKEWAITTIME = PROPBASE + "InvokeWaitTime";
private static final String DEPLOYWAITTIME = PROPBASE + "DeployWaitTime";
private static final String PROPOSALWAITTIME = PROPBASE + "ProposalWaitTime";
+ private static final String RUNIDEMIXMTTEST = PROPBASE + "RunIdemixMTTest"; // org.hyperledger.fabric.sdktest.RunIdemixMTTest ORG_HYPERLEDGER_FABRIC_SDKTEST_RUNIDEMIXMTTEST
private static final String INTEGRATIONTESTS_ORG = PROPBASE + "integrationTests.org.";
private static final Pattern orgPat = Pattern.compile("^" + Pattern.quote(INTEGRATIONTESTS_ORG) + "([^\\.]+)\\.mspid$");
@@ -120,6 +121,7 @@ private TestConfig() {
defaultProperty(INVOKEWAITTIME, "32000");
defaultProperty(DEPLOYWAITTIME, "120000");
defaultProperty(PROPOSALWAITTIME, "120000");
+ defaultProperty(RUNIDEMIXMTTEST, "false");
//////
defaultProperty(INTEGRATIONTESTS_ORG + "peerOrg1.mspid", "Org1MSP");
@@ -328,6 +330,10 @@ public long getProposalWaitTime() {
return Integer.parseInt(getProperty(PROPOSALWAITTIME));
}
+ public boolean getRunIdemixMTTest() {
+ return Boolean.valueOf(getProperty(RUNIDEMIXMTTEST));
+ }
+
public Collection getIntegrationTestsSampleOrgs() {
return Collections.unmodifiableCollection(sampleOrgs.values());
}
diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
index 8b17c14d..b157d872 100644
--- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
+++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
@@ -410,9 +410,19 @@ class ChaincodeEventCapture { //A test class to capture chaincode events
////For GO language and serving just a single user, chaincodeSource is mostly likely the users GOPATH
installProposalRequest.setChaincodeSourceLocation(Paths.get(TEST_FIXTURES_PATH, CHAIN_CODE_FILEPATH).toFile());
+
+ if (testConfig.isFabricVersionAtOrAfter("1.1")) { // Fabric 1.1 added support for META-INF in the chaincode image.
+
+ //This sets an index on the variable a in the chaincode // see http://hyperledger-fabric.readthedocs.io/en/master/couchdb_as_state_database.html#using-couchdb-from-chaincode
+ // The file IndexA.json as part of the META-INF will be packaged with the source to create the index.
+ installProposalRequest.setChaincodeMetaInfLocation(new File("src/test/fixture/meta-infs/end2endit"));
+ }
} else {
// On bar chain install from an input stream.
+ // For inputstream if indicies are desired the application needs to make sure the META-INF is provided in the stream.
+ // The SDK does not change anything in the stream.
+
if (CHAIN_CODE_LANG.equals(Type.GO_LANG)) {
installProposalRequest.setChaincodeInputStream(Util.generateTarGzInputStream(
@@ -488,29 +498,29 @@ policy OR(Org1MSP.member, Org2MSP.member) meaning 1 signature from someone in ei
successful.clear();
failed.clear();
- if (isFooChain) { //Send responses both ways with specifying peers and by using those on the channel.
- responses = channel.sendInstantiationProposal(instantiateProposalRequest, channel.getPeers());
+ if (isFooChain) { //Send responses both ways with specifying peers and by using those on the channel.
+ responses = channel.sendInstantiationProposal(instantiateProposalRequest, channel.getPeers());
+ } else {
+ responses = channel.sendInstantiationProposal(instantiateProposalRequest);
+ }
+ for (ProposalResponse response : responses) {
+ if (response.isVerified() && response.getStatus() == ProposalResponse.Status.SUCCESS) {
+ successful.add(response);
+ out("Succesful instantiate proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
} else {
- responses = channel.sendInstantiationProposal(instantiateProposalRequest);
+ failed.add(response);
}
- for (ProposalResponse response : responses) {
- if (response.isVerified() && response.getStatus() == ProposalResponse.Status.SUCCESS) {
- successful.add(response);
- out("Succesful instantiate proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
- } else {
- failed.add(response);
- }
- }
- out("Received %d instantiate proposal responses. Successful+verified: %d . Failed: %d", responses.size(), successful.size(), failed.size());
- if (failed.size() > 0) {
- for (ProposalResponse fail : failed) {
+ }
+ out("Received %d instantiate proposal responses. Successful+verified: %d . Failed: %d", responses.size(), successful.size(), failed.size());
+ if (failed.size() > 0) {
+ for (ProposalResponse fail : failed) {
- out("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + fail.getMessage() + ", on peer" + fail.getPeer());
+ out("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + fail.getMessage() + ", on peer" + fail.getPeer());
- }
- ProposalResponse first = failed.iterator().next();
- fail("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + first.getMessage() + ". Was verified:" + first.isVerified());
}
+ ProposalResponse first = failed.iterator().next();
+ fail("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + first.getMessage() + ". Was verified:" + first.isVerified());
+ }
///////////////
/// Send instantiate transaction to orderer
out("Sending instantiateTransaction to orderer with a and b set to 100 and %s respectively", "" + (200 + delta));