From 457ac6197f120d0759d1f31784afa46eba7f17c5 Mon Sep 17 00:00:00 2001 From: rickr Date: Mon, 22 May 2017 08:51:08 -0400 Subject: [PATCH] FAB-4088 Determine which proposals are consistent Utility to determine which proposals are consistent Move ChainUtils and rename to SDKUtils so it with other public classes. Rename SDKUtils to just Utils for internal usage. Fix typo tansaction to transaction Change-Id: I0d39dc2a89dc4c57ffee035d0ec3a73b8c32b78d Signed-off-by: rickr --- .../hyperledger/fabric/sdk/BlockEvent.java | 8 +- .../org/hyperledger/fabric/sdk/BlockInfo.java | 18 ++- .../org/hyperledger/fabric/sdk/Channel.java | 16 +-- .../org/hyperledger/fabric/sdk/Endpoint.java | 6 +- .../org/hyperledger/fabric/sdk/EventHub.java | 2 +- .../org/hyperledger/fabric/sdk/HFClient.java | 10 +- .../org/hyperledger/fabric/sdk/Orderer.java | 2 +- .../java/org/hyperledger/fabric/sdk/Peer.java | 2 +- .../fabric/sdk/ProposalResponse.java | 2 +- .../org/hyperledger/fabric/sdk/SDKUtils.java | 104 ++++++++++++++++++ .../fabric/sdk/helper/ChainUtils.java | 63 ----------- .../sdk/helper/{SDKUtil.java => Utils.java} | 8 +- .../fabric/sdk/security/CryptoPrimitives.java | 10 +- .../transaction/InstallProposalBuilder.java | 6 +- .../sdk/transaction/ProposalBuilder.java | 2 +- .../fabric/sdk/transaction/ProtoUtils.java | 4 +- .../sdk/transaction/TransactionContext.java | 6 +- .../hyperledger/fabric_ca/sdk/HFCAClient.java | 16 +-- .../fabric_ca/sdk/RevocationRequest.java | 2 +- .../sdk/{SDKUtilTest.java => UtilsTest.java} | 16 +-- .../fabric/sdk/testutils/TestConfig.java | 4 +- .../sdkintegration/End2endAndBackAgainIT.java | 28 ++++- .../fabric/sdkintegration/End2endIT.java | 30 +++-- .../fabric/sdkintegration/Util.java | 4 +- 24 files changed, 220 insertions(+), 149 deletions(-) create mode 100644 src/main/java/org/hyperledger/fabric/sdk/SDKUtils.java delete mode 100644 src/main/java/org/hyperledger/fabric/sdk/helper/ChainUtils.java rename src/main/java/org/hyperledger/fabric/sdk/helper/{SDKUtil.java => Utils.java} (97%) rename src/test/java/org/hyperledger/fabric/sdk/{SDKUtilTest.java => UtilsTest.java} (78%) diff --git a/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java b/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java index f54802f9..c781ca13 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java +++ b/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java @@ -65,12 +65,12 @@ public Event getEvent() { TransactionEvent getTransactionEvent(int index) throws InvalidProtocolBufferException { - return new TransactionEvent((TansactionEnvelopeInfo) getEnvelopeInfo(index), index); + return new TransactionEvent((TransactionEnvelopeInfo) getEnvelopeInfo(index), index); } - public class TransactionEvent extends BlockInfo.TansactionEnvelopeInfo { - TransactionEvent(TansactionEnvelopeInfo tansactionEnvelopeInfo, int index) { - super(tansactionEnvelopeInfo.getTransactionDeserializer(), index); + public class TransactionEvent extends TransactionEnvelopeInfo { + TransactionEvent(TransactionEnvelopeInfo transactionEnvelopeInfo, int index) { + super(transactionEnvelopeInfo.getTransactionDeserializer(), index); } EventHub getEventHub() { diff --git a/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java b/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java index 11db5489..21d11fb9 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java +++ b/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java @@ -38,7 +38,6 @@ public class BlockInfo { this.block = new BlockDeserializer(block); } - public String getChannelId() throws InvalidProtocolBufferException { return getEnvelopeInfo(0).getChannelId(); @@ -67,7 +66,7 @@ public byte[] getDataHash() { } /** - * @return the {@link Block} tansaction metadata value + * @return the {@link Block} transaction metadata value */ public byte[] getTransActionsMetaData() { @@ -99,7 +98,7 @@ public int getEnvelopCount() { // * @throws InvalidProtocolBufferException // */ -// public TansactionEnvelopeInfo getEnvelopeInfo(int index) throws InvalidProtocolBufferException { +// public TransactionEnvelopeInfo getEnvelopeInfo(int index) throws InvalidProtocolBufferException { // // try { // // block.getData(0).getEnvelope().getSignature(); @@ -108,7 +107,7 @@ public int getEnvelopCount() { // // final PayloadDeserializer payload = block.getData(index).getPayload(); // -// return new TansactionEnvelopeInfo(null, payload.getHeader()); +// return new TransactionEnvelopeInfo(null, payload.getHeader()); // } catch (InvalidProtocolBufferRuntimeException e) { // throw (InvalidProtocolBufferException) e.getCause(); // } @@ -161,10 +160,9 @@ public boolean isValid() { * @return the validation code of this Transaction (enumeration TxValidationCode in Transaction.proto) */ public byte getValidationCode() { - return envelopeDeserializer.validationCode(); + return envelopeDeserializer.validationCode(); } - public EnvelopeType getType() { switch (headerDeserializer.getChannelHeader().getType()) { @@ -190,7 +188,7 @@ public EnvelopeInfo getEnvelopeInfo(int blockIndex) throws InvalidProtocolBuffer switch (ed.getType()) { case 3: - ret = new TansactionEnvelopeInfo((EndorserTransactionEnvDeserializer) ed, blockIndex); + ret = new TransactionEnvelopeInfo((EndorserTransactionEnvDeserializer) ed, blockIndex); break; default: //just assume base properties. ret = new EnvelopeInfo(ed, blockIndex); @@ -210,7 +208,7 @@ public Iterable getEnvelopeInfos() { return new TransactionInfoIterable(); } - public class TansactionEnvelopeInfo extends EnvelopeInfo { + public class TransactionEnvelopeInfo extends EnvelopeInfo { EndorserTransactionEnvDeserializer getTransactionDeserializer() { return transactionDeserializer; @@ -218,9 +216,7 @@ EndorserTransactionEnvDeserializer getTransactionDeserializer() { protected final EndorserTransactionEnvDeserializer transactionDeserializer; - - - public TansactionEnvelopeInfo(EndorserTransactionEnvDeserializer transactionDeserializer, int blockIndex) { + public TransactionEnvelopeInfo(EndorserTransactionEnvDeserializer transactionDeserializer, int blockIndex) { super(transactionDeserializer, blockIndex); this.transactionDeserializer = transactionDeserializer; diff --git a/src/main/java/org/hyperledger/fabric/sdk/Channel.java b/src/main/java/org/hyperledger/fabric/sdk/Channel.java index a92808f9..cc35c37c 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Channel.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Channel.java @@ -86,7 +86,7 @@ import org.hyperledger.fabric.sdk.exception.TransactionEventException; import org.hyperledger.fabric.sdk.exception.TransactionException; import org.hyperledger.fabric.sdk.helper.Config; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdk.security.CryptoSuite; import org.hyperledger.fabric.sdk.transaction.InstallProposalBuilder; import org.hyperledger.fabric.sdk.transaction.InstantiateProposalBuilder; @@ -107,8 +107,8 @@ import static org.hyperledger.fabric.protos.common.Configtx.ConfigValue; import static org.hyperledger.fabric.protos.common.Policies.SignaturePolicy; import static org.hyperledger.fabric.protos.common.Policies.SignaturePolicyEnvelope; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.checkGrpcUrl; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.toHexString; +import static org.hyperledger.fabric.sdk.helper.Utils.checkGrpcUrl; +import static org.hyperledger.fabric.sdk.helper.Utils.toHexString; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.createChannelHeader; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.getCurrentFabricTimestamp; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.getSignatureHeaderAsByteString; @@ -298,7 +298,7 @@ public boolean isInitialized() { name = SYSTEM_CHANNEL_NAME;///It's special ! initialized = true; } else { - if (SDKUtil.isNullOrEmpty(name)) { + if (Utils.isNullOrEmpty(name)) { throw new InvalidArgumentException("Channel name is invalid can not be null or empty."); } } @@ -355,7 +355,7 @@ public Channel addPeer(Peer peer) throws InvalidArgumentException { if (null == peer) { throw new InvalidArgumentException("Peer is invalid can not be null."); } - if (SDKUtil.isNullOrEmpty(peer.getName())) { + if (Utils.isNullOrEmpty(peer.getName())) { throw new InvalidArgumentException("Peer added to channel has no name."); } @@ -586,7 +586,7 @@ public Channel initialize() throws InvalidArgumentException, TransactionExceptio throw new InvalidArgumentException("Channel needs at least one peer."); } - if (SDKUtil.isNullOrEmpty(name)) { + if (Utils.isNullOrEmpty(name)) { throw new InvalidArgumentException("Can not initialize Channel without a valid name."); @@ -710,7 +710,7 @@ private Block getGenesisBlock(Orderer order) throws TransactionException { SignatureHeader deliverSignatureHeader = SignatureHeader.newBuilder() .setCreator(identity.toByteString()) - .setNonce(ByteString.copyFrom(SDKUtil.generateNonce())) + .setNonce(ByteString.copyFrom(Utils.generateNonce())) .build(); Header deliverHeader = Header.newBuilder() @@ -2550,7 +2550,7 @@ public String getHandle() { BL(BlockListener listener) { - handle = SDKUtil.generateUUID(); + handle = Utils.generateUUID(); logger.debug(format("Channel %s blockListener %s starting", name, handle)); this.listener = listener; diff --git a/src/main/java/org/hyperledger/fabric/sdk/Endpoint.java b/src/main/java/org/hyperledger/fabric/sdk/Endpoint.java index 6af35302..f6bc017c 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Endpoint.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Endpoint.java @@ -45,10 +45,10 @@ import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdk.security.CryptoPrimitives; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.parseGrpcUrl; +import static org.hyperledger.fabric.sdk.helper.Utils.parseGrpcUrl; class Endpoint { private static final Log logger = LogFactory.getLog(Endpoint.class); @@ -133,7 +133,7 @@ class Endpoint { .usePlaintext(true); addNettyBuilderProps(channelBuilder, properties); } else if (protocol.equalsIgnoreCase("grpcs")) { - if (SDKUtil.isNullOrEmpty(pem)) { + if (Utils.isNullOrEmpty(pem)) { // use root certificate this.channelBuilder = ManagedChannelBuilder.forAddress(addr, port); addNettyBuilderProps(channelBuilder, properties); diff --git a/src/main/java/org/hyperledger/fabric/sdk/EventHub.java b/src/main/java/org/hyperledger/fabric/sdk/EventHub.java index e05e4e53..d6a3334e 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/EventHub.java +++ b/src/main/java/org/hyperledger/fabric/sdk/EventHub.java @@ -35,7 +35,7 @@ import org.hyperledger.fabric.sdk.transaction.TransactionContext; import static java.lang.String.format; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.checkGrpcUrl; +import static org.hyperledger.fabric.sdk.helper.Utils.checkGrpcUrl; /** * Class to manage fabric events. diff --git a/src/main/java/org/hyperledger/fabric/sdk/HFClient.java b/src/main/java/org/hyperledger/fabric/sdk/HFClient.java index a2a08452..833b361d 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/HFClient.java +++ b/src/main/java/org/hyperledger/fabric/sdk/HFClient.java @@ -32,7 +32,7 @@ import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; import org.hyperledger.fabric.sdk.exception.ProposalException; import org.hyperledger.fabric.sdk.exception.TransactionException; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdk.security.CryptoSuite; import static java.lang.String.format; @@ -244,7 +244,7 @@ public void setUserContext(User userContext) throws InvalidArgumentException { throw new InvalidArgumentException("setUserContext is null"); } final String userName = userContext.getName(); - if (SDKUtil.isNullOrEmpty(userName)) { + if (Utils.isNullOrEmpty(userName)) { throw new InvalidArgumentException("setUserContext user's name is missing"); } @@ -253,15 +253,15 @@ public void setUserContext(User userContext) throws InvalidArgumentException { throw new InvalidArgumentException(format("setUserContext for user %s has no Enrollment set", userName)); } - if (SDKUtil.isNullOrEmpty(userContext.getMSPID())) { + if (Utils.isNullOrEmpty(userContext.getMSPID())) { throw new InvalidArgumentException(format("setUserContext for user %s has user's MSPID is missing", userName)); } - if (SDKUtil.isNullOrEmpty(userContext.getName())) { + if (Utils.isNullOrEmpty(userContext.getName())) { throw new InvalidArgumentException("setUserContext user's name is missing"); } - if (SDKUtil.isNullOrEmpty(enrollment.getCert())) { + if (Utils.isNullOrEmpty(enrollment.getCert())) { throw new InvalidArgumentException(format("setUserContext for user %s Enrollment missing user certificate.", userName)); } if (null == enrollment.getKey()) { diff --git a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java index 547692b2..c11baf59 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java @@ -26,7 +26,7 @@ import org.hyperledger.fabric.sdk.exception.TransactionException; import static java.lang.String.format; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.checkGrpcUrl; +import static org.hyperledger.fabric.sdk.helper.Utils.checkGrpcUrl; /** * The Orderer class represents a orderer to which SDK sends deploy, invoke, or query requests. diff --git a/src/main/java/org/hyperledger/fabric/sdk/Peer.java b/src/main/java/org/hyperledger/fabric/sdk/Peer.java index 2d5517a8..5e26d562 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Peer.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Peer.java @@ -27,7 +27,7 @@ import org.hyperledger.fabric.sdk.exception.PeerException; import static java.lang.String.format; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.checkGrpcUrl; +import static org.hyperledger.fabric.sdk.helper.Utils.checkGrpcUrl; /** * The Peer class represents a peer to which SDK sends deploy, or query proposals requests. diff --git a/src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java b/src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java index ef07643f..b1ee51bb 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java +++ b/src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java @@ -40,7 +40,7 @@ public class ProposalResponse extends ChaincodeResponse { } - private ProposalResponsePayloadDeserializer getProposalResponsePayloadDeserializer() throws InvalidArgumentException { + public ProposalResponsePayloadDeserializer getProposalResponsePayloadDeserializer() throws InvalidArgumentException { ProposalResponsePayloadDeserializer ret = null; if (proposalResponsePayload != null) { diff --git a/src/main/java/org/hyperledger/fabric/sdk/SDKUtils.java b/src/main/java/org/hyperledger/fabric/sdk/SDKUtils.java new file mode 100644 index 00000000..492146d7 --- /dev/null +++ b/src/main/java/org/hyperledger/fabric/sdk/SDKUtils.java @@ -0,0 +1,104 @@ +/* + * + * Copyright 2016,2017 DTCC, Fujitsu Australia Software Technology, IBM - All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.hyperledger.fabric.sdk; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import com.google.protobuf.ByteString; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequenceGenerator; +import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; +import org.hyperledger.fabric.sdk.security.CryptoSuite; + +public class SDKUtils { + + public static CryptoSuite suite = null; + + /** + * used asn1 and get hash + * + * @param blockNumber + * @param previousHash + * @param dataHash + * @return byte[] + * @throws IOException + * @throws InvalidArgumentException + */ + public static byte[] calculateBlockHash(long blockNumber, byte[] previousHash, byte[] dataHash) throws IOException, InvalidArgumentException { + + if (previousHash == null) { + throw new InvalidArgumentException("previousHash parameter is null."); + } + if (dataHash == null) { + throw new InvalidArgumentException("dataHash parameter is null."); + } + + if (null == suite) { + suite = CryptoSuite.Factory.getCryptoSuite(); + } + + ByteArrayOutputStream s = new ByteArrayOutputStream(); + DERSequenceGenerator seq = new DERSequenceGenerator(s); + seq.addObject(new ASN1Integer(blockNumber)); + seq.addObject(new DEROctetString(previousHash)); + seq.addObject(new DEROctetString(dataHash)); + seq.close(); + return suite.hash(s.toByteArray()); + + } + + /** + * Check that the proposals all have consistent read write sets + * + * @param proposalResponses + * @return A Collection of sets where each set has consistent proposals. + * @throws InvalidArgumentException + */ + + public static Collection> getProposalConsistencySets(Collection proposalResponses) throws InvalidArgumentException { + + if (proposalResponses == null) { + throw new InvalidArgumentException("proposalResponses collection is null"); + } + + if (proposalResponses.isEmpty()) { + throw new InvalidArgumentException("proposalResponses collection is empty"); + } + + HashMap> ret = new HashMap<>(); + + for (ProposalResponse proposalResponse : proposalResponses) { + + ByteString rwsetByteString = proposalResponse.getProposalResponsePayloadDeserializer() + .getExtension().getChaincodeAction().getResults(); + + Set set = ret.computeIfAbsent(rwsetByteString, k -> new HashSet<>()); + + set.add(proposalResponse); + + } + + return ret.values(); + + } +} diff --git a/src/main/java/org/hyperledger/fabric/sdk/helper/ChainUtils.java b/src/main/java/org/hyperledger/fabric/sdk/helper/ChainUtils.java deleted file mode 100644 index 42e85ff9..00000000 --- a/src/main/java/org/hyperledger/fabric/sdk/helper/ChainUtils.java +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright DTCC 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.hyperledger.fabric.sdk.helper; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DERSequenceGenerator; -import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; -import org.hyperledger.fabric.sdk.security.CryptoSuite; - - -public class ChainUtils { - - public static CryptoSuite suite = null; - /** - * used asn1 and get hash - * @param blockNumber - * @param previousHash - * @param dataHash - * @return byte[] - * @throws IOException - * @throws InvalidArgumentException - */ - public static byte[] calculateBlockHash(long blockNumber, byte[] previousHash, byte[] dataHash) throws IOException, InvalidArgumentException{ - - if (previousHash == null) { - throw new InvalidArgumentException("previousHash parameter is null."); - } - if (dataHash == null) { - throw new InvalidArgumentException("dataHash parameter is null."); - } - - if(null == suite){ - suite = CryptoSuite.Factory.getCryptoSuite(); - } - - ByteArrayOutputStream s = new ByteArrayOutputStream(); - DERSequenceGenerator seq = new DERSequenceGenerator(s); - seq.addObject(new ASN1Integer(blockNumber)); - seq.addObject(new DEROctetString(previousHash)); - seq.addObject(new DEROctetString(dataHash)); - seq.close(); - return suite.hash(s.toByteArray()); - - } -} diff --git a/src/main/java/org/hyperledger/fabric/sdk/helper/SDKUtil.java b/src/main/java/org/hyperledger/fabric/sdk/helper/Utils.java similarity index 97% rename from src/main/java/org/hyperledger/fabric/sdk/helper/SDKUtil.java rename to src/main/java/org/hyperledger/fabric/sdk/helper/Utils.java index b30b386c..c407893e 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/helper/SDKUtil.java +++ b/src/main/java/org/hyperledger/fabric/sdk/helper/Utils.java @@ -54,8 +54,8 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.commons.codec.binary.Hex.encodeHexString; -public class SDKUtil { - private static final Log logger = LogFactory.getLog(SDKUtil.class); +public class Utils { + private static final Log logger = LogFactory.getLog(Utils.class); private static final Config confg = Config.getConfig(); private static final int maxLogStringLength = confg.maxLogStringLength(); @@ -156,7 +156,7 @@ public static byte[] generateTarGz(File src, String pathPrefix) throws IOExcepti String relativePath = childPath.substring((sourcePath.length() + 1), childPath.length()); if (pathPrefix != null) { - relativePath = SDKUtil.combinePaths(pathPrefix, relativePath); + relativePath = Utils.combinePaths(pathPrefix, relativePath); } relativePath = FilenameUtils.separatorsToUnix(relativePath); @@ -266,7 +266,7 @@ public static String combinePaths(String first, String... other) { * @throws IOException */ public static byte[] readFileFromClasspath(String fileName) throws IOException { - InputStream is = SDKUtil.class.getClassLoader().getResourceAsStream(fileName); + InputStream is = Utils.class.getClassLoader().getResourceAsStream(fileName); byte[] data = ByteStreams.toByteArray(is); try { is.close(); diff --git a/src/main/java/org/hyperledger/fabric/sdk/security/CryptoPrimitives.java b/src/main/java/org/hyperledger/fabric/sdk/security/CryptoPrimitives.java index a283bbd8..cf0f5959 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/security/CryptoPrimitives.java +++ b/src/main/java/org/hyperledger/fabric/sdk/security/CryptoPrimitives.java @@ -105,7 +105,7 @@ import org.hyperledger.fabric.sdk.exception.CryptoException; import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; import org.hyperledger.fabric.sdk.helper.Config; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import static java.nio.charset.StandardCharsets.UTF_8; @@ -189,8 +189,9 @@ public Certificate bytesToCertificate(byte[] certBytes) throws CryptoException { public boolean verify(byte[] plainText, byte[] signature, byte[] pemCertificate) throws CryptoException { boolean isVerified = false; - if (plainText == null || signature == null || pemCertificate == null) + if (plainText == null || signature == null || pemCertificate == null) { return false; + } if (config.extraLogLevel(10)) { @@ -259,8 +260,9 @@ private void createTrustStore() throws CryptoException { */ public void setTrustStore(KeyStore keyStore) throws InvalidArgumentException { - if (keyStore == null) + if (keyStore == null) { throw new InvalidArgumentException("Need to specify a java.security.KeyStore input parameter"); + } trustStore = keyStore; } @@ -474,7 +476,7 @@ public String getHashAlgorithm() { } public void setHashAlgorithm(String algorithm) throws InvalidArgumentException { - if (SDKUtil.isNullOrEmpty(algorithm) + if (Utils.isNullOrEmpty(algorithm) || !(algorithm.equalsIgnoreCase("SHA2") || algorithm.equalsIgnoreCase("SHA3"))) { throw new InvalidArgumentException("Illegal Hash function family: " + this.hashAlgorithm + " - must be either SHA2 or SHA3"); diff --git a/src/main/java/org/hyperledger/fabric/sdk/transaction/InstallProposalBuilder.java b/src/main/java/org/hyperledger/fabric/sdk/transaction/InstallProposalBuilder.java index 1b3a631e..9d55f44f 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/transaction/InstallProposalBuilder.java +++ b/src/main/java/org/hyperledger/fabric/sdk/transaction/InstallProposalBuilder.java @@ -30,7 +30,7 @@ import org.hyperledger.fabric.protos.peer.FabricProposal; import org.hyperledger.fabric.sdk.TransactionRequest; import org.hyperledger.fabric.sdk.exception.ProposalException; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import static java.lang.String.format; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.createDeploymentSpec; @@ -106,7 +106,7 @@ private void createNetModeTransaction() throws Exception { logger.debug("createNetModeTransaction"); // Verify that chaincodePath is being passed - if (SDKUtil.isNullOrEmpty(chaincodePath)) { + if (Utils.isNullOrEmpty(chaincodePath)) { throw new IllegalArgumentException("Missing chaincodePath in InstallRequest"); } if (null == chaincodeSource && chaincodeInputStream == null) { @@ -165,7 +165,7 @@ private void createNetModeTransaction() throws Exception { chaincodeID, dplang, projectSourceDir.getAbsolutePath(), targetPathPrefix, chaincodePath)); // generate chaincode source tar - data = SDKUtil.generateTarGz(projectSourceDir, targetPathPrefix); + data = Utils.generateTarGz(projectSourceDir, targetPathPrefix); } else { logger.info(format("Installing '%s' %s chaincode chaincodePath:'%s' from input stream", diff --git a/src/main/java/org/hyperledger/fabric/sdk/transaction/ProposalBuilder.java b/src/main/java/org/hyperledger/fabric/sdk/transaction/ProposalBuilder.java index 0638d618..492eb757 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/transaction/ProposalBuilder.java +++ b/src/main/java/org/hyperledger/fabric/sdk/transaction/ProposalBuilder.java @@ -38,7 +38,7 @@ import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.logString; +import static org.hyperledger.fabric.sdk.helper.Utils.logString; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.createChannelHeader; import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.getSignatureHeaderAsByteString; 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 45658bec..85420e25 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java +++ b/src/main/java/org/hyperledger/fabric/sdk/transaction/ProtoUtils.java @@ -38,8 +38,8 @@ import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.logString; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.toHexString; +import static org.hyperledger.fabric.sdk.helper.Utils.logString; +import static org.hyperledger.fabric.sdk.helper.Utils.toHexString; public class ProtoUtils { diff --git a/src/main/java/org/hyperledger/fabric/sdk/transaction/TransactionContext.java b/src/main/java/org/hyperledger/fabric/sdk/transaction/TransactionContext.java index bd7186d1..d1f02af7 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/transaction/TransactionContext.java +++ b/src/main/java/org/hyperledger/fabric/sdk/transaction/TransactionContext.java @@ -32,7 +32,7 @@ import org.hyperledger.fabric.sdk.User; import org.hyperledger.fabric.sdk.exception.CryptoException; import org.hyperledger.fabric.sdk.helper.Config; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdk.security.CryptoSuite; /** @@ -43,7 +43,7 @@ public class TransactionContext { private static final Config config = Config.getConfig(); private static final Log logger = LogFactory.getLog(TransactionContext.class); //TODO right now the server does not care need to figure out - private final ByteString nonce = ByteString.copyFrom(SDKUtil.generateNonce()); + private final ByteString nonce = ByteString.copyFrom(Utils.generateNonce()); private boolean verify = true; @@ -80,7 +80,7 @@ public TransactionContext(Channel channel, User user, CryptoSuite cryptoPrimitiv byte[] txh = cryptoPrimitives.hash(comp.toByteArray()); // txID = Hex.encodeHexString(txh); - txID = new String(SDKUtil.toHexString(txh)); + txID = new String(Utils.toHexString(txh)); } diff --git a/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java b/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java index dc463916..349f801c 100644 --- a/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java +++ b/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java @@ -83,7 +83,7 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.hyperledger.fabric.sdk.Enrollment; import org.hyperledger.fabric.sdk.User; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdk.security.CryptoPrimitives; import org.hyperledger.fabric.sdk.security.CryptoSuite; import org.hyperledger.fabric_ca.sdk.exception.EnrollmentException; @@ -150,20 +150,20 @@ public class HFCAClient { } final String host = purl.getHost(); - if (SDKUtil.isNullOrEmpty(host)) { + if (Utils.isNullOrEmpty(host)) { throw new IllegalArgumentException("HFCAClient url needs host"); } final String path = purl.getPath(); - if (!SDKUtil.isNullOrEmpty(path)) { + if (!Utils.isNullOrEmpty(path)) { throw new IllegalArgumentException("HFCAClient url does not support path portion in url remove path: '" + path + "'."); } final String query = purl.getQuery(); - if (!SDKUtil.isNullOrEmpty(query)) { + if (!Utils.isNullOrEmpty(query)) { throw new IllegalArgumentException("HFCAClient url does not support query portion in url remove query: '" + query + "'."); } @@ -217,7 +217,7 @@ public CryptoSuite getCryptoSuite() { public String register(RegistrationRequest req, User registrar) throws RegistrationException, InvalidArgumentException { - if (SDKUtil.isNullOrEmpty(req.getEnrollmentID())) { + if (Utils.isNullOrEmpty(req.getEnrollmentID())) { throw new InvalidArgumentException("EntrollmentID cannot be null or empty"); } @@ -276,10 +276,10 @@ public Enrollment enroll(String user, String secret, EnrollmentRequest req) thro logger.debug(format("url:%s enroll user: %s", url, user)); - if (SDKUtil.isNullOrEmpty(user)) { + if (Utils.isNullOrEmpty(user)) { throw new InvalidArgumentException("enrollment user is not set"); } - if (SDKUtil.isNullOrEmpty(secret)) { + if (Utils.isNullOrEmpty(secret)) { throw new InvalidArgumentException("enrollment secret is not set"); } @@ -497,7 +497,7 @@ public void revoke(User revoker, String revokee, String reason) throws Revocatio logger.debug(format("revoke revoker: %s, revokee: %s, reason: %s", revoker, revokee, reason)); - if (SDKUtil.isNullOrEmpty(revokee)) { + if (Utils.isNullOrEmpty(revokee)) { throw new InvalidArgumentException("revokee user is not set"); } if (revoker == null) { diff --git a/src/main/java/org/hyperledger/fabric_ca/sdk/RevocationRequest.java b/src/main/java/org/hyperledger/fabric_ca/sdk/RevocationRequest.java index 19c299f5..1213881f 100644 --- a/src/main/java/org/hyperledger/fabric_ca/sdk/RevocationRequest.java +++ b/src/main/java/org/hyperledger/fabric_ca/sdk/RevocationRequest.java @@ -22,7 +22,7 @@ import javax.json.JsonObjectBuilder; import javax.json.JsonWriter; -import static org.hyperledger.fabric.sdk.helper.SDKUtil.isNullOrEmpty; +import static org.hyperledger.fabric.sdk.helper.Utils.isNullOrEmpty; /** * A RevocationRequest defines the attributes required to revoke credentials with member service. diff --git a/src/test/java/org/hyperledger/fabric/sdk/SDKUtilTest.java b/src/test/java/org/hyperledger/fabric/sdk/UtilsTest.java similarity index 78% rename from src/test/java/org/hyperledger/fabric/sdk/SDKUtilTest.java rename to src/test/java/org/hyperledger/fabric/sdk/UtilsTest.java index 06bd9f2c..f116b558 100644 --- a/src/test/java/org/hyperledger/fabric/sdk/SDKUtilTest.java +++ b/src/test/java/org/hyperledger/fabric/sdk/UtilsTest.java @@ -21,35 +21,35 @@ import org.bouncycastle.crypto.digests.SHA3Digest; import org.bouncycastle.util.encoders.Hex; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.junit.Assert; -import org.junit.Test; import org.junit.Ignore; +import org.junit.Test; import static java.nio.charset.StandardCharsets.UTF_8; @Ignore -public class SDKUtilTest { +public class UtilsTest { @Test public void testGenerateParameterHash() { List args = new ArrayList<>(); args.add("a"); args.add("b"); - String hash = SDKUtil.generateParameterHash("mypath", "myfunc", args); - Assert.assertEquals(Hex.toHexString(SDKUtil.hash("mypathmyfuncab".getBytes(UTF_8), new SHA3Digest())), hash); + String hash = Utils.generateParameterHash("mypath", "myfunc", args); + Assert.assertEquals(Hex.toHexString(Utils.hash("mypathmyfuncab".getBytes(UTF_8), new SHA3Digest())), hash); } @Test @Ignore //TODO NEED to bring back ? public void testGenerateDirectoryHash() throws IOException { // valid hash - String hash = SDKUtil.generateDirectoryHash(System.getenv("GOPATH"), "/src/github.com/hyperledger/fabric/examples/chaincode/java/Example", ""); + String hash = Utils.generateDirectoryHash(System.getenv("GOPATH"), "/src/github.com/hyperledger/fabric/examples/chaincode/java/Example", ""); Assert.assertEquals("3c08029b52176eacf802dee93129a9f1fd115008950e1bb968465dcd51bbbb9d", hash); // non-existing directory try { - SDKUtil.generateDirectoryHash(null, "/src/github.com/hyperledger/fabric/examples/chaincode/java/Example", ""); + Utils.generateDirectoryHash(null, "/src/github.com/hyperledger/fabric/examples/chaincode/java/Example", ""); Assert.fail("Should have failed as the directory does not exist"); } catch(IOException iex) { Assert.assertEquals(String.format("The chaincode path \"%s\" is invalid", Paths.get("/src/github.com/hyperledger/fabric/examples/chaincode/java/Example")), iex.getMessage()); @@ -60,7 +60,7 @@ public void testGenerateDirectoryHash() throws IOException { file.mkdir(); try { - SDKUtil.generateDirectoryHash(null, file.getAbsolutePath(), ""); + Utils.generateDirectoryHash(null, file.getAbsolutePath(), ""); Assert.fail("Should have failed as the directory is empty"); } catch(IOException iex) { Assert.assertEquals(String.format("The chaincode directory \"%s\" has no files", file.getAbsolutePath()), iex.getMessage()); 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 8cf305b5..d487a7f7 100644 --- a/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java +++ b/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java @@ -27,7 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; import org.hyperledger.fabric.sdkintegration.SampleOrg; /** @@ -178,7 +178,7 @@ private TestConfig() { private String grpcTLSify(String location) { location = location.trim(); - Exception e = SDKUtil.checkGrpcUrl(location); + Exception e = Utils.checkGrpcUrl(location); if (e != null) { throw new RuntimeException(String.format("Bad TEST parameters for grpc url %s", location), e); } diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java index 7ed0546d..b3df2157 100644 --- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java +++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java @@ -37,6 +37,7 @@ import org.hyperledger.fabric.sdk.Peer; import org.hyperledger.fabric.sdk.ProposalResponse; import org.hyperledger.fabric.sdk.QueryByChaincodeRequest; +import org.hyperledger.fabric.sdk.SDKUtils; import org.hyperledger.fabric.sdk.TestConfigHelper; import org.hyperledger.fabric.sdk.TransactionProposalRequest; import org.hyperledger.fabric.sdk.UpgradeProposalRequest; @@ -170,7 +171,6 @@ public void setup() { runChannel(client, barChannel, sampleOrg, 100); //run a newly constructed foo channel with different b value! barChannel.shutdown(true); - out("That's all folks!"); } catch (Exception e) { @@ -234,7 +234,14 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int failed.add(response); } } - // } + + // Check that all the proposals are consistent with each other. We should have only one set + // where all the proposals above are consistent. + Collection> proposalConsistencySets = SDKUtils.getProposalConsistencySets(responses); + if (proposalConsistencySets.size() != 1) { + fail(format("Expected only one set of consistent install proposal responses but got %d", proposalConsistencySets.size())); + } + out("Received %d install proposal responses. Successful+verified: %d . Failed: %d", numInstallProposal, successful.size(), failed.size()); if (failed.size() > 0) { @@ -274,7 +281,14 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int failed.add(response); } } - // } + + // Check that all the proposals are consistent with each other. We should have only one set + // where the proposals above are consistent. + proposalConsistencySets = SDKUtils.getProposalConsistencySets(responses2); + if (proposalConsistencySets.size() != 1) { + fail(format("Expected only one set of consistent upgrade proposal responses but got %d", proposalConsistencySets.size())); + } + out("Received %d upgrade proposal responses. Successful+verified: %d . Failed: %d", channel.getPeers().size(), successful.size(), failed.size()); if (failed.size() > 0) { @@ -385,6 +399,14 @@ CompletableFuture moveAmount(HFClient client, Chann failed.add(response); } } + + // Check that all the proposals are consistent with each other. We should have only one set + // where all the proposals above are consistent. + Collection> proposalConsistencySets = SDKUtils.getProposalConsistencySets(invokePropResp); + if (proposalConsistencySets.size() != 1) { + fail(format("Expected only one set of consistent move proposal responses but got %d", proposalConsistencySets.size())); + } + out("Received %d transaction proposal responses. Successful+verified: %d . Failed: %d", invokePropResp.size(), successful.size(), failed.size()); if (failed.size() > 0) { diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java index da0b728b..c1a73576 100644 --- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java +++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java @@ -45,6 +45,7 @@ import org.hyperledger.fabric.sdk.Peer; import org.hyperledger.fabric.sdk.ProposalResponse; import org.hyperledger.fabric.sdk.QueryByChaincodeRequest; +import org.hyperledger.fabric.sdk.SDKUtils; import org.hyperledger.fabric.sdk.TestConfigHelper; import org.hyperledger.fabric.sdk.TransactionInfo; import org.hyperledger.fabric.sdk.TransactionProposalRequest; @@ -53,7 +54,6 @@ import org.hyperledger.fabric.sdk.exception.InvalidProtocolBufferRuntimeException; import org.hyperledger.fabric.sdk.exception.ProposalException; import org.hyperledger.fabric.sdk.exception.TransactionEventException; -import org.hyperledger.fabric.sdk.helper.ChainUtils; import org.hyperledger.fabric.sdk.security.CryptoSuite; import org.hyperledger.fabric.sdk.testutils.TestConfig; import org.hyperledger.fabric_ca.sdk.HFCAClient; @@ -281,6 +281,8 @@ void runChannel(HFClient client, Channel channel, boolean installChaincode, Samp failed.add(response); } } + + SDKUtils.getProposalConsistencySets(responses); // } out("Received %d install proposal responses. Successful+verified: %d . Failed: %d", numInstallProposal, successful.size(), failed.size()); @@ -374,6 +376,14 @@ policy OR(Org1MSP.member, Org2MSP.member) meaning 1 signature from someone in ei failed.add(response); } } + + // Check that all the proposals are consistent with each other. We should have only one set + // where all the proposals above are consistent. + Collection> proposalConsistencySets = SDKUtils.getProposalConsistencySets(transactionPropResp); + if (proposalConsistencySets.size() != 1) { + fail(format("Expected only one set of consistent proposal responses but got %d", proposalConsistencySets.size())); + } + out("Received %d transaction proposal responses. Successful+verified: %d . Failed: %d", transactionPropResp.size(), successful.size(), failed.size()); if (failed.size() > 0) { @@ -644,7 +654,7 @@ void blockWalker(Channel channel) throws InvalidProtocolBufferException, Invalid out("current block number %d has data hash: %s", blockNumber, Hex.encodeHexString(returnedBlock.getDataHash())); out("current block number %d has previous hash id: %s", blockNumber, Hex.encodeHexString(returnedBlock.getPreviousHash())); - out("current block number %d has calculated block hash is %s", blockNumber, Hex.encodeHexString(ChainUtils.calculateBlockHash(blockNumber, returnedBlock.getPreviousHash(), returnedBlock.getDataHash()))); + out("current block number %d has calculated block hash is %s", blockNumber, Hex.encodeHexString(SDKUtils.calculateBlockHash(blockNumber, returnedBlock.getPreviousHash(), returnedBlock.getDataHash()))); final int envelopCount = returnedBlock.getEnvelopCount(); assertEquals(1, envelopCount); @@ -663,17 +673,17 @@ void blockWalker(Channel channel) throws InvalidProtocolBufferException, Invalid out(" Transaction number %d has type id: %s", i, "" + envelopeInfo.getType()); if (envelopeInfo.getType() == TRANSACTION_ENVELOPE) { - BlockInfo.TansactionEnvelopeInfo tansactionEnvelopeInfo = (BlockInfo.TansactionEnvelopeInfo) envelopeInfo; + BlockInfo.TransactionEnvelopeInfo transactionEnvelopeInfo = (BlockInfo.TransactionEnvelopeInfo) envelopeInfo; - out(" Transaction number %d has %d actions", i, tansactionEnvelopeInfo.getTransactionActionInfoCount()); - assertEquals(1, tansactionEnvelopeInfo.getTransactionActionInfoCount()); // for now there is only 1 action per transaction. - out(" Transaction number %d isValid %b", i, tansactionEnvelopeInfo.isValid()); - assertEquals(tansactionEnvelopeInfo.isValid(), true); - out(" Transaction number %d validation code %d", i, tansactionEnvelopeInfo.getValidationCode()); - assertEquals(0, tansactionEnvelopeInfo.getValidationCode()); + out(" Transaction number %d has %d actions", i, transactionEnvelopeInfo.getTransactionActionInfoCount()); + assertEquals(1, transactionEnvelopeInfo.getTransactionActionInfoCount()); // for now there is only 1 action per transaction. + out(" Transaction number %d isValid %b", i, transactionEnvelopeInfo.isValid()); + assertEquals(transactionEnvelopeInfo.isValid(), true); + out(" Transaction number %d validation code %d", i, transactionEnvelopeInfo.getValidationCode()); + assertEquals(0, transactionEnvelopeInfo.getValidationCode()); int j = 0; - for (BlockInfo.TansactionEnvelopeInfo.TransactionActionInfo transactionActionInfo : tansactionEnvelopeInfo.getTransactionActionInfos()) { + for (BlockInfo.TransactionEnvelopeInfo.TransactionActionInfo transactionActionInfo : transactionEnvelopeInfo.getTransactionActionInfos()) { ++j; out(" Transaction action %d has response status %d", j, transactionActionInfo.getResponseStatus()); assertEquals(200, transactionActionInfo.getResponseStatus()); diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/Util.java b/src/test/java/org/hyperledger/fabric/sdkintegration/Util.java index ff3521a8..0c5ee87f 100644 --- a/src/test/java/org/hyperledger/fabric/sdkintegration/Util.java +++ b/src/test/java/org/hyperledger/fabric/sdkintegration/Util.java @@ -31,7 +31,7 @@ import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; -import org.hyperledger.fabric.sdk.helper.SDKUtil; +import org.hyperledger.fabric.sdk.helper.Utils; class Util { @@ -67,7 +67,7 @@ public static InputStream generateTarGzInputStream(File src, String pathPrefix) String relativePath = childPath.substring((sourcePath.length() + 1), childPath.length()); if (pathPrefix != null) { - relativePath = SDKUtil.combinePaths(pathPrefix, relativePath); + relativePath = Utils.combinePaths(pathPrefix, relativePath); } relativePath = FilenameUtils.separatorsToUnix(relativePath);