From cdfa714bd869a78babf75e94bd1781d7b5d047d1 Mon Sep 17 00:00:00 2001 From: "Mark S. Lewis" Date: Mon, 4 Nov 2024 17:50:49 +0000 Subject: [PATCH] Replace checkstyle with PMD Signed-off-by: Mark S. Lewis --- .../contractinstall/ContractInstallTest.java | 2 +- .../ledgertests/LedgerIntegrationTest.java | 2 +- .../shimtests/SACCIntegrationTest.java | 2 +- .../shimtests/SBECCIntegrationTest.java | 4 +- .../shim/integration/util/FabricState.java | 8 +- fabric-chaincode-shim/build.gradle | 18 +- .../java/org/hyperledger/fabric/Logger.java | 8 +- .../java/org/hyperledger/fabric/Logging.java | 11 +- .../fabric/contract/ClientIdentity.java | 25 +- .../fabric/contract/ContextFactory.java | 12 +- .../fabric/contract/ContractInterface.java | 8 +- .../fabric/contract/ContractRouter.java | 53 ++-- .../contract/ContractRuntimeException.java | 5 +- .../contract/execution/ExecutionFactory.java | 7 +- .../execution/JSONTransactionSerializer.java | 236 ++++++++++-------- .../impl/ContractExecutionService.java | 4 +- .../impl/ContractInvocationRequest.java | 37 ++- .../contract/metadata/MetadataBuilder.java | 101 ++++---- .../fabric/contract/metadata/TypeSchema.java | 209 ++++++++-------- .../routing/impl/ContractDefinitionImpl.java | 20 +- .../routing/impl/DataTypeDefinitionImpl.java | 4 +- .../routing/impl/RoutingRegistryImpl.java | 19 +- .../routing/impl/SerializerRegistryImpl.java | 41 ++- .../contract/routing/impl/TxFunctionImpl.java | 70 +++--- .../routing/impl/TypeRegistryImpl.java | 13 +- .../systemcontract/SystemContract.java | 8 +- .../org/hyperledger/fabric/ledger/Ledger.java | 1 - .../fabric/ledger/impl/CollectionImpl.java | 28 --- .../fabric/ledger/impl/LedgerImpl.java | 15 +- .../hyperledger/fabric/metrics/Metrics.java | 12 +- .../fabric/metrics/MetricsProvider.java | 10 +- .../fabric/metrics/impl/DefaultProvider.java | 39 ++- .../fabric/metrics/impl/NullProvider.java | 6 +- .../hyperledger/fabric/shim/Chaincode.java | 4 +- .../fabric/shim/ChaincodeBase.java | 75 +++--- .../fabric/shim/ChaincodeException.java | 2 + .../shim/ChaincodeServerProperties.java | 10 +- .../fabric/shim/ChatChaincodeWithPeer.java | 4 +- .../fabric/shim/NettyChaincodeServer.java | 2 + .../fabric/shim/NettyGrpcServer.java | 103 ++++---- .../fabric/shim/ResponseUtils.java | 11 +- .../shim/ext/sbe/StateBasedEndorsement.java | 17 +- .../impl/StateBasedEndorsementFactory.java | 9 +- .../sbe/impl/StateBasedEndorsementImpl.java | 5 +- .../shim/impl/ChaincodeInvocationTask.java | 64 +++-- .../shim/impl/ChaincodeMessageFactory.java | 35 ++- .../shim/impl/ChaincodeSupportClient.java | 10 +- .../fabric/shim/impl/InvocationStubImpl.java | 125 +++++----- .../shim/impl/InvocationTaskExecutor.java | 4 +- .../shim/impl/InvocationTaskManager.java | 174 ++++++------- .../fabric/shim/impl/KeyModificationImpl.java | 41 ++- .../fabric/shim/impl/KeyValueImpl.java | 24 +- .../shim/impl/QueryResultsIteratorImpl.java | 7 +- .../QueryResultsIteratorWithMetadataImpl.java | 9 +- .../fabric/shim/ledger/CompositeKey.java | 11 +- .../org/hyperledger/fabric/traces/Traces.java | 11 +- .../fabric/traces/TracesProvider.java | 1 - .../traces/impl/OpenTelemetryProperties.java | 22 +- .../src/test/java/contract/Greeting.java | 11 +- .../test/java/contract/SampleContract.java | 3 +- .../org/hyperledger/fabric/LoggerTest.java | 8 +- .../org/hyperledger/fabric/LoggingTest.java | 20 +- .../java/org/hyperledger/fabric/TestUtil.java | 3 +- .../fabric/contract/AllTypesAsset.java | 31 +-- .../contract/ChaincodeStubNaiveImpl.java | 8 +- .../contract/ContractInterfaceTest.java | 3 +- .../hyperledger/fabric/contract/MyType.java | 4 +- .../JSONTransactionSerializerTest.java | 6 - .../metadata/MetadataBuilderTest.java | 38 +-- .../contract/metadata/TypeSchemaTest.java | 3 - .../routing/ContractDefinitionTest.java | 8 +- .../routing/DataTypeDefinitionTest.java | 35 +-- .../contract/routing/TxFunctionTest.java | 1 - .../simplepath/ContractSimplePathTest.java | 2 +- .../metrics/impl/DefaultProviderTest.java | 14 +- .../fabric/shim/ChaincodeStubTest.java | 3 +- .../shim/ChatChaincodeWithPeerTest.java | 17 +- .../fabric/shim/fvt/ChaincodeFVTest.java | 12 +- .../shim/impl/KeyModificationImplTest.java | 39 ++- .../fabric/shim/impl/KeyValueImplTest.java | 28 +-- ...ryResultsIteratorWithMetadataImplTest.java | 18 +- .../shim/mock/peer/ChaincodeMockPeer.java | 25 +- .../shim/mock/peer/GetHistoryForKeyStep.java | 2 +- .../shim/mock/peer/QueryResultStep.java | 2 +- .../traces/impl/TestSpanExporterProvider.java | 2 +- pmd-ruleset.xml | 48 ++++ 86 files changed, 1092 insertions(+), 1120 deletions(-) delete mode 100644 fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/CollectionImpl.java create mode 100644 pmd-ruleset.xml diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java index b05dbf81..f63dc8b6 100644 --- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java +++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java @@ -22,7 +22,7 @@ public static void setUp() throws Exception { } @Test - public void TestInstall() { + public void testInstall() { InvokeHelper helper = InvokeHelper.newHelper("baregradlecc", "sachannel"); String text = helper.invoke("org1", "whoami"); diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java index ad856978..815ab88c 100644 --- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java +++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java @@ -23,7 +23,7 @@ public static void setUp() throws Exception { } @Test - public void TestLedgers() { + public void testLedgers() { InvokeHelper helper = InvokeHelper.newHelper("ledgercc", "sachannel"); String text = helper.invoke("org1", "accessLedgers"); diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java index 94ebb378..93923ac6 100644 --- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java +++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java @@ -22,7 +22,7 @@ public static void setUp() throws Exception { } @Test - public void TestLedger() { + public void testLedger() { InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel"); String text = helper.invoke("org1", "putBulkStates"); diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java index 32e8ec56..02ffb16c 100644 --- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java +++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java @@ -22,7 +22,7 @@ public static void setUp() throws Exception { } @Test - public void RunSBE_pub_setget() { + public void runSBE_pub_setget() { final String mode = "pub"; final InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel"); @@ -85,7 +85,7 @@ public void RunSBE_pub_setget() { } @Test - public void RunSBE_priv() { + public void runSBE_priv() { final String mode = "priv"; final InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel"); diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java index 8483446e..916f31ea 100644 --- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java +++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java @@ -9,19 +9,13 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.Semaphore; import org.hyperleder.fabric.shim.integration.util.Bash.BashBuilder; public final class FabricState { private static FabricState state; - private static final Map channelStarted = new HashMap<>(); - - // sempaphore to protect access - private static final Semaphore flag = new Semaphore(1); - - public static FabricState getState() { + public static synchronized FabricState getState() { if (state == null) { state = new FabricState(); } diff --git a/fabric-chaincode-shim/build.gradle b/fabric-chaincode-shim/build.gradle index b4c50500..eb6cb7e5 100644 --- a/fabric-chaincode-shim/build.gradle +++ b/fabric-chaincode-shim/build.gradle @@ -8,20 +8,14 @@ plugins { id 'maven-publish' id 'jacoco' id 'signing' - id 'checkstyle' + id 'pmd' } -checkstyle { - toolVersion '10.18.1' - configFile file("../ci/checkstyle/checkstyle.xml") - configProperties = [root_dir: file("..") ] -} -checkstyleMain { - source ='src/main/java' -} -checkstyleMain.exclude("**/ChaincodeServerProperties.**") -checkstyleTest { - source ='src/test/java' +pmd { + toolVersion = '7.7.0' + ruleSetFiles = files('../pmd-ruleset.xml') + ruleSets = [] // explicitly set to empty to avoid using the default configuration + ignoreFailures = false } configurations { diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java index e1a55c90..35720635 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java @@ -18,7 +18,7 @@ protected Logger(final String name) { super(name, null); // ensure that the parent logger is set - this.setParent(java.util.logging.Logger.getLogger("org.hyperledger.fabric")); + super.setParent(java.util.logging.Logger.getLogger("org.hyperledger.fabric")); } /** @@ -45,9 +45,9 @@ public void debug(final String msg) { */ public static Logger getLogger(final Class class1) { // important to add the logger to the log manager - final Logger l = Logger.getLogger(class1.getName()); - LogManager.getLogManager().addLogger(l); - return l; + final Logger result = Logger.getLogger(class1.getName()); + LogManager.getLogManager().addLogger(result); + return result; } /** @param message */ diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java index 1d26eaf4..0901d75e 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java @@ -7,8 +7,9 @@ import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.Locale; import java.util.logging.Level; import java.util.logging.LogManager; @@ -50,7 +51,7 @@ public static String formatError(final Throwable throwable) { final Throwable cause = throwable.getCause(); if (cause != null) { buffer.append(".. caused by ..").append(System.lineSeparator()); - buffer.append(Logging.formatError(cause)); + buffer.append(formatError(cause)); } return buffer.toString(); @@ -67,11 +68,11 @@ public static void setLogLevel(final String newLevel) { final LogManager logManager = LogManager.getLogManager(); // slightly cumbersome approach - but the loggers don't have a 'get children' // so find those that have the correct stem. - final ArrayList allLoggers = Collections.list(logManager.getLoggerNames()); + final List allLoggers = Collections.list(logManager.getLoggerNames()); allLoggers.add("org.hyperledger"); allLoggers.stream() .filter(name -> name.startsWith("org.hyperledger")) - .map(name -> logManager.getLogger(name)) + .map(logManager::getLogger) .forEach(logger -> { if (logger != null) { logger.setLevel(l); @@ -81,7 +82,7 @@ public static void setLogLevel(final String newLevel) { private static Level mapLevel(final String level) { if (level != null) { - switch (level.toUpperCase().trim()) { + switch (level.toUpperCase(Locale.getDefault()).trim()) { case "ERROR": case "CRITICAL": return Level.SEVERE; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java index 4c10f704..2ce5cbbc 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java @@ -30,11 +30,11 @@ * and attributes. Such information is useful in enforcing access control by the chaincode. */ public final class ClientIdentity { - private static Logger logger = Logger.getLogger(ContractRouter.class.getName()); + private static final Logger LOGGER = Logger.getLogger(ContractRouter.class.getName()); private final String mspId; private final X509Certificate cert; - private Map attrs; + private final Map attrs; private final String id; // special OID used by Fabric to save attributes in x.509 certificates private static final String FABRIC_CERT_ATTR_OID = "1.2.3.4.5.6.7.8.1"; @@ -47,7 +47,7 @@ public final class ClientIdentity { * @throws JSONException * @throws IOException */ - public ClientIdentity(final ChaincodeStub stub) throws CertificateException, JSONException, IOException { + public ClientIdentity(final ChaincodeStub stub) throws CertificateException, IOException { final byte[] signingId = stub.getCreator(); // Create a Serialized Identity protobuf @@ -60,11 +60,12 @@ public ClientIdentity(final ChaincodeStub stub) throws CertificateException, JSO CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(idBytes)); this.cert = cert; - this.attrs = new HashMap(); // Get the extension where the identity attributes are stored final byte[] extensionValue = cert.getExtensionValue(FABRIC_CERT_ATTR_OID); if (extensionValue != null) { this.attrs = parseAttributes(extensionValue); + } else { + this.attrs = new HashMap<>(); } // Populate identity @@ -100,7 +101,7 @@ public String getMSPID() { */ private Map parseAttributes(final byte[] extensionValue) throws IOException { - final Map attrMap = new HashMap(); + final Map attrMap = new HashMap<>(); // Create ASN1InputStream from extensionValue try (ByteArrayInputStream inStream = new ByteArrayInputStream(extensionValue); @@ -126,7 +127,7 @@ private Map parseAttributes(final byte[] extensionValue) throws } catch (final JSONException error) { // creating a JSON object failed // decoded extensionValue is not a string containing JSON - logger.error(() -> logger.formatError(error)); + LOGGER.error(() -> LOGGER.formatError(error)); // return empty map } return attrMap; @@ -142,11 +143,7 @@ private Map parseAttributes(final byte[] extensionValue) throws * @return {String | null} Value of the attribute or null if the invoking identity does not possess the attribute. */ public String getAttributeValue(final String attrName) { - if (this.attrs.containsKey(attrName)) { - return this.attrs.get(attrName); - } else { - return null; - } + return this.attrs.getOrDefault(attrName, null); } /** @@ -160,11 +157,7 @@ public String getAttributeValue(final String attrName) { * expected value. Otherwise, returns false. */ public boolean assertAttributeValue(final String attrName, final String attrValue) { - if (!this.attrs.containsKey(attrName)) { - return false; - } else { - return attrValue.equals(this.attrs.get(attrName)); - } + return this.attrs.containsKey(attrName) && attrValue.equals(this.attrs.get(attrName)); } /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java index 64e12a1b..68514adb 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java @@ -10,14 +10,11 @@ /** Factory to create {@link Context} from {@link ChaincodeStub} by wrapping stub with dynamic proxy. */ public final class ContextFactory { - private static ContextFactory cf; + private static final ContextFactory INSTANCE = new ContextFactory(); /** @return ContextFactory */ - public static synchronized ContextFactory getInstance() { - if (cf == null) { - cf = new ContextFactory(); - } - return cf; + public static ContextFactory getInstance() { + return INSTANCE; } /** @@ -25,7 +22,6 @@ public static synchronized ContextFactory getInstance() { * @return Context */ public Context createContext(final ChaincodeStub stub) { - final Context newContext = new Context(stub); - return newContext; + return new Context(stub); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java index c9bea5fc..e1db9de4 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java @@ -75,7 +75,9 @@ default void unknownTransaction(final Context ctx) { * * @param ctx the context as created by {@link #createContext(ChaincodeStub)}. */ - default void beforeTransaction(final Context ctx) {} + default void beforeTransaction(final Context ctx) { + // Nothing by default + } /** * Invoked once after each transaction. @@ -86,5 +88,7 @@ default void beforeTransaction(final Context ctx) {} * @param result The object returned from the transaction function if any. As this is a Java object and therefore * pass-by-reference it is possible to modify this object. */ - default void afterTransaction(final Context ctx, final Object result) {} + default void afterTransaction(final Context ctx, final Object result) { + // Nothing by default + } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java index 0219f71d..d7b6f9e5 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java @@ -35,7 +35,7 @@ * @see ContractInterface */ public final class ContractRouter extends ChaincodeBase { - private static Logger logger = Logger.getLogger(ContractRouter.class.getName()); + private static final Logger LOGGER = Logger.getLogger(ContractRouter.class.getName()); private final RoutingRegistry registry; private final TypeRegistry typeRegistry; @@ -53,6 +53,7 @@ public final class ContractRouter extends ChaincodeBase { * @param args */ public ContractRouter(final String[] args) { + super(); super.initializeLogging(); super.processEnvironmentOptions(); super.processCommandLineOptions(args); @@ -62,7 +63,7 @@ public ContractRouter(final String[] args) { Metrics.initialize(props); Traces.initialize(props); - logger.fine("ContractRouter"); + LOGGER.fine("ContractRouter"); registry = new RoutingRegistryImpl(); typeRegistry = TypeRegistry.getRegistry(); @@ -72,15 +73,15 @@ public ContractRouter(final String[] args) { serializers.findAndSetContents(); } catch (InstantiationException | IllegalAccessException e) { final ContractRuntimeException cre = new ContractRuntimeException("Unable to locate Serializers", e); - logger.severe(() -> Logging.formatError(cre)); - throw new RuntimeException(cre); + LOGGER.severe(() -> Logging.formatError(cre)); + throw cre; } executor = ExecutionFactory.getInstance().createExecutionService(serializers); } /** Locate all the contracts that are available on the classpath. */ - protected void findAllContracts() { + void findAllContracts() { registry.findAndSetContracts(this.typeRegistry); } @@ -91,28 +92,29 @@ protected void findAllContracts() { * * @throws Exception */ + @SuppressWarnings("PMD.AvoidCatchingGenericException") void startRouting() { try { super.connectToPeer(); } catch (final Exception e) { - logger.severe(() -> Logging.formatError(e)); - final ContractRuntimeException cre = new ContractRuntimeException("Unable to start routing", e); - throw cre; + LOGGER.severe(() -> Logging.formatError(e)); + throw new ContractRuntimeException("Unable to start routing", e); } } + @SuppressWarnings("PMD.AvoidCatchingThrowable") private Response processRequest(final ChaincodeStub stub) { - logger.info(() -> "Got invoke routing request"); + LOGGER.info(() -> "Got invoke routing request"); try { - if (stub.getStringArgs().size() > 0) { - logger.info(() -> "Got the invoke request for:" + stub.getFunction() + " " + stub.getParameters()); - final InvocationRequest request = ExecutionFactory.getInstance().createRequest(stub); - final TxFunction txFn = getRouting(request); - logger.info(() -> "Got routing:" + txFn.getRouting()); - return executor.executeRequest(txFn, request, stub); - } else { + if (stub.getStringArgs().isEmpty()) { return ResponseUtils.newSuccessResponse(); } + + LOGGER.info(() -> "Got the invoke request for:" + stub.getFunction() + " " + stub.getParameters()); + final InvocationRequest request = ExecutionFactory.getInstance().createRequest(stub); + final TxFunction txFn = getRouting(request); + LOGGER.info(() -> "Got routing:" + txFn.getRouting()); + return executor.executeRequest(txFn, request, stub); } catch (final Throwable throwable) { return ResponseUtils.newErrorResponse(throwable); } @@ -139,7 +141,7 @@ TxFunction getRouting(final InvocationRequest request) { if (registry.containsRoute(request)) { return registry.getTxFn(request); } else { - logger.fine(() -> "Namespace is " + request); + LOGGER.fine(() -> "Namespace is " + request); final ContractDefinition contract = registry.getContract(request.getNamespace()); return contract.getUnknownRoute(); } @@ -150,34 +152,35 @@ TxFunction getRouting(final InvocationRequest request) { * * @param args */ + @SuppressWarnings("PMD.SignatureDeclareThrowsException") public static void main(final String[] args) throws Exception { final ContractRouter cfc = new ContractRouter(args); cfc.findAllContracts(); - logger.fine(cfc.getRoutingRegistry().toString()); + LOGGER.fine(() -> cfc.getRoutingRegistry().toString()); // Create the Metadata ahead of time rather than have to produce every // time MetadataBuilder.initialize(cfc.getRoutingRegistry(), cfc.getTypeRegistry()); - logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); + LOGGER.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); // check if this should be running in client or server mode if (cfc.isServer()) { - logger.info("Starting chaincode as server"); + LOGGER.info("Starting chaincode as server"); ChaincodeServer chaincodeServer = new NettyChaincodeServer(cfc, cfc.getChaincodeServerConfig()); chaincodeServer.start(); } else { - logger.info("Starting chaincode as client"); + LOGGER.info("Starting chaincode as client"); cfc.startRouting(); } } - protected TypeRegistry getTypeRegistry() { + TypeRegistry getTypeRegistry() { return this.typeRegistry; } - protected RoutingRegistry getRoutingRegistry() { + RoutingRegistry getRoutingRegistry() { return this.registry; } @@ -189,10 +192,10 @@ protected RoutingRegistry getRoutingRegistry() { public void startRouterWithChaincodeServer(final ChaincodeServer chaincodeServer) throws IOException, InterruptedException { findAllContracts(); - logger.fine(getRoutingRegistry().toString()); + LOGGER.fine(() -> getRoutingRegistry().toString()); MetadataBuilder.initialize(getRoutingRegistry(), getTypeRegistry()); - logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); + LOGGER.info(() -> "Metadata follows:" + MetadataBuilder.debugString()); chaincodeServer.start(); } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java index b51c218f..78d559a2 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java @@ -14,6 +14,8 @@ *

FUTURE At some future point we wish to add more diagnostic information into this, for example current tx id */ public class ContractRuntimeException extends ChaincodeException { + /** Generated serial version id. */ + private static final long serialVersionUID = -884373036398750450L; /** @param string */ public ContractRuntimeException(final String string) { @@ -32,7 +34,4 @@ public ContractRuntimeException(final String string, final Throwable cause) { public ContractRuntimeException(final Throwable cause) { super(cause); } - - /** Generated serial version id. */ - private static final long serialVersionUID = -884373036398750450L; } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java index fee47eb1..3cd7a5fc 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java @@ -12,14 +12,11 @@ import org.hyperledger.fabric.shim.ChaincodeStub; public class ExecutionFactory { - private static ExecutionFactory rf; + private static final ExecutionFactory INSTANCE = new ExecutionFactory(); /** @return ExecutionFactory */ public static ExecutionFactory getInstance() { - if (rf == null) { - rf = new ExecutionFactory(); - } - return rf; + return INSTANCE; } /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java index c1c99591..ac2e33b9 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java @@ -11,8 +11,6 @@ import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; import java.util.Map; import java.util.Set; import org.hyperledger.fabric.Logger; @@ -26,15 +24,13 @@ import org.json.JSONException; import org.json.JSONObject; -/** Used as a the default serialisation for transmission from SDK to Contract. */ +/** Used as the default serialisation for transmission from SDK to Contract. */ @Serializer() +@SuppressWarnings({"PMD.GodClass", "PMD.AvoidLiteralsInIfCondition", "PMD.AvoidDuplicateLiterals"}) public class JSONTransactionSerializer implements SerializerInterface { - private static Logger logger = Logger.getLogger(JSONTransactionSerializer.class.getName()); + private static final Logger LOGGER = Logger.getLogger(JSONTransactionSerializer.class.getName()); private final TypeRegistry typeRegistry = TypeRegistry.getRegistry(); - /** Create a new serialiser. */ - public JSONTransactionSerializer() {} - /** * Convert the value supplied to a byte array, according to the TypeSchema. * @@ -44,7 +40,7 @@ public JSONTransactionSerializer() {} */ @Override public byte[] toBuffer(final Object value, final TypeSchema ts) { - logger.debug(() -> "Schema to convert is " + ts); + LOGGER.debug(() -> "Schema to convert is " + ts); byte[] buffer = null; if (value != null) { final String type = ts.getType(); @@ -56,7 +52,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) { break; case "string": final String format = ts.getFormat(); - if (format != null && format.contentEquals("uint16")) { + if ("utin16".equals(format)) { buffer = Character.valueOf((char) value).toString().getBytes(UTF_8); } else { buffer = ((String) value).getBytes(UTF_8); @@ -66,7 +62,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) { case "integer": case "boolean": default: - buffer = (value).toString().getBytes(UTF_8); + buffer = value.toString().getBytes(UTF_8); } } else { // at this point we can assert that the value is @@ -76,7 +72,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) { // it should have final DataTypeDefinition dtd = this.typeRegistry.getDataType(ts); final Set keySet = dtd.getProperties().keySet(); - final String[] propNames = keySet.toArray(new String[keySet.size()]); + final String[] propNames = keySet.toArray(new String[0]); // Note: whilst the current JSON library does pretty much // everything is required, this part is hard. @@ -105,6 +101,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) { * @param ts Schema to normalise to * @return JSONArray */ + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts) { JSONArray normalizedArray; @@ -112,22 +109,12 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts) final TypeSchema items = ts.getItems(); final String type = items.getType(); - if (type != null && type != "array") { - // primitive - can return this directly - normalizedArray = jsonArray; - } else if (type != null && type == "array") { - // nested arrays, get the type of what it makes up - // Need to loop over all elements and normalize each one - normalizedArray = new JSONArray(); - for (int i = 0; i < jsonArray.length(); i++) { - normalizedArray.put(i, normalizeArray(jsonArray.getJSONArray(i), items)); - } - } else { + if (null == type) { // get the permitted propeties in the type, // then loop over the array and ensure they are correct final DataTypeDefinition dtd = this.typeRegistry.getDataType(items); final Set keySet = dtd.getProperties().keySet(); - final String[] propNames = keySet.toArray(new String[keySet.size()]); + final String[] propNames = keySet.toArray(new String[0]); normalizedArray = new JSONArray(); // array of objects @@ -136,7 +123,18 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts) final JSONObject obj = new JSONObject(jsonArray.getJSONObject(i), propNames); normalizedArray.put(i, obj); } + } else if ("array".equals(type)) { + // nested arrays, get the type of what it makes up + // Need to loop over all elements and normalize each one + normalizedArray = new JSONArray(); + for (int i = 0; i < jsonArray.length(); i++) { + normalizedArray.put(i, normalizeArray(jsonArray.getJSONArray(i), items)); + } + } else { + // primitive - can return this directly + normalizedArray = jsonArray; } + return normalizedArray; } @@ -150,15 +148,10 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts) @Override public Object fromBuffer(final byte[] buffer, final TypeSchema ts) { try { - final String stringData = new String(buffer, StandardCharsets.UTF_8); - Object value = null; - - value = convert(stringData, ts); - - return value; + final String stringData = new String(buffer, UTF_8); + return convert(stringData, ts); } catch (InstantiationException | IllegalAccessException e) { - final ContractRuntimeException cre = new ContractRuntimeException(e); - throw cre; + throw new ContractRuntimeException(e); } } @@ -172,102 +165,136 @@ public Object fromBuffer(final byte[] buffer, final TypeSchema ts) { * @return Class for the Object variant */ private Class mapPrimitive(final Class primitive) { - String primitiveType; - final boolean isArray = primitive.isArray(); - if (isArray) { - primitiveType = primitive.getComponentType().getName(); - } else { - primitiveType = primitive.getName(); + if (primitive.isArray()) { + return mapArrayPrimitive(primitive); } - switch (primitiveType) { + return mapBasicPrimitive(primitive); + } + + private Class mapArrayPrimitive(final Class primitive) { + switch (primitive.getComponentType().getName()) { case "int": - return isArray ? Integer[].class : Integer.class; + return Integer[].class; case "long": - return isArray ? Long[].class : Long.class; + return Long[].class; case "float": - return isArray ? Float[].class : Float.class; + return Float[].class; case "double": - return isArray ? Double[].class : Double.class; + return Double[].class; case "short": - return isArray ? Short[].class : Short.class; + return Short[].class; case "byte": - return isArray ? Byte[].class : Byte.class; + return Byte[].class; case "char": - return isArray ? Character[].class : Character.class; + return Character[].class; case "boolean": - return isArray ? Boolean[].class : Boolean.class; + return Boolean[].class; default: return primitive; } } - /* - * Internal method to do the conversion - */ + private Class mapBasicPrimitive(final Class primitive) { + switch (primitive.getName()) { + case "int": + return Integer.class; + case "long": + return Long.class; + case "float": + return Float.class; + case "double": + return Double.class; + case "short": + return Short.class; + case "byte": + return Byte.class; + case "char": + return Character.class; + case "boolean": + return Boolean.class; + default: + return primitive; + } + } + + /** Internal method to do the conversion */ private Object convert(final String stringData, final TypeSchema ts) - throws IllegalArgumentException, IllegalAccessException, InstantiationException { - logger.debug(() -> "Schema to convert is " + ts); + throws IllegalAccessException, InstantiationException { + LOGGER.debug(() -> "Schema to convert is " + ts); + String type = ts.getType(); + String format = null; - Object value = null; if (type == null) { type = "object"; final String ref = ts.getRef(); - format = ref.substring(ref.lastIndexOf("/") + 1); + format = ref.substring(ref.lastIndexOf('/') + 1); } - if (type.contentEquals("string")) { - final String strformat = ts.getFormat(); - if (strformat != null && strformat.contentEquals("uint16")) { - value = stringData.charAt(0); - } else { - value = stringData; - } - } else if (type.contentEquals("integer")) { - final String intFormat = ts.getFormat(); - switch (intFormat) { - case "int32": - value = Integer.parseInt(stringData); - break; - case "int8": - value = Byte.parseByte(stringData); - break; - case "int16": - value = Short.parseShort(stringData); - break; - case "int64": - value = Long.parseLong(stringData); - break; - default: - throw new RuntimeException("Unknown format for integer " + intFormat); - } + switch (type) { + case "string": + return convertString(stringData, ts); + case "integer": + return convertInteger(stringData, ts); + case "number": + return convertNumber(stringData, ts); + case "boolean": + return Boolean.parseBoolean(stringData); + case "object": + return createComponentInstance(format, stringData, ts); + case "array": + return convertArray(stringData, ts); + default: + return null; + } + } - } else if (type.contentEquals("number")) { - final String numFormat = ts.getFormat(); - if (numFormat.contentEquals("float")) { - value = Float.parseFloat(stringData); - } else { - value = Double.parseDouble(stringData); - } - } else if (type.contentEquals("boolean")) { - value = Boolean.parseBoolean(stringData); - } else if (type.contentEquals("object")) { - value = createComponentInstance(format, stringData, ts); - } else if (type.contentEquals("array")) { - final JSONArray jsonArray = new JSONArray(stringData); - final TypeSchema itemSchema = ts.getItems(); - - // note here that the type has to be converted in the case of primitives - final Object[] data = (Object[]) - Array.newInstance(mapPrimitive(itemSchema.getTypeClass(this.typeRegistry)), jsonArray.length()); - for (int i = 0; i < jsonArray.length(); i++) { - final Object convertedData = convert(jsonArray.get(i).toString(), itemSchema); - data[i] = convertedData; - } - value = data; + private Object convertArray(final String stringData, final TypeSchema ts) + throws IllegalAccessException, InstantiationException { + final JSONArray jsonArray = new JSONArray(stringData); + final TypeSchema itemSchema = ts.getItems(); + + // note here that the type has to be converted in the case of primitives + final Object[] data = (Object[]) + Array.newInstance(mapPrimitive(itemSchema.getTypeClass(this.typeRegistry)), jsonArray.length()); + for (int i = 0; i < jsonArray.length(); i++) { + final Object convertedData = convert(jsonArray.get(i).toString(), itemSchema); + data[i] = convertedData; + } + + return data; + } + + private Object convertNumber(final String stringData, final TypeSchema ts) { + if ("float".equals(ts.getFormat())) { + return Float.parseFloat(stringData); + } + + return Double.parseDouble(stringData); + } + + private Object convertInteger(final String stringData, final TypeSchema ts) { + switch (ts.getFormat()) { + case "int32": + return Integer.parseInt(stringData); + case "int8": + return Byte.parseByte(stringData); + case "int16": + return Short.parseShort(stringData); + case "int64": + return Long.parseLong(stringData); + default: + throw new IllegalArgumentException("Unknown format for integer " + ts.getFormat()); + } + } + + private Object convertString(final String stringData, final TypeSchema ts) { + if ("uint16".equals(ts.getFormat())) { + return stringData.charAt(0); } - return value; + + return stringData; } /** @@ -278,6 +305,7 @@ private Object convert(final String stringData, final TypeSchema ts) * @param ts TypeSchema * @return new object */ + @SuppressWarnings("PMD.AvoidAccessibilityAlteration") Object createComponentInstance(final String format, final String jsonString, final TypeSchema ts) { final DataTypeDefinition dtd = this.typeRegistry.getDataType(format); @@ -296,9 +324,7 @@ Object createComponentInstance(final String format, final String jsonString, fin ts.validate(json); try { final Map fields = dtd.getProperties(); - for (final Iterator iterator = fields.values().iterator(); iterator.hasNext(); ) { - final PropertyDefinition prop = iterator.next(); - + for (final PropertyDefinition prop : fields.values()) { final Field f = prop.getField(); f.setAccessible(true); final Object newValue = convert(json.get(prop.getName()).toString(), prop.getSchema()); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java index b8803269..509f60d9 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java @@ -28,7 +28,7 @@ public class ContractExecutionService implements ExecutionService { - private static Logger logger = Logger.getLogger(ContractExecutionService.class.getName()); + private static final Logger LOGGER = Logger.getLogger(ContractExecutionService.class.getName()); private final SerializerRegistryImpl serializers; @@ -41,7 +41,7 @@ public ContractExecutionService(final SerializerRegistryImpl serializers) { @Override public Chaincode.Response executeRequest( final TxFunction txFn, final InvocationRequest req, final ChaincodeStub stub) { - logger.fine(() -> "Routing Request" + txFn); + LOGGER.fine(() -> "Routing Request" + txFn); final TxFunction.Routing rd = txFn.getRouting(); Chaincode.Response response; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java index a63d2ffc..7a3e0ff3 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java @@ -6,27 +6,36 @@ package org.hyperledger.fabric.contract.execution.impl; -import java.util.Collections; +import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.stream.Collectors; +import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperledger.fabric.contract.execution.InvocationRequest; import org.hyperledger.fabric.shim.ChaincodeStub; -public class ContractInvocationRequest implements InvocationRequest { - private String namespace; - private String method; - private List args = Collections.emptyList(); +public final class ContractInvocationRequest implements InvocationRequest { + @SuppressWarnings("PMD.ProperLogger") // PMD 7.7.0 gives a false positive here + private static final Log LOGGER = LogFactory.getLog(ContractInvocationRequest.class); - private static Log logger = LogFactory.getLog(ContractInvocationRequest.class); + private static final Pattern NS_REGEX = Pattern.compile(":"); + + private final String namespace; + private final String method; + private final List args; /** @param context */ + @SuppressWarnings("PMD.AvoidLiteralsInIfCondition") public ContractInvocationRequest(final ChaincodeStub context) { - final String func = - context.getStringArgs().size() > 0 ? context.getStringArgs().get(0) : null; - final String[] funcParts = func.split(":"); - logger.debug(func); + List funcAndArgs = context.getArgs(); + if (funcAndArgs.isEmpty()) { + throw new IllegalArgumentException("Missing function name"); + } + + final String func = new String(funcAndArgs.get(0), StandardCharsets.UTF_8); + LOGGER.debug(func); + + final String[] funcParts = NS_REGEX.split(func); if (funcParts.length == 2) { namespace = funcParts[0]; method = funcParts[1]; @@ -35,8 +44,10 @@ public ContractInvocationRequest(final ChaincodeStub context) { method = funcParts[0]; } - args = context.getArgs().stream().skip(1).collect(Collectors.toList()); - logger.debug(namespace + " " + method + " " + args); + args = funcAndArgs.subList(1, funcAndArgs.size()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(namespace + " " + method + " " + args); + } } /** */ diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java index c7b5d0c0..e444efa7 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; +import java.io.UncheckedIOException; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -40,16 +41,26 @@ *

This class is used to build up the JSON structure to be returned as the metadata It is not a store of information, * rather a set of functional data to process to and from metadata json to the internal data structure */ +@SuppressWarnings("PMD.AvoidDuplicateLiterals") public final class MetadataBuilder { - private static Logger logger = Logger.getLogger(MetadataBuilder.class); + private static final Logger LOGGER = Logger.getLogger(MetadataBuilder.class); - private MetadataBuilder() {} + private static final int PADDING = 3; - @SuppressWarnings("serial") - static class MetadataMap extends HashMap { + // Metadata is composed of three primary sections + // each of which is stored in a map + private static Map> contractMap = new HashMap<>(); + private static Map overallInfoMap = new HashMap<>(); + private static Map componentMap = new HashMap<>(); + + // The schema client used to load any other referenced schemas + private static SchemaClient schemaClient = new DefaultSchemaClient(); + + static final class MetadataMap extends HashMap { + private static final long serialVersionUID = 1L; V putIfNotNull(final K key, final V value) { - logger.info(key + " " + value); + LOGGER.info(() -> key + " " + value); if (value != null && !value.toString().isEmpty()) { return put(key, value); } else { @@ -58,14 +69,7 @@ V putIfNotNull(final K key, final V value) { } } - // Metadata is composed of three primary sections - // each of which is stored in a map - private static Map> contractMap = new HashMap<>(); - private static Map overallInfoMap = new HashMap(); - private static Map componentMap = new HashMap(); - - // The schema client used to load any other referenced schemas - private static SchemaClient schemaClient = new DefaultSchemaClient(); + private MetadataBuilder() {} /** * Validation method. @@ -73,7 +77,7 @@ V putIfNotNull(final K key, final V value) { * @throws ValidationException if the metadata is not valid */ public static void validate() { - logger.info("Running schema test validation"); + LOGGER.info("Running schema test validation"); final ClassLoader cl = MetadataBuilder.class.getClassLoader(); try (InputStream contractSchemaInputStream = cl.getResourceAsStream("contract-schema.json"); InputStream jsonSchemaInputStream = cl.getResourceAsStream("json-schema-draft-04-schema.json")) { @@ -88,13 +92,13 @@ public static void validate() { schema.validate(metadata()); } catch (final IOException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } catch (final ValidationException e) { - logger.error(e.getMessage()); + LOGGER.error(e::getMessage); e.getCausingExceptions().stream() .map(ValidationException::getMessage) - .forEach(logger::info); - logger.error(debugString()); + .forEach(LOGGER::info); + LOGGER.error(MetadataBuilder::debugString); throw e; } } @@ -115,8 +119,8 @@ public static void initialize(final RoutingRegistry registry, final TypeRegistry // need to validate that the metadata that has been created is really valid // it should be as it's been created by code, but this is a valuable double // check - logger.info("Validating schema created"); - MetadataBuilder.validate(); + LOGGER.info("Validating schema created"); + validate(); } /** @@ -133,7 +137,7 @@ public static void addComponent(final DataTypeDefinition datatype) { component.put("additionalProperties", false); final Map propertiesMap = datatype.getProperties().entrySet().stream() - .collect(Collectors.toMap(Entry::getKey, e -> (e.getValue().getSchema()))); + .collect(Collectors.toMap(Entry::getKey, e -> e.getValue().getSchema())); component.put("properties", propertiesMap); componentMap.put(datatype.getSimpleName(), component); @@ -145,7 +149,7 @@ public static void addComponent(final DataTypeDefinition datatype) { * @param contractDefinition Class of the object to use as a contract * @return the key that the contract class is referred to in the metadata */ - @SuppressWarnings("serial") + @SuppressWarnings("PMD.LooseCoupling") public static String addContract(final ContractDefinition contractDefinition) { final String key = contractDefinition.getName(); @@ -153,40 +157,34 @@ public static String addContract(final ContractDefinition contractDefinition) { final Contract annotation = contractDefinition.getAnnotation(); final Info info = annotation.info(); - final HashMap infoMap = new HashMap(); + final HashMap infoMap = new HashMap<>(); infoMap.put("title", info.title()); infoMap.put("description", info.description()); infoMap.put("termsOfService", info.termsOfService()); - infoMap.put("contact", new MetadataMap() { - { - putIfNotNull("email", info.contact().email()); - putIfNotNull("name", info.contact().name()); - putIfNotNull("url", info.contact().url()); - } - }); - infoMap.put("license", new MetadataMap() { - { - put("name", info.license().name()); - putIfNotNull("url", info.license().url()); - } - }); + + MetadataMap contact = new MetadataMap<>(); + contact.putIfNotNull("email", info.contact().email()); + contact.putIfNotNull("name", info.contact().name()); + contact.putIfNotNull("url", info.contact().url()); + infoMap.put("contact", contact); + + MetadataMap license = new MetadataMap<>(); + license.put("name", info.license().name()); + license.putIfNotNull("url", info.license().url()); + infoMap.put("license", license); + infoMap.put("version", info.version()); - final HashMap contract = new HashMap(); + final HashMap contract = new HashMap<>(); contract.put("name", key); - contract.put("transactions", new ArrayList()); + contract.put("transactions", new ArrayList<>()); contract.put("info", infoMap); contractMap.put(key, contract); - final boolean defaultContract = true; - if (defaultContract) { - overallInfoMap.putAll(infoMap); - } + overallInfoMap.putAll(infoMap); final Collection fns = contractDefinition.getTxFunctions(); - fns.forEach(txFn -> { - MetadataBuilder.addTransaction(txFn, key); - }); + fns.forEach(txFn -> addTransaction(txFn, key)); return key; } @@ -204,7 +202,7 @@ public static void addTransaction(final TxFunction txFunction, final String cont transaction.put("returns", returnSchema); } - final ArrayList tags = new ArrayList(); + final List tags = new ArrayList<>(); tags.add(txFunction.getType()); if (txFunction.getType() == TransactionType.SUBMIT) { // add deprecated tags tags.add(TransactionType.INVOKE); @@ -216,7 +214,7 @@ public static void addTransaction(final TxFunction txFunction, final String cont @SuppressWarnings("unchecked") final List txs = (ArrayList) contract.get("transactions"); - final ArrayList paramsList = new ArrayList(); + final List paramsList = new ArrayList<>(); txFunction.getParamsList().forEach(pd -> { final TypeSchema paramMap = pd.getSchema(); paramMap.put("name", pd.getName()); @@ -225,7 +223,7 @@ public static void addTransaction(final TxFunction txFunction, final String cont transaction.put("parameters", paramsList); - if (tags.size() != 0) { + if (!tags.isEmpty()) { transaction.put("tags", tags.toArray()); transaction.put("name", txFunction.getName()); txs.add(transaction); @@ -241,8 +239,6 @@ public static String getMetadata() { return metadata().toString(); } - private static final int PADDING = 3; - /** * Returns the metadata as a JSON string (spaced out for humans). * @@ -258,15 +254,14 @@ public static String debugString() { * @return JSONObject of the metadata */ private static JSONObject metadata() { - final HashMap metadata = new HashMap(); + final Map metadata = new HashMap<>(); metadata.put("$schema", "https://fabric-shim.github.io/release-1.4/contract-schema.json"); metadata.put("info", overallInfoMap); metadata.put("contracts", contractMap); metadata.put("components", Collections.singletonMap("schemas", componentMap)); - final JSONObject joMetadata = new JSONObject(metadata); - return joMetadata; + return new JSONObject(metadata); } /** @return All the components indexed by name */ diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java index 79453428..b3cfe1f8 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java @@ -9,6 +9,7 @@ import java.lang.reflect.Array; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.everit.json.schema.Schema; import org.everit.json.schema.ValidationException; import org.everit.json.schema.loader.SchemaLoader; @@ -24,12 +25,16 @@ * *

Does not include the "schema" top level map */ -@SuppressWarnings("serial") +@SuppressWarnings({"PMD.LooseCoupling", "PMD.GodClass"}) public final class TypeSchema extends HashMap { - private static Logger logger = Logger.getLogger(TypeSchema.class.getName()); + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(TypeSchema.class.getName()); - /** */ - public TypeSchema() {} + private static final String SCHEMA_PROP = "schema"; + private static final String TYPE_PROP = "type"; + private static final String ITEMS_PROP = "items"; + private static final String FORMAT_PROP = "format"; + private static final String INTEGER_TYPE = "integer"; private Object putInternal(final String key, final Object value) { if (value != null && !value.toString().isEmpty()) { @@ -57,26 +62,26 @@ TypeSchema[] putIfNotNull(final String key, final TypeSchema[] value) { /** @return Return Type String */ public String getType() { - if (this.containsKey("schema")) { - final Map intermediateMap = (Map) this.get("schema"); - return (String) intermediateMap.get("type"); + if (this.containsKey(SCHEMA_PROP)) { + final Map intermediateMap = (Map) this.get(SCHEMA_PROP); + return (String) intermediateMap.get(TYPE_PROP); } - return (String) this.get("type"); + return (String) this.get(TYPE_PROP); } /** @return TypeSchema items */ public TypeSchema getItems() { - if (this.containsKey("schema")) { - final Map intermediateMap = (Map) this.get("schema"); - return (TypeSchema) intermediateMap.get("items"); + if (this.containsKey(SCHEMA_PROP)) { + final Map intermediateMap = (Map) this.get(SCHEMA_PROP); + return (TypeSchema) intermediateMap.get(ITEMS_PROP); } - return (TypeSchema) this.get("items"); + return (TypeSchema) this.get(ITEMS_PROP); } /** @return Reference */ public String getRef() { - if (this.containsKey("schema")) { - final Map intermediateMap = (Map) this.get("schema"); + if (this.containsKey(SCHEMA_PROP)) { + final Map intermediateMap = (Map) this.get(SCHEMA_PROP); return (String) intermediateMap.get("$ref"); } return (String) this.get("$ref"); @@ -84,11 +89,11 @@ public String getRef() { /** @return Format */ public String getFormat() { - if (this.containsKey("schema")) { - final Map intermediateMap = (Map) this.get("schema"); - return (String) intermediateMap.get("format"); + if (this.containsKey(SCHEMA_PROP)) { + final Map intermediateMap = (Map) this.get(SCHEMA_PROP); + return (String) intermediateMap.get(FORMAT_PROP); } - return (String) this.get("format"); + return (String) this.get(FORMAT_PROP); } /** @@ -96,65 +101,71 @@ public String getFormat() { * @return Class object */ public Class getTypeClass(final TypeRegistry typeRegistry) { - Class clz = null; - String type = getType(); - if (type == null) { - type = "object"; + String type = Optional.ofNullable(getType()).orElse("object"); + + switch (type) { + case "object": + return getObjectClass(typeRegistry); + case "string": + return getStringClass(); + case INTEGER_TYPE: + return getIntegerClass(); + case "number": + return getNumberClass(); + case "boolean": + return boolean.class; + case "array": + return getArrayClass(typeRegistry); + default: + return null; } + } - if (type.contentEquals("string")) { - final String format = getFormat(); - if (format != null && format.contentEquals("uint16")) { - clz = char.class; - } else { - clz = String.class; - } + private Class getArrayClass(final TypeRegistry typeRegistry) { + final TypeSchema typdef = this.getItems(); + final Class arrayType = typdef.getTypeClass(typeRegistry); + return Array.newInstance(arrayType, 0).getClass(); + } - } else if (type.contentEquals("integer")) { - // need to check the format - final String format = getFormat(); - switch (format) { - case "int8": - clz = byte.class; - break; - case "int16": - clz = short.class; - break; - case "int32": - clz = int.class; - break; - case "int64": - clz = long.class; - break; - default: - throw new RuntimeException("Unknown format for integer of " + format); - } - } else if (type.contentEquals("number")) { - // need to check the format - final String format = getFormat(); - switch (format) { - case "double": - clz = double.class; - break; - case "float": - clz = float.class; - break; - default: - throw new RuntimeException("Unknown format for number of " + format); - } - } else if (type.contentEquals("boolean")) { - clz = boolean.class; - } else if (type.contentEquals("object")) { - final String ref = this.getRef(); - final String format = ref.substring(ref.lastIndexOf("/") + 1); - clz = typeRegistry.getDataType(format).getTypeClass(); - } else if (type.contentEquals("array")) { - final TypeSchema typdef = this.getItems(); - final Class arrayType = typdef.getTypeClass(typeRegistry); - clz = Array.newInstance(arrayType, 0).getClass(); + private Class getNumberClass() { + switch (getFormat()) { + case "double": + return double.class; + case "float": + return float.class; + default: + throw new IllegalArgumentException("Unknown format for number of " + getFormat()); } + } - return clz; + private Class getIntegerClass() { + // need to check the format + switch (getFormat()) { + case "int8": + return byte.class; + case "int16": + return short.class; + case "int32": + return int.class; + case "int64": + return long.class; + default: + throw new IllegalArgumentException("Unknown format for integer of " + getFormat()); + } + } + + @SuppressWarnings("PMD.AvoidLiteralsInIfCondition") + private Class getStringClass() { + if ("uint16".equals(getFormat())) { + return char.class; + } + return String.class; + } + + private Class getObjectClass(final TypeRegistry typeRegistry) { + final String ref = this.getRef(); + final String format = ref.substring(ref.lastIndexOf('/') + 1); + return typeRegistry.getDataType(format).getTypeClass(); } /** @@ -163,26 +174,27 @@ public Class getTypeClass(final TypeRegistry typeRegistry) { * @param clz * @return TypeSchema */ + @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull") public static TypeSchema typeConvert(final Class clz) { - final TypeSchema returnschema = new TypeSchema(); String className = clz.getTypeName(); - if (className == "void") { + if ("void".equals(className)) { return null; } - TypeSchema schema; + final TypeSchema returnschema = new TypeSchema(); + final TypeSchema schema; if (clz.isArray()) { - returnschema.put("type", "array"); + returnschema.put(TYPE_PROP, "array"); schema = new TypeSchema(); // double check the componentType final Class componentClass = clz.getComponentType(); if (componentClass.isArray()) { // nested arrays - returnschema.put("items", TypeSchema.typeConvert(componentClass)); + returnschema.put(ITEMS_PROP, typeConvert(componentClass)); } else { - returnschema.put("items", schema); + returnschema.put(ITEMS_PROP, schema); } className = componentClass.getTypeName(); @@ -192,46 +204,46 @@ public static TypeSchema typeConvert(final Class clz) { switch (className) { case "java.lang.String": - schema.put("type", "string"); + schema.put(TYPE_PROP, "string"); break; case "char": case "java.lang.Character": - schema.put("type", "string"); - schema.put("format", "uint16"); + schema.put(TYPE_PROP, "string"); + schema.put(FORMAT_PROP, "uint16"); break; case "byte": case "java.lang.Byte": - schema.put("type", "integer"); - schema.put("format", "int8"); + schema.put(TYPE_PROP, INTEGER_TYPE); + schema.put(FORMAT_PROP, "int8"); break; case "short": case "java.lang.Short": - schema.put("type", "integer"); - schema.put("format", "int16"); + schema.put(TYPE_PROP, INTEGER_TYPE); + schema.put(FORMAT_PROP, "int16"); break; case "int": case "java.lang.Integer": - schema.put("type", "integer"); - schema.put("format", "int32"); + schema.put(TYPE_PROP, INTEGER_TYPE); + schema.put(FORMAT_PROP, "int32"); break; case "long": case "java.lang.Long": - schema.put("type", "integer"); - schema.put("format", "int64"); + schema.put(TYPE_PROP, INTEGER_TYPE); + schema.put(FORMAT_PROP, "int64"); break; case "double": case "java.lang.Double": - schema.put("type", "number"); - schema.put("format", "double"); + schema.put(TYPE_PROP, "number"); + schema.put(FORMAT_PROP, "double"); break; case "float": case "java.lang.Float": - schema.put("type", "number"); - schema.put("format", "float"); + schema.put(TYPE_PROP, "number"); + schema.put(FORMAT_PROP, "float"); break; case "boolean": case "java.lang.Boolean": - schema.put("type", "boolean"); + schema.put(TYPE_PROP, "boolean"); break; default: schema.put("$ref", "#/components/schemas/" + className.substring(className.lastIndexOf('.') + 1)); @@ -252,8 +264,8 @@ public void validate(final JSONObject obj) { toValidate.put("prop", obj); JSONObject schemaJSON; - if (this.containsKey("schema")) { - schemaJSON = new JSONObject((Map) this.get("schema")); + if (this.containsKey(SCHEMA_PROP)) { + schemaJSON = new JSONObject((Map) this.get(SCHEMA_PROP)); } else { schemaJSON = new JSONObject(this); } @@ -269,8 +281,9 @@ public void validate(final JSONObject obj) { e.getCausingExceptions().stream() .map(ValidationException::getMessage) .forEach(sb::append); - logger.info(sb.toString()); - throw new ContractRuntimeException(sb.toString(), e); + String message = sb.toString(); + LOGGER.info(message); + throw new ContractRuntimeException(message, e); } } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ContractDefinitionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ContractDefinitionImpl.java index 056b3abc..8df5f3ab 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ContractDefinitionImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ContractDefinitionImpl.java @@ -24,20 +24,20 @@ *

Contains information about the contract, including transaction functions and unknown transaction routing */ public final class ContractDefinitionImpl implements ContractDefinition { - private static Logger logger = Logger.getLogger(ContractDefinitionImpl.class); + private static final Logger LOGGER = Logger.getLogger(ContractDefinitionImpl.class); private final Map txFunctions = new HashMap<>(); - private String name; + private final String name; private final boolean isDefault; private final Class contractClz; private final Contract contractAnnotation; - private TxFunction unknownTx; + private final TxFunction unknownTx; /** @param cl */ public ContractDefinitionImpl(final Class cl) { final Contract annotation = cl.getAnnotation(Contract.class); - logger.debug(() -> "Class Contract Annotation: " + annotation); + LOGGER.debug(() -> "Class Contract Annotation: " + annotation); final String annotationName = annotation.name(); @@ -52,18 +52,18 @@ public ContractDefinitionImpl(final Class cl) { contractClz = cl; try { - final Method m = cl.getMethod("unknownTransaction", new Class[] {Context.class}); + final Method m = cl.getMethod("unknownTransaction", Context.class); unknownTx = new TxFunctionImpl(m, this); unknownTx.setUnknownTx(true); } catch (NoSuchMethodException | SecurityException e) { final ContractRuntimeException cre = new ContractRuntimeException("Failure to find unknownTransaction method", e); - logger.severe(() -> logger.formatError(cre)); + LOGGER.severe(() -> LOGGER.formatError(cre)); throw cre; } - logger.info(() -> "Found class: " + cl.getCanonicalName()); - logger.debug(() -> "Namespace: " + this.name); + LOGGER.info(() -> "Found class: " + cl.getCanonicalName()); + LOGGER.debug(() -> "Namespace: " + this.name); } @Override @@ -83,13 +83,13 @@ public Class getContractImpl() { @Override public TxFunction addTxFunction(final Method m) { - logger.debug(() -> "Adding method " + m.getName()); + LOGGER.debug(() -> "Adding method " + m.getName()); final TxFunction txFn = new TxFunctionImpl(m, this); final TxFunction previousTxnFn = txFunctions.put(txFn.getName(), txFn); if (previousTxnFn != null) { final String message = String.format("Duplicate transaction method %s", previousTxnFn.getName()); final ContractRuntimeException cre = new ContractRuntimeException(message); - logger.severe(() -> logger.formatError(cre)); + LOGGER.severe(() -> LOGGER.formatError(cre)); throw cre; } return txFn; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/DataTypeDefinitionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/DataTypeDefinitionImpl.java index 5165bfbf..8d1ed867 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/DataTypeDefinitionImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/DataTypeDefinitionImpl.java @@ -7,6 +7,7 @@ import java.lang.reflect.Field; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.stream.Stream; import org.hyperledger.fabric.contract.annotation.Property; @@ -22,6 +23,7 @@ public final class DataTypeDefinitionImpl implements DataTypeDefinition { private final Class clazz; /** @param componentClass */ + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") public DataTypeDefinitionImpl(final Class componentClass) { this.clazz = componentClass; this.name = componentClass.getName(); @@ -39,7 +41,7 @@ public DataTypeDefinitionImpl(final Class componentClass) { for (int i = 0; i < userSupplied.length; i += 2) { final String userKey = userSupplied[i]; Object userValue; - switch (userKey.toLowerCase()) { + switch (userKey.toLowerCase(Locale.getDefault())) { case "title": case "pattern": userValue = userSupplied[i + 1]; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/RoutingRegistryImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/RoutingRegistryImpl.java index 5996137c..49180d38 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/RoutingRegistryImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/RoutingRegistryImpl.java @@ -96,8 +96,7 @@ public TxFunction.Routing getRoute(final InvocationRequest request) { @Override public TxFunction getTxFn(final InvocationRequest request) { - final TxFunction txFunction = contracts.get(request.getNamespace()).getTxFunction(request.getMethod()); - return txFunction; + return contracts.get(request.getNamespace()).getTxFunction(request.getMethod()); } /* @@ -145,7 +144,7 @@ public void findAndSetContracts(final TypeRegistry typeRegistry) { final List> dataTypeClasses = new ArrayList<>(); try (ScanResult scanResult = classGraph.scan()) { for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(Contract.class.getCanonicalName())) { - logger.debug("Found class with contract annotation: " + classInfo.getName()); + logger.debug(() -> "Found class with contract annotation: " + classInfo.getName()); try { final Class contractClass = classInfo.loadClass(); logger.debug("Loaded class"); @@ -155,18 +154,18 @@ public void findAndSetContracts(final TypeRegistry typeRegistry) { // compatible, // and not some random class with the same name. logger.debug("Class does not have compatible contract annotation"); - } else if (!ContractInterface.class.isAssignableFrom(contractClass)) { - logger.debug("Class is not assignable from ContractInterface"); - } else { + } else if (ContractInterface.class.isAssignableFrom(contractClass)) { logger.debug("Class is assignable from ContractInterface"); contractClasses.add((Class) contractClass); + } else { + logger.debug("Class is not assignable from ContractInterface"); } } catch (final IllegalArgumentException e) { - logger.debug("Failed to load class: " + e); + logger.debug(() -> "Failed to load class: " + e); } } for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(DataType.class.getCanonicalName())) { - logger.debug("Found class with data type annotation: " + classInfo.getName()); + logger.debug(() -> "Found class with data type annotation: " + classInfo.getName()); try { final Class dataTypeClass = classInfo.loadClass(); logger.debug("Loaded class"); @@ -181,7 +180,7 @@ public void findAndSetContracts(final TypeRegistry typeRegistry) { dataTypeClasses.add(dataTypeClass); } } catch (final IllegalArgumentException e) { - logger.debug("Failed to load class: " + e); + logger.debug(() -> "Failed to load class: " + e); } } } @@ -206,7 +205,7 @@ private void addContracts(final List> contractClasses) logger.debug("Searching annotated methods"); for (final Method m : contractClass.getMethods()) { if (m.getAnnotation(Transaction.class) != null) { - logger.debug("Found annotated method " + m.getName()); + logger.debug(() -> "Found annotated method " + m.getName()); contract.addTxFunction(m); } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java index 3e7c1f74..728966f0 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java @@ -22,13 +22,10 @@ *

It holds the serializers that have been defined. JSONTransactionSerializer is the default. */ public class SerializerRegistryImpl { - private static Logger logger = Logger.getLogger(SerializerRegistryImpl.class); + private static final Logger LOGGER = Logger.getLogger(SerializerRegistryImpl.class); private final Class annotationClass = Serializer.class; - /** */ - public SerializerRegistryImpl() {} - // Could index these by name and or type. private final Map contents = new HashMap<>(); @@ -45,17 +42,14 @@ public SerializerInterface getSerializer(final String name, final Serializer.TAR } private SerializerInterface add( - final String name, final Serializer.TARGET target, final Class clazz) { - logger.debug(() -> "Adding new Class " + clazz.getCanonicalName() + " for " + target); - try { - final String key = name + ":" + target; - final SerializerInterface newObj = clazz.newInstance(); - this.contents.put(key, newObj); + final String name, final Serializer.TARGET target, final Class clazz) + throws InstantiationException, IllegalAccessException { + LOGGER.debug(() -> "Adding new Class " + clazz.getCanonicalName() + " for " + target); + final String key = name + ":" + target; + final SerializerInterface newObj = clazz.newInstance(); + this.contents.put(key, newObj); - return newObj; - } catch (InstantiationException | IllegalAccessException e) { - throw new RuntimeException(e); - } + return newObj; } /** @@ -75,19 +69,14 @@ public void findAndSetContents() throws InstantiationException, IllegalAccessExc try (ScanResult scanResult = classGraph.scan()) { for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(this.annotationClass.getCanonicalName())) { - logger.debug("Found class with contract annotation: " + classInfo.getName()); - try { - final Class cls = (Class) classInfo.loadClass(); - logger.debug("Loaded class"); - - final String className = cls.getCanonicalName(); - if (!seenClass.contains(className)) { - seenClass.add(className); - this.add(className, Serializer.TARGET.TRANSACTION, cls); - } + LOGGER.debug(() -> "Found class with contract annotation: " + classInfo.getName()); + final Class cls = (Class) classInfo.loadClass(); + LOGGER.debug("Loaded class"); - } catch (final IllegalArgumentException e) { - logger.debug("Failed to load class: " + e); + final String className = cls.getCanonicalName(); + if (!seenClass.contains(className)) { + seenClass.add(className); + this.add(className, Serializer.TARGET.TRANSACTION, cls); } } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TxFunctionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TxFunctionImpl.java index 3f61350a..26f336f5 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TxFunctionImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TxFunctionImpl.java @@ -7,9 +7,10 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; +import java.lang.reflect.Parameter; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.hyperledger.fabric.Logger; import org.hyperledger.fabric.contract.Context; import org.hyperledger.fabric.contract.ContractInterface; @@ -23,18 +24,17 @@ import org.hyperledger.fabric.contract.routing.TxFunction; public final class TxFunctionImpl implements TxFunction { - private static Logger logger = Logger.getLogger(TxFunctionImpl.class); + private static final Logger LOGGER = Logger.getLogger(TxFunctionImpl.class); private final Method method; private String name; private TransactionType type; - private TransactionType typeDeprecated; private final Routing routing; private TypeSchema returnSchema; - private List paramsList = new ArrayList<>(); + private List paramsList; private boolean isUnknownTx; - public final class RoutingImpl implements Routing { + public static final class RoutingImpl implements Routing { private final Method method; private final Class clazz; @@ -88,7 +88,7 @@ public TxFunctionImpl(final Method m, final ContractDefinition contract) { this.method = m; if (m.getAnnotation(Transaction.class) != null) { - logger.debug("Found Transaction method: " + m.getName()); + LOGGER.debug(() -> "Found Transaction method: " + m.getName()); if (m.getAnnotation(Transaction.class).intent() == Transaction.TYPE.SUBMIT) { this.type = TransactionType.SUBMIT; } else { @@ -113,18 +113,18 @@ public TxFunctionImpl(final Method m, final ContractDefinition contract) { this.returnSchema = TypeSchema.typeConvert(m.getReturnType()); // parameter processing - final List params = - new ArrayList(Arrays.asList(method.getParameters())); + this.paramsList = buildParameters(m); + } + private List buildParameters(final Method m) { + Parameter[] params = m.getParameters(); // validate the first one is a context object - if (params.size() == 0) { + if (params.length == 0) { throw new ContractRuntimeException("First argument should be of type Context"); - } else if (!Context.class.isAssignableFrom(params.get(0).getType())) { - throw new ContractRuntimeException("First argument should be of type Context " + method.getName() + " " - + params.get(0).getType()); - } else { - - params.remove(0); + } + if (!Context.class.isAssignableFrom(params[0].getType())) { + throw new ContractRuntimeException( + "First argument should be of type Context " + m.getName() + " " + params[0].getType()); } // FUTURE: if ever the method of creating the instance where to change, @@ -132,25 +132,27 @@ public TxFunctionImpl(final Method m, final ContractDefinition contract) { // here encapsulating the change. eg use an annotation to define where the // context goes - for (final java.lang.reflect.Parameter parameter : params) { - final TypeSchema paramMap = new TypeSchema(); - final TypeSchema schema = TypeSchema.typeConvert(parameter.getType()); - - final Property annotation = - parameter.getAnnotation(org.hyperledger.fabric.contract.annotation.Property.class); - if (annotation != null) { - final String[] userSupplied = annotation.schema(); - for (int i = 0; i < userSupplied.length; i += 2) { - schema.put(userSupplied[i], userSupplied[i + 1]); - } - } + return Arrays.stream(params) + .skip(1) + .map(TxFunctionImpl::newParameterDefinition) + .collect(Collectors.toList()); + } + + private static ParameterDefinitionImpl newParameterDefinition(final Parameter parameter) { + final TypeSchema paramMap = new TypeSchema(); + final TypeSchema schema = TypeSchema.typeConvert(parameter.getType()); - paramMap.put("name", parameter.getName()); - paramMap.put("schema", schema); - final ParameterDefinition pd = - new ParameterDefinitionImpl(parameter.getName(), parameter.getClass(), paramMap, parameter); - paramsList.add(pd); + final Property annotation = parameter.getAnnotation(Property.class); + if (annotation != null) { + final String[] userSupplied = annotation.schema(); + for (int i = 0; i < userSupplied.length; i += 2) { + schema.put(userSupplied[i], userSupplied[i + 1]); + } } + + paramMap.put("name", parameter.getName()); + paramMap.put("schema", schema); + return new ParameterDefinitionImpl(parameter.getName(), parameter.getClass(), paramMap, parameter); } @Override @@ -169,7 +171,7 @@ public Class getReturnType() { } @Override - public java.lang.reflect.Parameter[] getParameters() { + public Parameter[] getParameters() { return method.getParameters(); } @@ -194,7 +196,7 @@ public List getParamsList() { } /** @param paramsList */ - public void setParamsList(final ArrayList paramsList) { + public void setParamsList(final List paramsList) { this.paramsList = paramsList; } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TypeRegistryImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TypeRegistryImpl.java index 07377c77..54d2e995 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TypeRegistryImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TypeRegistryImpl.java @@ -14,8 +14,9 @@ /** Registry to hold the complex data types as defined in the contract. */ public final class TypeRegistryImpl implements TypeRegistry { + private static final TypeRegistryImpl INSTANCE = new TypeRegistryImpl(); - private static TypeRegistryImpl singletonInstance; + private final Map components = new HashMap<>(); /** * Get the TypeRegistry singleton instance. @@ -23,15 +24,9 @@ public final class TypeRegistryImpl implements TypeRegistry { * @return TypeRegistry */ public static TypeRegistry getInstance() { - if (singletonInstance == null) { - singletonInstance = new TypeRegistryImpl(); - } - - return singletonInstance; + return INSTANCE; } - private final Map components = new HashMap<>(); - /* * (non-Javadoc) * @@ -68,7 +63,7 @@ public DataTypeDefinition getDataType(final String name) { @Override public DataTypeDefinition getDataType(final TypeSchema schema) { final String ref = schema.getRef(); - final String format = ref.substring(ref.lastIndexOf("/") + 1); + final String format = ref.substring(ref.lastIndexOf('/') + 1); return getDataType(format); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/SystemContract.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/SystemContract.java index 74fd07ab..762efe66 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/SystemContract.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/SystemContract.java @@ -21,16 +21,12 @@ description = "Provides information about the contracts within this container")) public final class SystemContract implements ContractInterface { - /** */ - public SystemContract() {} - /** * @param ctx * @return Metadata */ - @Transaction(submit = false, name = "GetMetadata") + @Transaction(intent = Transaction.TYPE.EVALUATE, name = "GetMetadata") public String getMetadata(final Context ctx) { - final String jsonmetadata = MetadataBuilder.getMetadata(); - return jsonmetadata; + return MetadataBuilder.getMetadata(); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Ledger.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Ledger.java index 3f9c11cc..1d97ec71 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Ledger.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Ledger.java @@ -33,7 +33,6 @@ public interface Ledger { static Ledger getLedger(final Context ctx) { return new LedgerImpl(ctx); } - ; /** * Return the a collection based on the supplied name. diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/CollectionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/CollectionImpl.java deleted file mode 100644 index c313ef77..00000000 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/CollectionImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020 IBM All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.fabric.ledger.impl; - -import org.hyperledger.fabric.ledger.Collection; - -/** Placeholder. */ -public class CollectionImpl implements Collection { - - private final String name; - - /** - * @param name - * @param ledgerImpl - */ - public CollectionImpl(final String name, final LedgerImpl ledgerImpl) { - this.name = name; - } - - @Override - public void placeholder() { - // TODO Auto-generated method stub - - } -} diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/LedgerImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/LedgerImpl.java index 9f8ed761..5d204ba2 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/LedgerImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/LedgerImpl.java @@ -8,26 +8,27 @@ import org.hyperledger.fabric.contract.Context; import org.hyperledger.fabric.ledger.Collection; import org.hyperledger.fabric.ledger.Ledger; -import org.hyperledger.fabric.shim.ChaincodeStub; public final class LedgerImpl implements Ledger { - // The Chaincode Stub or SPI to provide access to the underlying Fabric - // APIs - private final ChaincodeStub stub; - /** * New Ledger Implementation. * * @param ctx Context transactional context to use */ + @SuppressWarnings("PMD.UnusedFormalParameter") public LedgerImpl(final Context ctx) { - this.stub = ctx.getStub(); + // Empty stub } @Override public Collection getCollection(final String name) { - return new CollectionImpl(name, this); + return new Collection() { + @Override + public void placeholder() { + // Empty stub + } + }; } @Override diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/Metrics.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/Metrics.java index 74cd6247..b13e3708 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/Metrics.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/Metrics.java @@ -5,7 +5,6 @@ */ package org.hyperledger.fabric.metrics; -import java.lang.reflect.InvocationTargetException; import java.util.Properties; import java.util.logging.Logger; import org.hyperledger.fabric.metrics.impl.DefaultProvider; @@ -32,6 +31,7 @@ private Metrics() {} * @param props * @return The metrics provide */ + @SuppressWarnings("PMD.AvoidCatchingGenericException") public static MetricsProvider initialize(final Properties props) { if (Boolean.parseBoolean((String) props.get(CHAINCODE_METRICS_ENABLED))) { try { @@ -46,14 +46,8 @@ public static MetricsProvider initialize(final Properties props) { logger.info("Using default metrics provider (logs to org.hyperledger.Performance)"); provider = new DefaultProvider(); } - } catch (ClassNotFoundException - | InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException e) { - throw new RuntimeException("Unable to start metrics", e); + } catch (Exception e) { + throw new IllegalStateException("Unable to start metrics", e); } } else { // return a 'null' provider diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/MetricsProvider.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/MetricsProvider.java index 9609ea87..aa726b96 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/MetricsProvider.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/MetricsProvider.java @@ -28,8 +28,9 @@ public interface MetricsProvider { * * @param props */ - default void initialize(final Properties props) {} - ; + default void initialize(final Properties props) { + // Do nothing by default + } /** * Pass a reference to this task service for information gathering. This is related specifically to the handling of @@ -37,6 +38,7 @@ default void initialize(final Properties props) {} * * @param taskService */ - default void setTaskMetricsCollector(final TaskMetricsCollector taskService) {} - ; + default void setTaskMetricsCollector(final TaskMetricsCollector taskService) { + // Do nothing by default + } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/DefaultProvider.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/DefaultProvider.java index 841e4164..3f34028d 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/DefaultProvider.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/DefaultProvider.java @@ -15,13 +15,14 @@ /** Simple default provider that logs to the org.hyperledger.Performance logger the basic metrics. */ public final class DefaultProvider implements MetricsProvider { - private static Logger perflogger = Logger.getLogger(Logging.PERFLOGGER); + private static final Logger PERFLOGGER = Logger.getLogger(Logging.PERFLOGGER); + private static final int TIME_INTERVAL = 5000; private TaskMetricsCollector taskService; /** */ public DefaultProvider() { - perflogger.info("Default Metrics Provider started"); + PERFLOGGER.info("Default Metrics Provider started"); } @Override @@ -29,8 +30,6 @@ public void setTaskMetricsCollector(final TaskMetricsCollector taskService) { this.taskService = taskService; } - private static final int TIME_INTERVAL = 5000; - @Override public void initialize(final Properties props) { final Timer metricTimer = new Timer(true); @@ -45,26 +44,22 @@ public void run() { TIME_INTERVAL); } - protected void logMetrics() { - - perflogger.info(() -> { - if (DefaultProvider.this.taskService == null) { + void logMetrics() { + PERFLOGGER.info(() -> { + if (taskService == null) { return "No Metrics Provider service yet"; } - final StringBuilder sb = new StringBuilder(); - sb.append('{'); - sb.append(String.format(" \"active_count\":%d ", DefaultProvider.this.taskService.getActiveCount())) - .append(','); - sb.append(String.format(" \"pool_size\":%d ", DefaultProvider.this.taskService.getPoolSize())) - .append(','); - sb.append(String.format(" \"core_pool_size\":%d ", DefaultProvider.this.taskService.getCorePoolSize())) - .append(','); - sb.append(String.format( - " \"current_task_count\":%d ", DefaultProvider.this.taskService.getCurrentTaskCount())) - .append(','); - sb.append(String.format( - " \"current_queue_depth\":%d ", DefaultProvider.this.taskService.getCurrentQueueCount())); - return sb.append('}').toString(); + return '{' + + String.format(" \"active_count\":%d ", taskService.getActiveCount()) + + ',' + + String.format(" \"pool_size\":%d ", taskService.getPoolSize()) + + ',' + + String.format(" \"core_pool_size\":%d ", taskService.getCorePoolSize()) + + ',' + + String.format(" \"current_task_count\":%d ", taskService.getCurrentTaskCount()) + + ',' + + String.format(" \"current_queue_depth\":%d ", taskService.getCurrentQueueCount()) + + '}'; }); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/NullProvider.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/NullProvider.java index 19639009..35be1fa6 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/NullProvider.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/NullProvider.java @@ -8,8 +8,4 @@ import org.hyperledger.fabric.metrics.MetricsProvider; /** Very simple provider that does absolutely nothing. Used when metrics are disabled. */ -public class NullProvider implements MetricsProvider { - - /** */ - public NullProvider() {} -} +public class NullProvider implements MetricsProvider {} diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/Chaincode.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/Chaincode.java index b8882487..2eca580b 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/Chaincode.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/Chaincode.java @@ -46,6 +46,7 @@ class Response { * @param message a response message. * @param payload a response payload. */ + @SuppressWarnings("PMD.ArrayIsStoredDirectly") public Response(final Status status, final String message, final byte[] payload) { this.statusCode = status.getCode(); this.message = message; @@ -59,6 +60,7 @@ public Response(final Status status, final String message, final byte[] payload) * @param message a response message. * @param payload a response payload. */ + @SuppressWarnings("PMD.ArrayIsStoredDirectly") public Response(final int statusCode, final String message, final byte[] payload) { this.statusCode = statusCode; this.message = message; @@ -164,7 +166,7 @@ public static boolean hasStatusForCode(final int code) { } static { - for (final Status status : Status.values()) { + for (final Status status : values()) { CODETOSTATUS.put(status.code, status); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java index 0ce76bc4..5f73f110 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java @@ -6,7 +6,6 @@ package org.hyperledger.fabric.shim; -import static java.lang.String.format; import static java.util.logging.Level.ALL; import com.google.protobuf.InvalidProtocolBufferException; @@ -29,6 +28,7 @@ import java.nio.file.Paths; import java.security.Security; import java.util.Base64; +import java.util.Locale; import java.util.Properties; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -56,6 +56,7 @@ * * @see org.hyperledger.fabric.contract */ +@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.GodClass"}) public abstract class ChaincodeBase implements Chaincode { /** */ @@ -64,12 +65,6 @@ public abstract class ChaincodeBase implements Chaincode { /** */ public static final String CORE_CHAINCODE_LOGGING_LEVEL = "CORE_CHAINCODE_LOGGING_LEVEL"; - @Override - public abstract Response init(ChaincodeStub stub); - - @Override - public abstract Response invoke(ChaincodeStub stub); - private static final Logger LOGGER = Logger.getLogger(ChaincodeBase.class.getName()); /** */ @@ -83,7 +78,7 @@ public abstract class ChaincodeBase implements Chaincode { private String host = DEFAULT_HOST; private int port = DEFAULT_PORT; - private boolean tlsEnabled = false; + private boolean tlsEnabled; private String tlsClientKeyPath; private String tlsClientCertPath; private String tlsClientKeyFile; @@ -107,11 +102,18 @@ public abstract class ChaincodeBase implements Chaincode { private static final String MAX_INBOUND_MESSAGE_SIZE = "MAX_INBOUND_MESSAGE_SIZE"; private Properties props; private Level logLevel; + private CCState state = CCState.CREATED; static { Security.addProvider(new BouncyCastleProvider()); } + @Override + public abstract Response init(ChaincodeStub stub); + + @Override + public abstract Response invoke(ChaincodeStub stub); + private int getMaxInboundMessageSize() { if (this.props == null) { throw new IllegalStateException("Chaincode config not available"); @@ -278,7 +280,7 @@ protected final void initializeLogging() { handler.setFormatter(new SimpleFormatter() { @Override - public synchronized String format(final LogRecord record) { + public String format(final LogRecord record) { return Thread.currentThread() + " " + super.format(record); } }); @@ -307,7 +309,7 @@ public synchronized String format(final LogRecord record) { private Level mapLevel(final String level) { if (level != null) { - switch (level.toUpperCase().trim()) { + switch (level.toUpperCase(Locale.getDefault()).trim()) { case "CRITICAL": case "ERROR": return Level.SEVERE; @@ -352,24 +354,25 @@ public boolean isServer() { } /** Validate init parameters from env chaincode base. */ + @SuppressWarnings("PMD.CyclomaticComplexity") public void validateOptions() { if (this.id == null || this.id.isEmpty()) { - throw new IllegalArgumentException(format( + throw new IllegalArgumentException(String.format( "The chaincode id must be specified using either the -i or --i command line options or the %s environment variable.", CORE_CHAINCODE_ID_NAME)); } if (this.tlsEnabled) { if (tlsClientCertPath == null) { - throw new IllegalArgumentException( - format("Client key certificate chain (%s) was not specified.", ENV_TLS_CLIENT_CERT_PATH)); + throw new IllegalArgumentException(String.format( + "Client key certificate chain (%s) was not specified.", ENV_TLS_CLIENT_CERT_PATH)); } if (tlsClientKeyPath == null) { throw new IllegalArgumentException( - format("Client key (%s) was not specified.", ENV_TLS_CLIENT_KEY_PATH)); + String.format("Client key (%s) was not specified.", ENV_TLS_CLIENT_KEY_PATH)); } if (tlsClientRootCertPath == null) { - throw new IllegalArgumentException( - format("Peer certificate trust store (%s) was not specified.", CORE_PEER_TLS_ROOTCERT_FILE)); + throw new IllegalArgumentException(String.format( + "Peer certificate trust store (%s) was not specified.", CORE_PEER_TLS_ROOTCERT_FILE)); } } } @@ -391,7 +394,7 @@ protected final void processCommandLineOptions(final String[] args) { } final String[] hostArr = hostAddrStr.split(":"); if (hostArr.length == 2) { - port = Integer.valueOf(hostArr[1].trim()); + port = Integer.parseInt(hostArr[1].trim()); host = hostArr[0].trim(); } else { final String msg = String.format( @@ -407,9 +410,9 @@ protected final void processCommandLineOptions(final String[] args) { LOGGER.warning(() -> "cli parsing failed with exception" + Logging.formatError(e)); } - LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); - LOGGER.info("CORE_CHAINCODE_ID_NAME: " + this.id); - LOGGER.info("CORE_PEER_ADDRESS: " + this.host + ":" + this.port); + LOGGER.info(() -> "<<<<<<<<<<<<>>>>>>>>>>>" + "\nCORE_CHAINCODE_ID_NAME: " + + this.id + "\nCORE_PEER_ADDRESS: " + + this.host + ":" + this.port); } /** set fields from env. */ @@ -421,7 +424,7 @@ public final void processEnvironmentOptions() { if (System.getenv().containsKey(CORE_PEER_ADDRESS)) { final String[] hostArr = System.getenv(CORE_PEER_ADDRESS).split(":"); if (hostArr.length == 2) { - this.port = Integer.valueOf(hostArr[1].trim()); + this.port = Integer.parseInt(hostArr[1].trim()); this.host = hostArr[0].trim(); } else { final String msg = String.format( @@ -449,18 +452,20 @@ public final void processEnvironmentOptions() { this.tlsClientCertFile = System.getenv(ENV_TLS_CLIENT_CERT_FILE); } - LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); - LOGGER.info("CORE_CHAINCODE_ID_NAME: " + this.id); - LOGGER.info("CORE_PEER_ADDRESS: " + this.host); - LOGGER.info("CORE_PEER_TLS_ENABLED: " + this.tlsEnabled); - LOGGER.info("CORE_PEER_TLS_ROOTCERT_FILE: " + this.tlsClientRootCertPath); - LOGGER.info("CORE_TLS_CLIENT_KEY_PATH: " + this.tlsClientKeyPath); - LOGGER.info("CORE_TLS_CLIENT_CERT_PATH: " + this.tlsClientCertPath); - LOGGER.info("CORE_TLS_CLIENT_KEY_FILE: " + this.tlsClientKeyFile); - LOGGER.info("CORE_TLS_CLIENT_CERT_FILE: " + this.tlsClientCertFile); - LOGGER.info("CORE_PEER_LOCALMSPID: " + this.localMspId); - LOGGER.info("CHAINCODE_SERVER_ADDRESS: " + this.chaincodeServerAddress); - LOGGER.info("LOGLEVEL: " + this.logLevel); + if (LOGGER.isLoggable(Level.INFO)) { + LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); + LOGGER.info("CORE_CHAINCODE_ID_NAME: " + this.id); + LOGGER.info("CORE_PEER_ADDRESS: " + this.host); + LOGGER.info("CORE_PEER_TLS_ENABLED: " + this.tlsEnabled); + LOGGER.info("CORE_PEER_TLS_ROOTCERT_FILE: " + this.tlsClientRootCertPath); + LOGGER.info("CORE_TLS_CLIENT_KEY_PATH: " + this.tlsClientKeyPath); + LOGGER.info("CORE_TLS_CLIENT_CERT_PATH: " + this.tlsClientCertPath); + LOGGER.info("CORE_TLS_CLIENT_KEY_FILE: " + this.tlsClientKeyFile); + LOGGER.info("CORE_TLS_CLIENT_CERT_FILE: " + this.tlsClientCertFile); + LOGGER.info("CORE_PEER_LOCALMSPID: " + this.localMspId); + LOGGER.info("CHAINCODE_SERVER_ADDRESS: " + this.chaincodeServerAddress); + LOGGER.info("LOGLEVEL: " + this.logLevel); + } } /** @@ -490,7 +495,7 @@ public Properties getChaincodeConfig() { props.setProperty(CORE_PEER_ADDRESS, this.host); LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>"); - LOGGER.info(() -> this.props.toString()); + LOGGER.info(this.props::toString); } return this.props; @@ -646,8 +651,6 @@ public enum CCState { READY } - private CCState state = CCState.CREATED; - /** @return State */ public final CCState getState() { return this.state; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeException.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeException.java index 7a4b5312..3690bddb 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeException.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeException.java @@ -62,6 +62,7 @@ public ChaincodeException(final String message, final Throwable cause) { * @param message the detail message. * @param payload the response payload. */ + @SuppressWarnings("PMD.ArrayIsStoredDirectly") public ChaincodeException(final String message, final byte[] payload) { super(message); @@ -75,6 +76,7 @@ public ChaincodeException(final String message, final byte[] payload) { * @param payload the response payload. * @param cause the cause. */ + @SuppressWarnings("PMD.ArrayIsStoredDirectly") public ChaincodeException(final String message, final byte[] payload, final Throwable cause) { super(message, cause); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java index af81bfb7..1b19c96e 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java @@ -20,10 +20,12 @@ public final class ChaincodeServerProperties { private String keyCertChainFile; private String keyFile; private String trustCertCollectionFile; - private boolean tlsEnabled = false; + private boolean tlsEnabled; /** Constructor using default configuration. */ - public ChaincodeServerProperties() {} + public ChaincodeServerProperties() { + // Nothing to do + } /** * Constructor. @@ -39,7 +41,7 @@ public ChaincodeServerProperties() {} * @param permitKeepAliveWithoutCalls whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are * no outstanding RPCs on the connection. */ - // checkstyle:ignore-next-line:ParameterNumber + @SuppressWarnings({"PMD.UnusedFormalParameter", "PMD.NullAssignment"}) public ChaincodeServerProperties( final int portChaincodeServer, final int maxInboundMetadataSize, @@ -174,6 +176,7 @@ public void setKeepAliveTimeMinutes(final int keepAliveTimeMinutes) { * * @return true if clients are allowed to send keep-alive requests without calls; otherwise false. */ + @SuppressWarnings("PMD.BooleanGetMethodName") public boolean getPermitKeepAliveWithoutCalls() { return permitKeepAliveWithoutCalls; } @@ -311,6 +314,7 @@ public void setTlsEnabled(final boolean tlsEnabled) { * * @throws IllegalArgumentException if any properties are not valid. */ + @SuppressWarnings("PMD.CyclomaticComplexity") public void validate() { if (this.getServerAddress() == null) { throw new IllegalArgumentException("chaincodeServerProperties.getServerAddress() must be set"); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeer.java index f53d0ad1..c6df3d0f 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeer.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeer.java @@ -15,9 +15,10 @@ public class ChatChaincodeWithPeer extends ChaincodeGrpc.ChaincodeImplBase { private static Logger logger = Logger.getLogger(ChatChaincodeWithPeer.class.getName()); - private ChaincodeBase chaincodeBase; + private final ChaincodeBase chaincodeBase; ChatChaincodeWithPeer(final ChaincodeBase chaincodeBase) throws IOException { + super(); if (chaincodeBase == null) { throw new IOException("chaincodeBase can't be null"); } @@ -34,6 +35,7 @@ public class ChatChaincodeWithPeer extends ChaincodeGrpc.ChaincodeImplBase { * @return */ @Override + @SuppressWarnings("PMD.AvoidCatchingGenericException") public StreamObserver connect(final StreamObserver responseObserver) { if (responseObserver == null) { return null; diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyChaincodeServer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyChaincodeServer.java index df594ed2..14679384 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyChaincodeServer.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyChaincodeServer.java @@ -33,12 +33,14 @@ public NettyChaincodeServer( * @throws IOException problem while start grpc server * @throws InterruptedException thrown when block and awaiting shutdown gprc server */ + @Override public void start() throws IOException, InterruptedException { grpcServer.start(); grpcServer.blockUntilShutdown(); } /** shutdown now grpc server. */ + @Override public void stop() { grpcServer.stop(); } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java index bb142337..00e7c2ac 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/NettyGrpcServer.java @@ -16,7 +16,9 @@ import java.io.IOException; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; +import javax.net.ssl.SSLException; /** implementation grpc server with NettyGrpcServer. */ public final class NettyGrpcServer implements GrpcServer { @@ -54,67 +56,76 @@ public NettyGrpcServer(final ChaincodeBase chaincodeBase, final ChaincodeServerP .maxInboundMessageSize(chaincodeServerProperties.getMaxInboundMessageSize()); if (chaincodeServerProperties.isTlsEnabled()) { - final File keyCertChainFile = - Paths.get(chaincodeServerProperties.getKeyCertChainFile()).toFile(); - final File keyFile = - Paths.get(chaincodeServerProperties.getKeyFile()).toFile(); - - SslContextBuilder sslContextBuilder; - if (chaincodeServerProperties.getKeyPassword() == null - || chaincodeServerProperties.getKeyPassword().isEmpty()) { - sslContextBuilder = SslContextBuilder.forServer(keyCertChainFile, keyFile); - } else { - sslContextBuilder = SslContextBuilder.forServer( - keyCertChainFile, keyFile, chaincodeServerProperties.getKeyPassword()); - } - - ApplicationProtocolConfig apn = new ApplicationProtocolConfig( - ApplicationProtocolConfig.Protocol.ALPN, - ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, - ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, - ApplicationProtocolNames.HTTP_2); - sslContextBuilder.applicationProtocolConfig(apn); - - if (chaincodeServerProperties.getTrustCertCollectionFile() != null) { - final File trustCertCollectionFile = Paths.get(chaincodeServerProperties.getTrustCertCollectionFile()) - .toFile(); - sslContextBuilder.clientAuth(ClientAuth.REQUIRE); - sslContextBuilder.trustManager(trustCertCollectionFile); - } - - serverBuilder.sslContext(sslContextBuilder.build()); + configureTls(serverBuilder, chaincodeServerProperties); } - LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>:\n"); - LOGGER.info( - "ServerAddress:" + chaincodeServerProperties.getServerAddress().toString()); - LOGGER.info("MaxInboundMetadataSize:" + chaincodeServerProperties.getMaxInboundMetadataSize()); - LOGGER.info("MaxInboundMessageSize:" + chaincodeServerProperties.getMaxInboundMessageSize()); - LOGGER.info("MaxConnectionAgeSeconds:" + chaincodeServerProperties.getMaxConnectionAgeSeconds()); - LOGGER.info("KeepAliveTimeoutSeconds:" + chaincodeServerProperties.getKeepAliveTimeoutSeconds()); - LOGGER.info("PermitKeepAliveTimeMinutes:" + chaincodeServerProperties.getPermitKeepAliveTimeMinutes()); - LOGGER.info("KeepAliveTimeMinutes:" + chaincodeServerProperties.getKeepAliveTimeMinutes()); - LOGGER.info("PermitKeepAliveWithoutCalls:" + chaincodeServerProperties.getPermitKeepAliveWithoutCalls()); - LOGGER.info("KeyPassword:" + chaincodeServerProperties.getKeyPassword()); - LOGGER.info("KeyCertChainFile:" + chaincodeServerProperties.getKeyCertChainFile()); - LOGGER.info("KeyFile:" + chaincodeServerProperties.getKeyFile()); - LOGGER.info("isTlsEnabled:" + chaincodeServerProperties.isTlsEnabled()); - LOGGER.info("\n"); + if (LOGGER.isLoggable(Level.INFO)) { + LOGGER.info("<<<<<<<<<<<<>>>>>>>>>>>:\n"); + LOGGER.info("ServerAddress:" + + chaincodeServerProperties.getServerAddress().toString()); + LOGGER.info("MaxInboundMetadataSize:" + chaincodeServerProperties.getMaxInboundMetadataSize()); + LOGGER.info("MaxInboundMessageSize:" + chaincodeServerProperties.getMaxInboundMessageSize()); + LOGGER.info("MaxConnectionAgeSeconds:" + chaincodeServerProperties.getMaxConnectionAgeSeconds()); + LOGGER.info("KeepAliveTimeoutSeconds:" + chaincodeServerProperties.getKeepAliveTimeoutSeconds()); + LOGGER.info("PermitKeepAliveTimeMinutes:" + chaincodeServerProperties.getPermitKeepAliveTimeMinutes()); + LOGGER.info("KeepAliveTimeMinutes:" + chaincodeServerProperties.getKeepAliveTimeMinutes()); + LOGGER.info("PermitKeepAliveWithoutCalls:" + chaincodeServerProperties.getPermitKeepAliveWithoutCalls()); + LOGGER.info("KeyPassword:" + chaincodeServerProperties.getKeyPassword()); + LOGGER.info("KeyCertChainFile:" + chaincodeServerProperties.getKeyCertChainFile()); + LOGGER.info("KeyFile:" + chaincodeServerProperties.getKeyFile()); + LOGGER.info("isTlsEnabled:" + chaincodeServerProperties.isTlsEnabled()); + LOGGER.info("\n"); + } this.server = serverBuilder.build(); } + private static void configureTls( + final NettyServerBuilder serverBuilder, final ChaincodeServerProperties chaincodeServerProperties) + throws SSLException { + final File keyCertChainFile = + Paths.get(chaincodeServerProperties.getKeyCertChainFile()).toFile(); + final File keyFile = Paths.get(chaincodeServerProperties.getKeyFile()).toFile(); + + final SslContextBuilder sslContextBuilder; + if (chaincodeServerProperties.getKeyPassword() == null + || chaincodeServerProperties.getKeyPassword().isEmpty()) { + sslContextBuilder = SslContextBuilder.forServer(keyCertChainFile, keyFile); + } else { + sslContextBuilder = + SslContextBuilder.forServer(keyCertChainFile, keyFile, chaincodeServerProperties.getKeyPassword()); + } + + ApplicationProtocolConfig apn = new ApplicationProtocolConfig( + ApplicationProtocolConfig.Protocol.ALPN, + ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, + ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, + ApplicationProtocolNames.HTTP_2); + sslContextBuilder.applicationProtocolConfig(apn); + + if (chaincodeServerProperties.getTrustCertCollectionFile() != null) { + final File trustCertCollectionFile = Paths.get(chaincodeServerProperties.getTrustCertCollectionFile()) + .toFile(); + sslContextBuilder.clientAuth(ClientAuth.REQUIRE); + sslContextBuilder.trustManager(trustCertCollectionFile); + } + + serverBuilder.sslContext(sslContextBuilder.build()); + } + /** * start grpc server. * * @throws IOException */ + @SuppressWarnings("PMD.SystemPrintln") + @Override public void start() throws IOException { LOGGER.info("start grpc server"); Runtime.getRuntime().addShutdownHook(new Thread(() -> { // Use stderr here since the logger may have been reset by its JVM shutdown hook. System.err.println("*** shutting down gRPC server since JVM is shutting down"); - NettyGrpcServer.this.stop(); + stop(); System.err.println("*** server shut down"); })); server.start(); @@ -125,12 +136,14 @@ public void start() throws IOException { * * @throws InterruptedException */ + @Override public void blockUntilShutdown() throws InterruptedException { LOGGER.info("Waits for the server to become terminated."); server.awaitTermination(); } /** shutdown now grpc server. */ + @Override public void stop() { LOGGER.info("shutdown now grpc server."); server.shutdownNow(); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ResponseUtils.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ResponseUtils.java index bd6ee06e..ab7419fa 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ResponseUtils.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ResponseUtils.java @@ -85,15 +85,12 @@ public static Chaincode.Response newErrorResponse(final Throwable throwable) { // logged logger.error(() -> logger.formatError(throwable)); - String message = null; - byte[] payload = null; if (throwable instanceof ChaincodeException) { - message = throwable.getMessage(); - payload = ((ChaincodeException) throwable).getPayload(); + String message = throwable.getMessage(); + byte[] payload = ((ChaincodeException) throwable).getPayload(); return new Chaincode.Response(INTERNAL_SERVER_ERROR, message, payload); - } else { - message = "Unexpected error"; - return ResponseUtils.newErrorResponse(message, payload); } + + return newErrorResponse("Unexpected error", null); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/StateBasedEndorsement.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/StateBasedEndorsement.java index c390ef90..df22a7b9 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/StateBasedEndorsement.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/StateBasedEndorsement.java @@ -48,12 +48,21 @@ public interface StateBasedEndorsement { List listOrgs(); /** RoleType of an endorsement policy's identity. */ + @SuppressWarnings("PMD.FieldNamingConventions") enum RoleType { /** RoleTypeMember identifies an org's member identity. */ RoleTypeMember("MEMBER"), /** RoleTypePeer identifies an org's peer identity. */ RoleTypePeer("PEER"); + private static final Map reverseLookup = new HashMap<>(); + + static { + for (final RoleType item : values()) { + reverseLookup.put(item.getVal(), item); + } + } + private final String val; RoleType(final String val) { @@ -65,14 +74,6 @@ public String getVal() { return val; } - private static Map reverseLookup = new HashMap<>(); - - static { - for (final RoleType item : RoleType.values()) { - reverseLookup.put(item.getVal(), item); - } - } - /** * @param val * @return RoleType diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementFactory.java index f93fc6ce..9a040a59 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementFactory.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementFactory.java @@ -9,14 +9,11 @@ /** Factory for {@link StateBasedEndorsement} objects. */ public class StateBasedEndorsementFactory { - private static StateBasedEndorsementFactory instance; + private static final StateBasedEndorsementFactory INSTANCE = new StateBasedEndorsementFactory(); /** @return Endorsement Factory */ - public static synchronized StateBasedEndorsementFactory getInstance() { - if (instance == null) { - instance = new StateBasedEndorsementFactory(); - } - return instance; + public static StateBasedEndorsementFactory getInstance() { + return INSTANCE; } /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java index 68a67369..1226a3cb 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java @@ -23,7 +23,8 @@ /** Implements {@link StateBasedEndorsement}. */ public final class StateBasedEndorsementImpl implements StateBasedEndorsement { - private static Log logger = LogFactory.getLog(StateBasedEndorsementImpl.class); + @SuppressWarnings("PMD.ProperLogger") // PMD 7.7.0 reports a false positive + private static final Log LOGGER = LogFactory.getLog(StateBasedEndorsementImpl.class); private final Map orgs = new HashMap<>(); @@ -86,7 +87,7 @@ private void addOrg(final MSPPrincipal identity) { final MSPRole mspRole = MSPRole.parseFrom(identity.getPrincipal()); orgs.put(mspRole.getMspIdentifier(), mspRole.getRole()); } catch (final InvalidProtocolBufferException e) { - logger.warn("error unmarshalling msp principal"); + LOGGER.warn("error unmarshalling msp principal"); throw new IllegalArgumentException("error unmarshalling msp principal", e); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeInvocationTask.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeInvocationTask.java index b2c3c916..1f502b36 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeInvocationTask.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeInvocationTask.java @@ -13,11 +13,14 @@ import com.google.protobuf.InvalidProtocolBufferException; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.StatusCode; +import java.security.NoSuchAlgorithmException; import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.function.Consumer; import java.util.logging.Logger; import org.hyperledger.fabric.Logging; +import org.hyperledger.fabric.contract.ContractRuntimeException; import org.hyperledger.fabric.protos.peer.ChaincodeMessage; import org.hyperledger.fabric.protos.peer.ChaincodeMessage.Type; import org.hyperledger.fabric.shim.Chaincode; @@ -25,10 +28,11 @@ import org.hyperledger.fabric.traces.Traces; /** A 'Callable' implementation the has the job of invoking the chaincode, and matching the response and requests. */ +@SuppressWarnings("PMD.MoreThanOneLogger") public class ChaincodeInvocationTask implements Callable { - private static Logger logger = Logger.getLogger(ChaincodeInvocationTask.class.getName()); - private static Logger perfLogger = Logger.getLogger(Logging.PERFLOGGER); + private static final Logger LOGGER = Logger.getLogger(ChaincodeInvocationTask.class.getName()); + private static final Logger PERFLOGGER = Logger.getLogger(Logging.PERFLOGGER); private final String key; private final Type type; @@ -40,7 +44,7 @@ public class ChaincodeInvocationTask implements Callable { // up if there's no body waiting. // // Usual case should be the main thread is waiting for something to come back - private final ArrayBlockingQueue postbox = new ArrayBlockingQueue<>(2, true); + private final BlockingQueue postbox = new ArrayBlockingQueue<>(2, true); private final ChaincodeMessage message; private final Chaincode chaincode; @@ -67,13 +71,14 @@ public ChaincodeInvocationTask( /** Main method to power the invocation of the chaincode. */ @Override + @SuppressWarnings("PMD.AvoidCatchingGenericException") public ChaincodeMessage call() { ChaincodeMessage finalResponseMessage; Span span = null; try { try { - perfLogger.fine(() -> "> task:start TX::" + this.txId); + PERFLOGGER.fine(() -> "> task:start TX::" + this.txId); // A key interface for the chaincode's invoke() method implementation // is the 'ChaincodeStub' interface. An instance of this is created @@ -87,7 +92,7 @@ public ChaincodeMessage call() { // result is what will be sent to the peer as a response to this invocation final Chaincode.Response result; - perfLogger.fine(() -> "> task:invoke TX::" + this.txId); + PERFLOGGER.fine(() -> "> task:invoke TX::" + this.txId); // Call chaincode's invoke // Note in Fabric v2, there won't be any INIT @@ -97,11 +102,11 @@ public ChaincodeMessage call() { result = chaincode.invoke(stub); } - perfLogger.fine(() -> "< task:invoke TX::" + this.txId); + PERFLOGGER.fine(() -> "< task:invoke TX::" + this.txId); if (result.getStatus().getCode() >= Chaincode.Response.Status.INTERNAL_SERVER_ERROR.getCode()) { // Send ERROR with entire result.Message as payload - logger.severe(() -> String.format( + LOGGER.severe(() -> String.format( "[%-8.8s] Invoke failed with error code %d. Sending %s", message.getTxid(), result.getStatus().getCode(), ERROR)); finalResponseMessage = ChaincodeMessageFactory.newCompletedEventMessage( @@ -111,14 +116,14 @@ public ChaincodeMessage call() { } } else { // Send COMPLETED with entire result as payload - logger.fine( + LOGGER.fine( () -> String.format("[%-8.8s] Invoke succeeded. Sending %s", message.getTxid(), COMPLETED)); finalResponseMessage = ChaincodeMessageFactory.newCompletedEventMessage( message.getChannelId(), message.getTxid(), result, stub.getEvent()); } - } catch (InvalidProtocolBufferException | RuntimeException e) { - logger.severe( + } catch (InvalidProtocolBufferException | NoSuchAlgorithmException | RuntimeException e) { + LOGGER.severe( () -> String.format("[%-8.8s] Invoke failed. Sending %s: %s", message.getTxid(), ERROR, e)); finalResponseMessage = ChaincodeMessageFactory.newErrorEventMessage(message.getChannelId(), message.getTxid(), e); @@ -129,7 +134,7 @@ public ChaincodeMessage call() { // send the final response message to the peer outgoingMessageConsumer.accept(finalResponseMessage); - perfLogger.fine(() -> "< task:end TX::" + this.txId); + PERFLOGGER.fine(() -> "< task:end TX::" + this.txId); } finally { if (span != null) { span.end(); @@ -151,11 +156,22 @@ public String getTxKey() { /** * Use the Key as to determine equality. * - * @param task + * @param other * @return equality */ - public boolean equals(final ChaincodeInvocationTask task) { - return key.equals(task.getTxKey()); + @Override + public boolean equals(final Object other) { + if (!(other instanceof ChaincodeInvocationTask)) { + return false; + } + + ChaincodeInvocationTask that = (ChaincodeInvocationTask) other; + return this.key.equals(that.getTxKey()); + } + + @Override + public int hashCode() { + return key.hashCode(); } /** @@ -190,33 +206,33 @@ public void postMessage(final ChaincodeMessage msg) throws InterruptedException protected ByteString invoke(final ChaincodeMessage message) { // send the message - logger.fine(() -> "Task Sending message to the peer " + message.getTxid()); + LOGGER.fine(() -> "Task Sending message to the peer " + message.getTxid()); outgoingMessageConsumer.accept(message); // wait for response ChaincodeMessage response; try { - perfLogger.fine(() -> "> task:answer TX::" + message.getTxid()); + PERFLOGGER.fine(() -> "> task:answer TX::" + message.getTxid()); response = postbox.take(); - perfLogger.fine(() -> "< task:answer TX::" + message.getTxid()); + PERFLOGGER.fine(() -> "< task:answer TX::" + message.getTxid()); } catch (final InterruptedException e) { - logger.severe(() -> "Interrupted exchanging messages "); - throw new RuntimeException(String.format("[%-8.8s]InterruptedException received.", txId), e); + LOGGER.severe(() -> "Interrupted exchanging messages "); + throw new ContractRuntimeException(String.format("[%-8.8s]InterruptedException received.", txId), e); } // handle response switch (response.getType()) { case RESPONSE: - logger.fine(() -> String.format("[%-8.8s] Successful response received.", txId)); + LOGGER.fine(() -> String.format("[%-8.8s] Successful response received.", txId)); return response.getPayload(); case ERROR: - logger.severe(() -> String.format("[%-8.8s] Unsuccessful response received.", txId)); - throw new RuntimeException(String.format("[%-8.8s]Unsuccessful response received.", txId)); + LOGGER.severe(() -> String.format("[%-8.8s] Unsuccessful response received.", txId)); + throw new ContractRuntimeException(String.format("[%-8.8s]Unsuccessful response received.", txId)); default: - logger.severe(() -> String.format( + LOGGER.severe(() -> String.format( "[%-8.8s] Unexpected %s response received. Expected %s or %s.", txId, response.getType(), RESPONSE, ERROR)); - throw new RuntimeException(String.format( + throw new IllegalStateException(String.format( "[%-8.8s] Unexpected %s response received. Expected %s or %s.", txId, response.getType(), RESPONSE, ERROR)); } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeMessageFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeMessageFactory.java index 651bc81a..199a1b75 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeMessageFactory.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeMessageFactory.java @@ -37,7 +37,7 @@ public final class ChaincodeMessageFactory { private ChaincodeMessageFactory() {} - protected static ChaincodeMessage newGetPrivateDataHashEventMessage( + static ChaincodeMessage newGetPrivateDataHashEventMessage( final String channelId, final String txId, final String collection, final String key) { return newEventMessage( GET_PRIVATE_DATA_HASH, @@ -50,7 +50,7 @@ protected static ChaincodeMessage newGetPrivateDataHashEventMessage( .toByteString()); } - protected static ChaincodeMessage newGetStateEventMessage( + static ChaincodeMessage newGetStateEventMessage( final String channelId, final String txId, final String collection, final String key) { return newEventMessage( GET_STATE, @@ -63,7 +63,7 @@ protected static ChaincodeMessage newGetStateEventMessage( .toByteString()); } - protected static ChaincodeMessage newGetStateMetadataEventMessage( + static ChaincodeMessage newGetStateMetadataEventMessage( final String channelId, final String txId, final String collection, final String key) { return newEventMessage( GET_STATE_METADATA, @@ -76,7 +76,7 @@ protected static ChaincodeMessage newGetStateMetadataEventMessage( .toByteString()); } - protected static ChaincodeMessage newPutStateEventMessage( + static ChaincodeMessage newPutStateEventMessage( final String channelId, final String txId, final String collection, @@ -94,7 +94,7 @@ protected static ChaincodeMessage newPutStateEventMessage( .toByteString()); } - protected static ChaincodeMessage newPutStateMetadataEventMessage( + static ChaincodeMessage newPutStateMetadataEventMessage( final String channelId, final String txId, final String collection, @@ -116,7 +116,7 @@ protected static ChaincodeMessage newPutStateMetadataEventMessage( .toByteString()); } - protected static ChaincodeMessage newDeleteStateEventMessage( + static ChaincodeMessage newDeleteStateEventMessage( final String channelId, final String txId, final String collection, final String key) { return newEventMessage( DEL_STATE, @@ -129,7 +129,7 @@ protected static ChaincodeMessage newDeleteStateEventMessage( .toByteString()); } - protected static ChaincodeMessage newPurgeStateEventMessage( + static ChaincodeMessage newPurgeStateEventMessage( final String channelId, final String txId, final String collection, final String key) { return newEventMessage( Type.PURGE_PRIVATE_DATA, @@ -142,46 +142,43 @@ protected static ChaincodeMessage newPurgeStateEventMessage( .toByteString()); } - protected static ChaincodeMessage newErrorEventMessage( - final String channelId, final String txId, final Throwable throwable) { + static ChaincodeMessage newErrorEventMessage(final String channelId, final String txId, final Throwable throwable) { return newErrorEventMessage(channelId, txId, printStackTrace(throwable)); } - protected static ChaincodeMessage newErrorEventMessage( - final String channelId, final String txId, final String message) { + static ChaincodeMessage newErrorEventMessage(final String channelId, final String txId, final String message) { return newErrorEventMessage(channelId, txId, message, null); } - protected static ChaincodeMessage newErrorEventMessage( + static ChaincodeMessage newErrorEventMessage( final String channelId, final String txId, final String message, final ChaincodeEvent event) { return newEventMessage(ERROR, channelId, txId, ByteString.copyFromUtf8(message), event); } - protected static ChaincodeMessage newCompletedEventMessage( + static ChaincodeMessage newCompletedEventMessage( final String channelId, final String txId, final Chaincode.Response response, final ChaincodeEvent event) { - final ChaincodeMessage message = newEventMessage( + return newEventMessage( COMPLETED, channelId, txId, toProtoResponse(response).toByteString(), event); - return message; } - protected static ChaincodeMessage newInvokeChaincodeMessage( + static ChaincodeMessage newInvokeChaincodeMessage( final String channelId, final String txId, final ByteString payload) { return newEventMessage(INVOKE_CHAINCODE, channelId, txId, payload, null); } - protected static ChaincodeMessage newRegisterChaincodeMessage(final ChaincodeID chaincodeId) { + static ChaincodeMessage newRegisterChaincodeMessage(final ChaincodeID chaincodeId) { return ChaincodeMessage.newBuilder() .setType(REGISTER) .setPayload(chaincodeId.toByteString()) .build(); } - protected static ChaincodeMessage newEventMessage( + static ChaincodeMessage newEventMessage( final Type type, final String channelId, final String txId, final ByteString payload) { return newEventMessage(type, channelId, txId, payload, null); } - protected static ChaincodeMessage newEventMessage( + static ChaincodeMessage newEventMessage( final Type type, final String channelId, final String txId, diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeSupportClient.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeSupportClient.java index d3a6190d..c5478f82 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeSupportClient.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeSupportClient.java @@ -22,8 +22,7 @@ public class ChaincodeSupportClient { private static final int DEFAULT_TIMEOUT = 5; - private static final Logger LOGGER = Logger.getLogger(ChaincodeSupportClient.class.getName()); - private static Logger perflogger = Logger.getLogger(Logging.PERFLOGGER); + private static final Logger PERFLOGGER = Logger.getLogger(Logging.PERFLOGGER); private final ManagedChannel channel; private final ChaincodeSupportStub stub; @@ -85,9 +84,9 @@ public void start(final InvocationTaskManager itm, final StreamObserver "> sendToPeer TX::" + t.getTxid()); + PERFLOGGER.fine(() -> "> sendToPeer TX::" + t.getTxid()); requestObserver.onNext(t); - perflogger.fine(() -> "< sendToPeer TX::" + t.getTxid()); + PERFLOGGER.fine(() -> "< sendToPeer TX::" + t.getTxid()); lock.unlock(); } }; @@ -97,7 +96,8 @@ public void accept(final ChaincodeMessage t) { // // NOTE the register() - very important - as this triggers the ITM to send the // first message to the peer; otherwise the both sides will sit there waiting - itm.setResponseConsumer(consumer).register(); + itm.setResponseConsumer(consumer); + itm.register(); } /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationStubImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationStubImpl.java index 809b36a5..3cf4cc85 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationStubImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationStubImpl.java @@ -16,6 +16,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Timestamp; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.MessageDigest; @@ -25,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -57,6 +59,7 @@ import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; import org.hyperledger.fabric.shim.ledger.QueryResultsIteratorWithMetadata; +@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.GodClass"}) class InvocationStubImpl implements ChaincodeStub { private static final String UNSPECIFIED_START_KEY = new String(Character.toChars(0x000001)); @@ -65,6 +68,7 @@ class InvocationStubImpl implements ChaincodeStub { public static final String MAX_UNICODE_RUNE = "\udbff\udfff"; private static final String CORE_PEER_LOCALMSPID = "CORE_PEER_LOCALMSPID"; + private final String channelId; private final String txId; private final ChaincodeInvocationTask handler; @@ -74,6 +78,15 @@ class InvocationStubImpl implements ChaincodeStub { private final ByteString creator; private final Map transientMap; private final byte[] binding; + private final Function + queryResultBytesToKeyModification = queryResultBytes -> { + try { + return org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.parseFrom( + queryResultBytes.getResultBytes()); + } catch (final InvalidProtocolBufferException e) { + throw new UncheckedIOException(e); + } + }; private ChaincodeEvent event; /** @@ -82,7 +95,7 @@ class InvocationStubImpl implements ChaincodeStub { * @throws InvalidProtocolBufferException */ InvocationStubImpl(final ChaincodeMessage message, final ChaincodeInvocationTask handler) - throws InvalidProtocolBufferException { + throws InvalidProtocolBufferException, NoSuchAlgorithmException { this.channelId = message.getChannelId(); this.txId = message.getTxid(); this.handler = handler; @@ -90,31 +103,35 @@ class InvocationStubImpl implements ChaincodeStub { this.args = Collections.unmodifiableList(input.getArgsList()); this.signedProposal = message.getProposal(); - if (this.signedProposal == null - || this.signedProposal.getProposalBytes().isEmpty()) { + if (this.signedProposal.getProposalBytes().isEmpty()) { this.creator = null; this.txTimestamp = null; this.transientMap = Collections.emptyMap(); this.binding = null; } else { - try { - final Proposal proposal = Proposal.parseFrom(signedProposal.getProposalBytes()); - final Header header = Header.parseFrom(proposal.getHeader()); - final ChannelHeader channelHeader = ChannelHeader.parseFrom(header.getChannelHeader()); - validateProposalType(channelHeader); - final SignatureHeader signatureHeader = SignatureHeader.parseFrom(header.getSignatureHeader()); - final ChaincodeProposalPayload chaincodeProposalPayload = - ChaincodeProposalPayload.parseFrom(proposal.getPayload()); - final Timestamp timestamp = channelHeader.getTimestamp(); - - this.txTimestamp = Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()); - this.creator = signatureHeader.getCreator(); - this.transientMap = chaincodeProposalPayload.getTransientMapMap(); - this.binding = computeBinding(channelHeader, signatureHeader); - } catch (InvalidProtocolBufferException | NoSuchAlgorithmException e) { - throw new RuntimeException(e); + final Proposal proposal = Proposal.parseFrom(signedProposal.getProposalBytes()); + final Header header = Header.parseFrom(proposal.getHeader()); + final ChannelHeader channelHeader = ChannelHeader.parseFrom(header.getChannelHeader()); + validateProposalType(channelHeader); + final SignatureHeader signatureHeader = SignatureHeader.parseFrom(header.getSignatureHeader()); + final ChaincodeProposalPayload chaincodeProposalPayload = + ChaincodeProposalPayload.parseFrom(proposal.getPayload()); + final Timestamp timestamp = channelHeader.getTimestamp(); + + this.txTimestamp = Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()); + this.creator = signatureHeader.getCreator(); + this.transientMap = chaincodeProposalPayload.getTransientMapMap(); + this.binding = computeBinding(channelHeader, signatureHeader); + } + } + + private static boolean isEmptyString(final String str) { + for (int i = 0; i < str.length(); i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return false; } } + return true; } private byte[] computeBinding(final ChannelHeader channelHeader, final SignatureHeader signatureHeader) @@ -135,24 +152,24 @@ private void validateProposalType(final ChannelHeader channelHeader) { case CONFIG: return; default: - throw new RuntimeException(String.format( + throw new IllegalArgumentException(String.format( "Unexpected transaction type: %s", HeaderType.forNumber(channelHeader.getType()))); } } @Override public List getArgs() { - return args.stream().map(x -> x.toByteArray()).collect(Collectors.toList()); + return args.stream().map(ByteString::toByteArray).collect(toList()); } @Override public List getStringArgs() { - return args.stream().map(x -> x.toStringUtf8()).collect(Collectors.toList()); + return args.stream().map(ByteString::toStringUtf8).collect(toList()); } @Override public String getFunction() { - return getStringArgs().size() > 0 ? getStringArgs().get(0) : null; + return getStringArgs().isEmpty() ? null : getStringArgs().get(0); } @Override @@ -162,7 +179,7 @@ public List getParameters() { @Override public void setEvent(final String name, final byte[] payload) { - if (name == null || name.trim().isEmpty()) { + if (null == name || isEmptyString(name)) { throw new IllegalArgumentException("event name can not be nil string"); } if (payload != null) { @@ -198,6 +215,7 @@ public byte[] getState(final String key) { } @Override + @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull") public byte[] getStateValidationParameter(final String key) { final ByteString payload = @@ -215,8 +233,8 @@ public byte[] getStateValidationParameter(final String key) { .toByteArray(); } } catch (final InvalidProtocolBufferException e) { - LOGGER.severe(String.format("[%-8.8s] unmarshalling error", txId)); - throw new RuntimeException("Error unmarshalling StateMetadataResult.", e); + LOGGER.severe(() -> String.format("[%-8.8s] unmarshalling error", txId)); + throw new UncheckedIOException("Error unmarshalling StateMetadataResult.", e); } return null; @@ -273,7 +291,7 @@ private QueryResultsIterator executeGetStateByRange( ChaincodeMessageFactory.newEventMessage(GET_STATE_BY_RANGE, channelId, txId, requestPayload); final ByteString response = handler.invoke(requestMessage); - return new QueryResultsIteratorImpl( + return new QueryResultsIteratorImpl<>( this.handler, channelId, txId, response, queryResultBytesToKv.andThen(KeyValueImpl::new)); } @@ -283,7 +301,7 @@ public KV apply(final QueryResultBytes queryResultBytes) { try { return KV.parseFrom(queryResultBytes.getResultBytes()); } catch (final InvalidProtocolBufferException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } }; @@ -409,7 +427,7 @@ public QueryResultsIterator getQueryResult(final String query) { ChaincodeMessageFactory.newEventMessage(GET_QUERY_RESULT, channelId, txId, requestPayload); final ByteString response = handler.invoke(requestMessage); - return new QueryResultsIteratorImpl( + return new QueryResultsIteratorImpl<>( this.handler, channelId, txId, response, queryResultBytesToKv.andThen(KeyValueImpl::new)); } @@ -432,7 +450,7 @@ public QueryResultsIteratorWithMetadata getQueryResultWithPagination( ChaincodeMessageFactory.newEventMessage(GET_QUERY_RESULT, channelId, txId, requestPayload); final ByteString response = handler.invoke(requestMessage); - return new QueryResultsIteratorWithMetadataImpl( + return new QueryResultsIteratorWithMetadataImpl<>( this.handler, channelId, txId, response, queryResultBytesToKv.andThen(KeyValueImpl::new)); } @@ -448,7 +466,7 @@ public QueryResultsIterator getHistoryForKey(final String key) ChaincodeMessageFactory.newEventMessage(GET_HISTORY_FOR_KEY, channelId, txId, requestPayload); final ByteString response = handler.invoke(requestMessage); - return new QueryResultsIteratorImpl( + return new QueryResultsIteratorImpl<>( this.handler, channelId, txId, @@ -456,21 +474,6 @@ public QueryResultsIterator getHistoryForKey(final String key) queryResultBytesToKeyModification.andThen(KeyModificationImpl::new)); } - private final Function - queryResultBytesToKeyModification = - new Function() { - @Override - public org.hyperledger.fabric.protos.ledger.queryresult.KeyModification apply( - final QueryResultBytes queryResultBytes) { - try { - return org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.parseFrom( - queryResultBytes.getResultBytes()); - } catch (final InvalidProtocolBufferException e) { - throw new RuntimeException(e); - } - } - }; - @Override public byte[] getPrivateData(final String collection, final String key) { validateCollection(collection); @@ -496,6 +499,7 @@ public byte[] getPrivateDataHash(final String collection, final String key) { } @Override + @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull") public byte[] getPrivateDataValidationParameter(final String collection, final String key) { validateCollection(collection); @@ -514,8 +518,8 @@ public byte[] getPrivateDataValidationParameter(final String collection, final S .toByteArray(); } } catch (final InvalidProtocolBufferException e) { - LOGGER.severe(String.format("[%-8.8s] unmarshalling error", txId)); - throw new RuntimeException("Error unmarshalling StateMetadataResult.", e); + LOGGER.severe(() -> String.format("[%-8.8s] unmarshalling error", txId)); + throw new UncheckedIOException("Error unmarshalling StateMetadataResult.", e); } return null; @@ -634,7 +638,7 @@ public Chaincode.Response invokeChaincode( final String chaincodeName, final List args, final String channel) { // internally we handle chaincode name as a composite name final String compositeName; - if (channel != null && !channel.trim().isEmpty()) { + if (channel != null && !isEmptyString(channel)) { compositeName = chaincodeName + "/" + channel; } else { compositeName = chaincodeName; @@ -644,7 +648,7 @@ public Chaincode.Response invokeChaincode( final ByteString invocationSpecPayload = ChaincodeSpec.newBuilder() .setChaincodeId(ChaincodeID.newBuilder().setName(compositeName).build()) .setInput(ChaincodeInput.newBuilder() - .addAllArgs(args.stream().map(ByteString::copyFrom).collect(Collectors.toList())) + .addAllArgs(args.stream().map(ByteString::copyFrom).collect(toList())) .build()) .build() .toByteString(); @@ -659,7 +663,7 @@ public Chaincode.Response invokeChaincode( final ChaincodeMessage responseMessage = ChaincodeMessage.parseFrom(response); // the actual response message must be of type COMPLETED - LOGGER.fine(String.format( + LOGGER.fine(() -> String.format( "[%-8.8s] %s response received from other chaincode.", txId, responseMessage.getType())); if (responseMessage.getType() == COMPLETED) { @@ -668,14 +672,14 @@ public Chaincode.Response invokeChaincode( return new Chaincode.Response( Chaincode.Response.Status.forCode(r.getStatus()), r.getMessage(), - r.getPayload() == null ? null : r.getPayload().toByteArray()); + r.getPayload().toByteArray()); } else { // error final String message = responseMessage.getPayload().toStringUtf8(); return new Chaincode.Response(Chaincode.Response.Status.INTERNAL_SERVER_ERROR, message, null); } } catch (final InvalidProtocolBufferException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } @@ -690,6 +694,7 @@ public Instant getTxTimestamp() { } @Override + @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull") public byte[] getCreator() { if (creator == null) { return null; @@ -700,7 +705,7 @@ public byte[] getCreator() { @Override public Map getTransient() { return transientMap.entrySet().stream() - .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue().toByteArray())); + .collect(Collectors.toMap(Map.Entry::getKey, x -> x.getValue().toByteArray())); } @Override @@ -709,18 +714,14 @@ public byte[] getBinding() { } private void validateKey(final String key) { - if (key == null) { - throw new NullPointerException("key cannot be null"); - } - if (key.length() == 0) { + Objects.requireNonNull(key, "key cannot be null"); + if (key.isEmpty()) { throw new IllegalArgumentException("key cannot not be an empty string"); } } private void validateCollection(final String collection) { - if (collection == null) { - throw new NullPointerException("collection cannot be null"); - } + Objects.requireNonNull(collection, "collection cannot be null"); if (collection.isEmpty()) { throw new IllegalArgumentException("collection must not be an empty string"); } @@ -731,6 +732,6 @@ public String getMspId() { if (System.getenv().containsKey(CORE_PEER_LOCALMSPID)) { return System.getenv(CORE_PEER_LOCALMSPID); } - throw new RuntimeException("CORE_PEER_LOCALMSPID is unset in chaincode process"); + throw new IllegalStateException("CORE_PEER_LOCALMSPID is unset in chaincode process"); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskExecutor.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskExecutor.java index c2402e48..1267ac4f 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskExecutor.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskExecutor.java @@ -18,6 +18,8 @@ public final class InvocationTaskExecutor extends ThreadPoolExecutor implements TaskMetricsCollector { private static Logger logger = Logger.getLogger(InvocationTaskExecutor.class.getName()); + private final AtomicInteger count = new AtomicInteger(); + /** * @param corePoolSize * @param maximumPoolSize @@ -40,8 +42,6 @@ public InvocationTaskExecutor( logger.info("Thread pool created"); } - private final AtomicInteger count = new AtomicInteger(); - @Override protected void beforeExecute(final Thread thread, final Runnable task) { super.beforeExecute(thread, task); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java index 2de85597..aecc8e64 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java @@ -8,6 +8,7 @@ import static org.hyperledger.fabric.protos.peer.ChaincodeMessage.Type.READY; import static org.hyperledger.fabric.protos.peer.ChaincodeMessage.Type.REGISTERED; +import java.util.Map; import java.util.Properties; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CompletableFuture; @@ -35,27 +36,19 @@ *

In the current 1.4 Fabric Protocol this is in practice a singleton - because the peer will ignore multiple * 'register' calls. And an instance of this will be created per register call for a given chaincodeID. */ +@SuppressWarnings("PMD.MoreThanOneLogger") public final class InvocationTaskManager { - private static Logger logger = Logger.getLogger(InvocationTaskManager.class.getName()); - private static Logger perflogger = Logger.getLogger(Logging.PERFLOGGER); - - /** - * Get an instance of the Invocation Task Manager. - * - * @param chaincode Chaincode Instance - * @param chaincodeId ID of the chaincode - * @return InvocationTaskManager - */ - public static InvocationTaskManager getManager(final ChaincodeBase chaincode, final ChaincodeID chaincodeId) { - return new InvocationTaskManager(chaincode, chaincodeId); - } + private static final Logger LOGGER = Logger.getLogger(InvocationTaskManager.class.getName()); + private static final Logger PERFLOGGER = Logger.getLogger(Logging.PERFLOGGER); + private static final String CANNOT_HANDLE_FORMAT = "[%-8.8s] Received %s: cannot handle"; + private static final int SHUTDOWN_TIMEOUT = 60; // Keeping a map here of the tasks that are currently ongoing, and the key // // Key = txid + channleid // One task = one transaction invocation - private final ConcurrentHashMap innvocationTasks = new ConcurrentHashMap<>(); + private final Map innvocationTasks = new ConcurrentHashMap<>(); // Way to send back the events and data that make up the requests private Consumer outgoingMessage; @@ -69,13 +62,14 @@ public static InvocationTaskManager getManager(final ChaincodeBase chaincode, fi private final int maximumPoolSize; private final int corePoolSize; private final long keepAliveTime; - private final TimeUnit unit = TimeUnit.MILLISECONDS; + private static final TimeUnit UNIT = TimeUnit.MILLISECONDS; private final BlockingQueue workQueue; // Minor customization of the ThreadFactory to give a more recognizable name to the threads private final ThreadFactory threadFactory = new ThreadFactory() { - private AtomicInteger next = new AtomicInteger(0); + private final AtomicInteger next = new AtomicInteger(0); + @Override public Thread newThread(final Runnable r) { Thread thread = Executors.defaultThreadFactory().newThread(r); thread.setName("fabric-txinvoke:" + next.incrementAndGet()); @@ -94,6 +88,17 @@ public Thread newThread(final Runnable r) { private final InvocationTaskExecutor taskService; + /** + * Get an instance of the Invocation Task Manager. + * + * @param chaincode Chaincode Instance + * @param chaincodeId ID of the chaincode + * @return InvocationTaskManager + */ + public static InvocationTaskManager getManager(final ChaincodeBase chaincode, final ChaincodeID chaincodeId) { + return new InvocationTaskManager(chaincode, chaincodeId); + } + /** * New InvocationTaskManager. * @@ -117,14 +122,14 @@ public InvocationTaskManager(final ChaincodeBase chaincode, final ChaincodeID ch corePoolSize = Integer.parseInt((String) props.getOrDefault("TP_CORE_POOL_SIZE", "5")); keepAliveTime = Long.parseLong((String) props.getOrDefault("TP_KEEP_ALIVE_MS", "5000")); - logger.info(() -> "Max Pool Size [TP_MAX_POOL_SIZE]" + maximumPoolSize); - logger.info(() -> "Queue Size [TP_CORE_POOL_SIZE]" + queueSize); - logger.info(() -> "Core Pool Size [TP_QUEUE_SIZE]" + corePoolSize); - logger.info(() -> "Keep Alive Time [TP_KEEP_ALIVE_MS]" + keepAliveTime); + LOGGER.info(() -> "Max Pool Size [TP_MAX_POOL_SIZE]" + maximumPoolSize); + LOGGER.info(() -> "Queue Size [TP_CORE_POOL_SIZE]" + queueSize); + LOGGER.info(() -> "Core Pool Size [TP_QUEUE_SIZE]" + corePoolSize); + LOGGER.info(() -> "Keep Alive Time [TP_KEEP_ALIVE_MS]" + keepAliveTime); - workQueue = new LinkedBlockingQueue(queueSize); + workQueue = new LinkedBlockingQueue<>(queueSize); taskService = new InvocationTaskExecutor( - corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); + corePoolSize, maximumPoolSize, keepAliveTime, UNIT, workQueue, threadFactory, handler); Metrics.getProvider().setTaskMetricsCollector(taskService); } @@ -135,45 +140,15 @@ public InvocationTaskManager(final ChaincodeBase chaincode, final ChaincodeID ch * @throws IllegalArgumentException validation fields and arguments * @param chaincodeMessage ChaincodeMessage */ - public void onChaincodeMessage(final ChaincodeMessage chaincodeMessage) throws IllegalArgumentException { - if (chaincodeMessage == null) { + @SuppressWarnings("PMD.AvoidCatchingGenericException") + public void onChaincodeMessage(final ChaincodeMessage chaincodeMessage) { + if (null == chaincodeMessage) { throw new IllegalArgumentException("chaincodeMessage is null"); } - logger.fine(() -> + LOGGER.fine(() -> String.format("[%-8.8s] %s", chaincodeMessage.getTxid(), ChaincodeBase.toJsonString(chaincodeMessage))); try { - final Type msgType = chaincodeMessage.getType(); - switch (chaincode.getState()) { - case CREATED: - if (msgType == REGISTERED) { - chaincode.setState(org.hyperledger.fabric.shim.ChaincodeBase.CCState.ESTABLISHED); - logger.fine(() -> String.format( - "[%-8.8s] Received REGISTERED: moving to established state", - chaincodeMessage.getTxid())); - } else { - logger.warning(() -> String.format( - "[%-8.8s] Received %s: cannot handle", chaincodeMessage.getTxid(), msgType)); - } - break; - case ESTABLISHED: - if (msgType == READY) { - chaincode.setState(org.hyperledger.fabric.shim.ChaincodeBase.CCState.READY); - logger.fine(() -> String.format( - "[%-8.8s] Received READY: ready for invocations", chaincodeMessage.getTxid())); - } else { - logger.warning(() -> String.format( - "[%-8.8s] Received %s: cannot handle", chaincodeMessage.getTxid(), msgType)); - } - break; - case READY: - handleMsg(chaincodeMessage, msgType); - break; - default: - logger.warning(() -> String.format( - "[%-8.8s] Received %s: cannot handle", - chaincodeMessage.getTxid(), chaincodeMessage.getType())); - break; - } + processChaincodeMessage(chaincodeMessage); } catch (final RuntimeException e) { // catch any issues with say the comms dropping or something else completely // unknown @@ -183,6 +158,37 @@ public void onChaincodeMessage(final ChaincodeMessage chaincodeMessage) throws I } } + private void processChaincodeMessage(final ChaincodeMessage chaincodeMessage) { + final Type msgType = chaincodeMessage.getType(); + + switch (chaincode.getState()) { + case CREATED: + if (msgType == REGISTERED) { + chaincode.setState(ChaincodeBase.CCState.ESTABLISHED); + LOGGER.fine(() -> String.format( + "[%-8.8s] Received REGISTERED: moving to established state", chaincodeMessage.getTxid())); + } else { + LOGGER.warning(() -> String.format(CANNOT_HANDLE_FORMAT, chaincodeMessage.getTxid(), msgType)); + } + break; + case ESTABLISHED: + if (msgType == READY) { + chaincode.setState(ChaincodeBase.CCState.READY); + LOGGER.fine(() -> String.format( + "[%-8.8s] Received READY: ready for invocations", chaincodeMessage.getTxid())); + } else { + LOGGER.warning(() -> String.format(CANNOT_HANDLE_FORMAT, chaincodeMessage.getTxid(), msgType)); + } + break; + case READY: + handleMsg(chaincodeMessage, msgType); + break; + default: + LOGGER.warning(() -> String.format(CANNOT_HANDLE_FORMAT, chaincodeMessage.getTxid(), msgType)); + break; + } + } + /** * Key method to take the message, determine if it is a new transaction or an answer (good or bad) to a stub api. * @@ -190,7 +196,7 @@ public void onChaincodeMessage(final ChaincodeMessage chaincodeMessage) throws I * @param msgType */ private void handleMsg(final ChaincodeMessage message, final Type msgType) { - logger.fine(() -> String.format("[%-8.8s] Received %s", message.getTxid(), msgType.toString())); + LOGGER.fine(() -> String.format("[%-8.8s] Received %s", message.getTxid(), msgType.toString())); switch (msgType) { case RESPONSE: case ERROR: @@ -201,8 +207,7 @@ private void handleMsg(final ChaincodeMessage message, final Type msgType) { newTask(message, msgType); break; default: - logger.warning(() -> - String.format("[%-8.8s] Received %s: cannot handle", message.getTxid(), message.getType())); + LOGGER.warning(() -> String.format(CANNOT_HANDLE_FORMAT, message.getTxid(), message.getType())); break; } } @@ -214,26 +219,29 @@ private void handleMsg(final ChaincodeMessage message, final Type msgType) { */ private void sendToTask(final ChaincodeMessage message) { try { - perflogger.fine(() -> "> sendToTask TX::" + message.getTxid()); + PERFLOGGER.fine(() -> "> sendToTask TX::" + message.getTxid()); final String key = message.getChannelId() + message.getTxid(); final ChaincodeInvocationTask task = this.innvocationTasks.get(key); if (task == null) { - throw new InterruptedException("Task hasmap missing entry"); + sendFailure(message, new InterruptedException("Task map missing entry: " + key)); + } else { + task.postMessage(message); + PERFLOGGER.fine(() -> "< sendToTask TX::" + message.getTxid()); } - task.postMessage(message); - - perflogger.fine(() -> "< sendToTask TX::" + message.getTxid()); } catch (final InterruptedException e) { - logger.severe( - () -> "Failed to send response to the task task " + message.getTxid() + Logging.formatError(e)); - - final ChaincodeMessage m = ChaincodeMessageFactory.newErrorEventMessage( - message.getChannelId(), message.getTxid(), "Failed to send response to task"); - this.outgoingMessage.accept(m); + sendFailure(message, e); } } + private void sendFailure(final ChaincodeMessage message, final InterruptedException e) { + LOGGER.severe(() -> "Failed to send response to the task task " + message.getTxid() + Logging.formatError(e)); + + final ChaincodeMessage m = ChaincodeMessageFactory.newErrorEventMessage( + message.getChannelId(), message.getTxid(), "Failed to send response to task"); + this.outgoingMessage.accept(m); + } + /** * Create a new task to handle this transaction function. * @@ -246,11 +254,11 @@ private void newTask(final ChaincodeMessage message, final Type type) { final ChaincodeInvocationTask task = new ChaincodeInvocationTask(message, type, this.outgoingMessage, this.chaincode); - perflogger.fine(() -> "> newTask:created TX::" + txid); + PERFLOGGER.fine(() -> "> newTask:created TX::" + txid); this.innvocationTasks.put(task.getTxKey(), task); try { - perflogger.fine(() -> "> newTask:submitting TX::" + txid); + PERFLOGGER.fine(() -> "> newTask:submitting TX::" + txid); // submit the task to run, with the taskService providing the // threading support. @@ -266,13 +274,13 @@ private void newTask(final ChaincodeMessage message, final Type type) { // list response.thenRun(() -> { innvocationTasks.remove(task.getTxKey()); - perflogger.fine(() -> "< newTask:completed TX::" + txid); + PERFLOGGER.fine(() -> "< newTask:completed TX::" + txid); }); - perflogger.fine(() -> "< newTask:submitted TX::" + txid); + PERFLOGGER.fine(() -> "< newTask:submitted TX::" + txid); } catch (final RejectedExecutionException e) { - logger.warning(() -> "Failed to submit task " + txid + Logging.formatError(e)); + LOGGER.warning(() -> "Failed to submit task " + txid + Logging.formatError(e)); // this means that there is no way that this can be handed off to another // thread for processing, and there's no space left in the queue to hold // it pending @@ -289,33 +297,27 @@ private void newTask(final ChaincodeMessage message, final Type type) { * @param outgoingMessage * @return InvocationTaskManager */ - public InvocationTaskManager setResponseConsumer(final Consumer outgoingMessage) { + public void setResponseConsumer(final Consumer outgoingMessage) { this.outgoingMessage = outgoingMessage; - - return this; } /** * Send the initial protocol message for the 'register' phase. * * @throws IllegalArgumentException validation fields and arguments - * @return InvocationTaskManager */ - public InvocationTaskManager register() throws IllegalArgumentException { + public void register() { if (outgoingMessage == null) { throw new IllegalArgumentException("outgoingMessage is null"); } - logger.info(() -> "Registering new chaincode " + this.chaincodeId); + LOGGER.info(() -> "Registering new chaincode " + this.chaincodeId); chaincode.setState(ChaincodeBase.CCState.CREATED); this.outgoingMessage.accept(ChaincodeMessageFactory.newRegisterChaincodeMessage(this.chaincodeId)); - - return this; } - private static final int SHUTDOWN_TIMEOUT = 60; - /** */ + @SuppressWarnings("PMD.SystemPrintln") public void shutdown() { // Recommended shutdown process from // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyModificationImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyModificationImpl.java index 2cecbf97..2bbcca43 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyModificationImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyModificationImpl.java @@ -13,7 +13,7 @@ public final class KeyModificationImpl implements KeyModification { private final String txId; private final ByteString value; - private final java.time.Instant timestamp; + private final Instant timestamp; private final boolean deleted; KeyModificationImpl(final org.hyperledger.fabric.protos.ledger.queryresult.KeyModification km) { @@ -40,7 +40,7 @@ public String getStringValue() { } @Override - public java.time.Instant getTimestamp() { + public Instant getTimestamp() { return timestamp; } @@ -52,38 +52,29 @@ public boolean isDeleted() { @Override public int hashCode() { final int prime = 31; - int result = 1; - result = prime * result + (deleted ? 1231 : 1237); - result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode()); - result = prime * result + ((txId == null) ? 0 : txId.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); + int result = Boolean.hashCode(deleted); + result = prime * result + timestamp.hashCode(); + result = prime * result + txId.hashCode(); + result = prime * result + value.hashCode(); return result; } @Override - public boolean equals(final Object obj) { - if (this == obj) { + public boolean equals(final Object other) { + if (this == other) { return true; } - if (obj == null) { + if (other == null) { return false; } - if (getClass() != obj.getClass()) { + if (getClass() != other.getClass()) { return false; } - final KeyModificationImpl other = (KeyModificationImpl) obj; - if (deleted != other.deleted) { - return false; - } - if (!timestamp.equals(other.timestamp)) { - return false; - } - if (!txId.equals(other.txId)) { - return false; - } - if (!value.equals(other.value)) { - return false; - } - return true; + + final KeyModificationImpl that = (KeyModificationImpl) other; + return this.deleted == that.deleted + && this.timestamp.equals(that.timestamp) + && this.txId.equals(that.txId) + && this.value.equals(that.value); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyValueImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyValueImpl.java index dbf1089f..e158fc96 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyValueImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/KeyValueImpl.java @@ -37,30 +37,24 @@ public String getStringValue() { @Override public int hashCode() { final int prime = 31; - int result = 1; - result = prime * result + ((key == null) ? 0 : key.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); + int result = key.hashCode(); + result = prime * result + value.hashCode(); return result; } @Override - public boolean equals(final Object obj) { - if (this == obj) { + public boolean equals(final Object other) { + if (this == other) { return true; } - if (obj == null) { + if (other == null) { return false; } - if (getClass() != obj.getClass()) { + if (getClass() != other.getClass()) { return false; } - final KeyValueImpl other = (KeyValueImpl) obj; - if (!key.equals(other.key)) { - return false; - } - if (!value.equals(other.value)) { - return false; - } - return true; + + final KeyValueImpl that = (KeyValueImpl) other; + return this.key.equals(that.key) && this.value.equals(that.value); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorImpl.java index 874ae4f7..e5220d7e 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorImpl.java @@ -11,6 +11,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.io.UncheckedIOException; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; @@ -39,7 +40,7 @@ class QueryResultsIteratorImpl implements QueryResultsIterator { private final String txId; private Iterator currentIterator; private QueryResponse currentQueryResponse; - private Function mapper; + private final Function mapper; QueryResultsIteratorImpl( final ChaincodeInvocationTask handler, @@ -56,7 +57,7 @@ class QueryResultsIteratorImpl implements QueryResultsIterator { this.currentIterator = currentQueryResponse.getResultsList().iterator(); this.mapper = mapper; } catch (final InvalidProtocolBufferException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } @@ -95,7 +96,7 @@ public T next() { try { currentQueryResponse = QueryResponse.parseFrom(responseMessage); } catch (final InvalidProtocolBufferException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } currentIterator = currentQueryResponse.getResultsList().iterator(); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImpl.java index 26d24f55..25043547 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImpl.java @@ -8,6 +8,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.io.UncheckedIOException; import java.util.function.Function; import java.util.logging.Logger; import org.hyperledger.fabric.protos.peer.QueryResponse; @@ -25,9 +26,9 @@ */ public final class QueryResultsIteratorWithMetadataImpl extends QueryResultsIteratorImpl implements QueryResultsIteratorWithMetadata { - private static Logger logger = Logger.getLogger(QueryResultsIteratorWithMetadataImpl.class.getName()); + private static final Logger LOGGER = Logger.getLogger(QueryResultsIteratorWithMetadataImpl.class.getName()); - private QueryResponseMetadata metadata; + private final QueryResponseMetadata metadata; /** * @param handler @@ -47,8 +48,8 @@ public QueryResultsIteratorWithMetadataImpl( final QueryResponse queryResponse = QueryResponse.parseFrom(responseBuffer); metadata = QueryResponseMetadata.parseFrom(queryResponse.getMetadata()); } catch (final InvalidProtocolBufferException e) { - logger.warning("can't parse response metadata"); - throw new RuntimeException(e); + LOGGER.warning("can't parse response metadata"); + throw new UncheckedIOException(e); } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java index 32335315..4c88c237 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,7 +27,7 @@ public class CompositeKey { private final String objectType; private final List attributes; - private final String compositeKey; + private final String key; /** * @param objectType @@ -41,12 +42,10 @@ public CompositeKey(final String objectType, final String... attributes) { * @param attributes */ public CompositeKey(final String objectType, final List attributes) { - if (objectType == null) { - throw new NullPointerException("objectType cannot be null"); - } + Objects.requireNonNull(objectType, "objectType cannot be null"); this.objectType = objectType; this.attributes = attributes; - this.compositeKey = generateCompositeKeyString(objectType, attributes); + this.key = generateCompositeKeyString(objectType, attributes); } /** @return object type */ @@ -62,7 +61,7 @@ public List getAttributes() { /** */ @Override public String toString() { - return compositeKey; + return key; } /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/Traces.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/Traces.java index 28ba7b28..81ad5520 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/Traces.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/Traces.java @@ -5,7 +5,6 @@ */ package org.hyperledger.fabric.traces; -import java.lang.reflect.InvocationTargetException; import java.util.Properties; import java.util.logging.Logger; import org.hyperledger.fabric.traces.impl.DefaultTracesProvider; @@ -47,14 +46,8 @@ public static TracesProvider initialize(final Properties props) { logger.info("Using default traces provider"); provider = new DefaultTracesProvider(); } - } catch (ClassNotFoundException - | InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException e) { - throw new RuntimeException("Unable to start traces", e); + } catch (Exception e) { + throw new IllegalStateException("Unable to start traces", e); } } else { // return a 'null' provider diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/TracesProvider.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/TracesProvider.java index 2083b4e9..d8c06279 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/TracesProvider.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/TracesProvider.java @@ -32,7 +32,6 @@ public interface TracesProvider { * @param props */ default void initialize(final Properties props) {} - ; /** * Creates a span with metadata of the current chaincode execution, possibly linked to the execution arguments. diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryProperties.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryProperties.java index 7afa5c48..f0d92eed 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryProperties.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryProperties.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -99,14 +100,13 @@ public Duration getDuration(final String name) { String numberString = value.substring(0, value.length() - unitString.length()); try { long rawNumber = Long.parseLong(numberString.trim()); - TimeUnit unit = getDurationUnit(unitString.trim()); + TimeUnit unit = getDurationUnit(unitString.trim()) + .orElseThrow(() -> new ConfigurationException( + "Invalid duration property " + name + "=" + value + ". Invalid duration unit.")); return Duration.ofMillis(TimeUnit.MILLISECONDS.convert(rawNumber, unit)); } catch (NumberFormatException ex) { throw new ConfigurationException( "Invalid duration property " + name + "=" + value + ". Expected number, found: " + numberString); - } catch (ConfigurationException ex) { - throw new ConfigurationException( - "Invalid duration property " + name + "=" + value + ". " + ex.getMessage()); } } @@ -151,21 +151,21 @@ private static List filterBlanksAndNulls(final String[] values) { * @param unitString the time unit as a string * @return the parsed TimeUnit */ - private static TimeUnit getDurationUnit(final String unitString) { + private static Optional getDurationUnit(final String unitString) { switch (unitString) { case "": // Fallthrough expected case "ms": - return TimeUnit.MILLISECONDS; + return Optional.of(TimeUnit.MILLISECONDS); case "s": - return TimeUnit.SECONDS; + return Optional.of(TimeUnit.SECONDS); case "m": - return TimeUnit.MINUTES; + return Optional.of(TimeUnit.MINUTES); case "h": - return TimeUnit.HOURS; + return Optional.of(TimeUnit.HOURS); case "d": - return TimeUnit.DAYS; + return Optional.of(TimeUnit.DAYS); default: - throw new ConfigurationException("Invalid duration string, found: " + unitString); + return Optional.empty(); } } diff --git a/fabric-chaincode-shim/src/test/java/contract/Greeting.java b/fabric-chaincode-shim/src/test/java/contract/Greeting.java index 7f2a16f5..ac49bf4f 100644 --- a/fabric-chaincode-shim/src/test/java/contract/Greeting.java +++ b/fabric-chaincode-shim/src/test/java/contract/Greeting.java @@ -5,6 +5,8 @@ */ package contract; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.fabric.contract.annotation.DataType; import org.hyperledger.fabric.contract.annotation.Property; import org.json.JSONObject; @@ -53,13 +55,8 @@ public Greeting(final String text) { public static void validate(final Greeting greeting) { final String text = greeting.text; - if (text.length() != greeting.textLength) { - throw new Error("Length incorrectly set"); - } - - if (text.split(" ").length != greeting.wordCount) { - throw new Error("Word count incorrectly set"); - } + assertThat(text).as("greeting length").hasSize(greeting.textLength); + assertThat(text.split(" ")).as("word count").hasSize(greeting.wordCount); } public String toJSONString() { diff --git a/fabric-chaincode-shim/src/test/java/contract/SampleContract.java b/fabric-chaincode-shim/src/test/java/contract/SampleContract.java index a28a2924..426aab7c 100644 --- a/fabric-chaincode-shim/src/test/java/contract/SampleContract.java +++ b/fabric-chaincode-shim/src/test/java/contract/SampleContract.java @@ -24,6 +24,7 @@ license = @License(name = "fred", url = "http://fred.me"), version = "0.0.1", title = "samplecontract")) +@SuppressWarnings("PMD.SystemPrintln") @Default() public class SampleContract implements ContractInterface { public static int getBeforeInvoked() { @@ -109,7 +110,7 @@ public String t3(final Context ctx, final String exception, final String message throw new ChaincodeException(message, "T3ERR1"); } } else { - throw new RuntimeException(message); + throw new IllegalArgumentException(message); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggerTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggerTest.java index 62751cef..90c327d6 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggerTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggerTest.java @@ -9,15 +9,15 @@ import org.hyperledger.fabric.contract.ContractRuntimeException; import org.junit.jupiter.api.Test; -public class LoggerTest { +class LoggerTest { @Test - public void logger() { + void logger() { Logger.getLogger(LoggerTest.class); Logger.getLogger(LoggerTest.class.getName()); } @Test - public void testContractException() { + void testContractException() { final Logger logger = Logger.getLogger(LoggerTest.class); final ContractRuntimeException cre1 = new ContractRuntimeException(""); @@ -32,7 +32,7 @@ public void testContractException() { } @Test - public void testDebug() { + void testDebug() { Logger.getLogger(LoggerTest.class).debug("debug message"); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggingTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggingTest.java index c4b22d47..fb7df29f 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggingTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/LoggingTest.java @@ -17,7 +17,7 @@ public final class LoggingTest { @Test - public void testMapLevel() { + public void testMapLevel() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { assertEquals(Level.SEVERE, proxyMapLevel("ERROR"), "Error maps"); assertEquals(Level.SEVERE, proxyMapLevel("critical"), "Critical maps"); @@ -30,19 +30,11 @@ public void testMapLevel() { assertEquals(Level.INFO, proxyMapLevel(new Object[] {null}), "Info maps"); } - public Object proxyMapLevel(final Object... args) { - - try { - final Method m = Logging.class.getDeclaredMethod("mapLevel", String.class); - m.setAccessible(true); - return m.invoke(null, args); - } catch (NoSuchMethodException - | SecurityException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException e) { - throw new RuntimeException(e); - } + public Object proxyMapLevel(final Object... args) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + final Method m = Logging.class.getDeclaredMethod("mapLevel", String.class); + m.setAccessible(true); + return m.invoke(null, args); } @Test diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/TestUtil.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/TestUtil.java index 8c48b8b5..2aa32cfe 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/TestUtil.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/TestUtil.java @@ -108,7 +108,6 @@ public static String createCertWithIdentityAttributes(final String attributeValu final X509CertificateHolder builtCert = certBuilder.build(contentSigner); final X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X509") .generateCertificate(new ByteArrayInputStream(builtCert.getEncoded())); - final String encodedCert = Base64.getEncoder().encodeToString(certificate.getEncoded()); - return encodedCert; + return Base64.getEncoder().encodeToString(certificate.getEncoded()); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/AllTypesAsset.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/AllTypesAsset.java index 86cee5cf..4b4ed224 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/AllTypesAsset.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/AllTypesAsset.java @@ -122,7 +122,13 @@ public void setTheCustomObject(final MyType customObject) { this.theCustomObject = customObject; } - public boolean equals(final AllTypesAsset obj) { + @Override + public boolean equals(final Object other) { + if (!(other instanceof AllTypesAsset)) { + return false; + } + + AllTypesAsset obj = (AllTypesAsset) other; return theByte == obj.getTheByte() && theShort == obj.getTheShort() && theInt == obj.getTheInt() @@ -135,18 +141,15 @@ public boolean equals(final AllTypesAsset obj) { @Override public String toString() { - final StringBuilder builder = new StringBuilder(System.lineSeparator()); - builder.append("byte=" + theByte).append(System.lineSeparator()); - builder.append("short=" + theShort).append(System.lineSeparator()); - builder.append("int=" + theInt).append(System.lineSeparator()); - builder.append("long=" + theLong).append(System.lineSeparator()); - builder.append("float=" + theFloat).append(System.lineSeparator()); - builder.append("double=" + theDouble).append(System.lineSeparator()); - builder.append("boolean=" + theBoolean).append(System.lineSeparator()); - builder.append("char=" + theChar).append(System.lineSeparator()); - builder.append("String=" + theString).append(System.lineSeparator()); - builder.append("Mytype=" + theCustomObject).append(System.lineSeparator()); - - return builder.toString(); + return System.lineSeparator() + "byte=" + theByte + System.lineSeparator() + "short=" + + theShort + System.lineSeparator() + "int=" + + theInt + System.lineSeparator() + "long=" + + theLong + System.lineSeparator() + "float=" + + theFloat + System.lineSeparator() + "double=" + + theDouble + System.lineSeparator() + "boolean=" + + theBoolean + System.lineSeparator() + "char=" + + theChar + System.lineSeparator() + "String=" + + theString + System.lineSeparator() + "Mytype=" + + theCustomObject + System.lineSeparator(); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ChaincodeStubNaiveImpl.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ChaincodeStubNaiveImpl.java index 0054c1d6..ad475730 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ChaincodeStubNaiveImpl.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ChaincodeStubNaiveImpl.java @@ -60,7 +60,9 @@ public ChaincodeStubNaiveImpl() { @Override public List getArgs() { if (argsAsByte == null) { - argsAsByte = args.stream().map(i -> i.getBytes()).collect(Collectors.toList()); + argsAsByte = args.stream() + .map(arg -> arg.getBytes(StandardCharsets.UTF_8)) + .collect(Collectors.toList()); } return argsAsByte; } @@ -259,7 +261,7 @@ public byte[] getCreator() { @Override public Map getTransient() { - return null; + return new HashMap<>(); } @Override @@ -269,7 +271,7 @@ public byte[] getBinding() { void setStringArgs(final List args) { this.args = args; - this.argsAsByte = args.stream().map(i -> i.getBytes()).collect(Collectors.toList()); + this.argsAsByte = args.stream().map(String::getBytes).collect(Collectors.toList()); } public byte[] buildSerializedIdentity() { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractInterfaceTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractInterfaceTest.java index e3fcdd6a..d9c6ccfb 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractInterfaceTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/ContractInterfaceTest.java @@ -17,8 +17,7 @@ public class ContractInterfaceTest { @Test public void createContext() { assertThat( - (new ContractInterface() {}).createContext(new ChaincodeStubNaiveImpl()), - is(instanceOf(Context.class))); + new ContractInterface() {}.createContext(new ChaincodeStubNaiveImpl()), is(instanceOf(Context.class))); } @Test diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/MyType.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/MyType.java index 893aa81e..6cc39f0e 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/MyType.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/MyType.java @@ -27,12 +27,12 @@ public void setState(final String state) { @JSONPropertyIgnore() public boolean isStarted() { - return state.equals(STARTED); + return STARTED.equals(state); } @JSONPropertyIgnore() public boolean isStopped() { - return state.equals(STARTED); + return STOPPED.equals(state); } public MyType setValue(final String value) { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializerTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializerTest.java index eb15c8c9..68e732d6 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializerTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializerTest.java @@ -53,8 +53,6 @@ public void toBuffer() { final byte[] buffer = "[{\"value\":\"hello\"},{\"value\":\"world\"}]".getBytes(StandardCharsets.UTF_8); - System.out.println(new String(buffer, StandardCharsets.UTF_8)); - System.out.println(new String(bytes, StandardCharsets.UTF_8)); assertThat(bytes, equalTo(buffer)); } @@ -74,13 +72,9 @@ public void alltypes() { final AllTypesAsset all = new AllTypesAsset(); final TypeSchema ts = TypeSchema.typeConvert(AllTypesAsset.class); - System.out.println("TS = " + ts); final byte[] bytes = serializer.toBuffer(all, ts); - System.out.println("Data as toBuffer-ed " + new String(bytes, StandardCharsets.UTF_8)); final AllTypesAsset returned = (AllTypesAsset) serializer.fromBuffer(bytes, ts); - System.out.println("Start object = " + all); - System.out.println("Returned object = " + returned); assertTrue(all.equals(returned)); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/MetadataBuilderTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/MetadataBuilderTest.java index 903a287f..20538af4 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/MetadataBuilderTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/MetadataBuilderTest.java @@ -10,6 +10,7 @@ import java.io.Serializable; import java.lang.reflect.Field; import java.util.HashMap; +import java.util.Map; import org.everit.json.schema.loader.SchemaClient; import org.everit.json.schema.loader.internal.DefaultSchemaClient; import org.hyperledger.fabric.contract.ChaincodeStubNaiveImpl; @@ -23,39 +24,20 @@ import org.junit.jupiter.api.Test; public final class MetadataBuilderTest { - private final String expectedMetadataString = " {\n" + " \"components\": {\"schemas\": {}},\n" - + " \"$schema\": \"https://fabric-shim.github.io/contract-schema.json\",\n" - + " \"contracts\": {\"SampleContract\": {\n" - + " \"name\": \"SampleContract\",\n" + " \"transactions\": [],\n" - + " \"info\": {\n" - + " \"license\": {\"name\": \"\"},\n" + " \"description\": \"\",\n" - + " \"termsOfService\": \"\",\n" - + " \"title\": \"\",\n" + " \"version\": \"\",\n" - + " \"contact\": {\"email\": \"fred@example.com\"}\n" - + " }\n" + " }},\n" + " \"info\": {\n" + " \"license\": {\"name\": \"\"},\n" - + " \"description\": \"\",\n" - + " \"termsOfService\": \"\",\n" + " \"title\": \"\",\n" - + " \"version\": \"\",\n" - + " \"contact\": {\"email\": \"fred@example.com\"}\n" + " }\n" + " }\n" + ""; - // fields are private, so use reflection to bypass this for unit testing - private void setMetadataBuilderField(final String name, final Object value) { - try { - final Field f = MetadataBuilder.class.getDeclaredField(name); - f.setAccessible(true); - f.set(null, value); - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - throw new RuntimeException("Unable to set field " + e.getMessage()); - } + private void setMetadataBuilderField(final String name, final Object value) + throws NoSuchFieldException, IllegalAccessException { + final Field f = MetadataBuilder.class.getDeclaredField(name); + f.setAccessible(true); + f.set(null, value); } @BeforeEach @AfterEach - public void beforeAndAfterEach() { + public void beforeAndAfterEach() throws NoSuchFieldException, IllegalAccessException { setMetadataBuilderField("componentMap", new HashMap()); - setMetadataBuilderField("contractMap", new HashMap>()); + setMetadataBuilderField("contractMap", new HashMap>()); setMetadataBuilderField("overallInfoMap", new HashMap()); setMetadataBuilderField("schemaClient", new DefaultSchemaClient()); } @@ -69,14 +51,14 @@ public void systemContract() { } @Test - public void defaultSchemasNotLoadedFromNetwork() { + public void defaultSchemasNotLoadedFromNetwork() throws NoSuchFieldException, IllegalAccessException { final ContractDefinition contractDefinition = new ContractDefinitionImpl(SampleContract.class); MetadataBuilder.addContract(contractDefinition); setMetadataBuilderField("schemaClient", new SchemaClient() { @Override public InputStream get(final String uri) { - throw new RuntimeException("Refusing to load schema: " + uri); + throw new IllegalStateException("Refusing to load schema: " + uri); } }); MetadataBuilder.validate(); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/TypeSchemaTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/TypeSchemaTest.java index 4139c165..9e01dd11 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/TypeSchemaTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/metadata/TypeSchemaTest.java @@ -27,16 +27,13 @@ public void beforeEach() {} public void putIfNotNull() { final TypeSchema ts = new TypeSchema(); - System.out.println("Key - value"); ts.putIfNotNull("Key", "value"); - System.out.println("Key - null"); final String nullstr = null; ts.putIfNotNull("Key", nullstr); assertThat(ts.get("Key"), equalTo("value")); - System.out.println("Key - "); ts.putIfNotNull("Key", ""); assertThat(ts.get("Key"), equalTo("value")); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/ContractDefinitionTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/ContractDefinitionTest.java index a948720c..523238df 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/ContractDefinitionTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/ContractDefinitionTest.java @@ -33,7 +33,7 @@ public void constructor() throws NoSuchMethodException, SecurityException { public class FailureTestObject {} private boolean fail; - private final int step = 1; + private static final int STEP = 1; @Test public void unknownRoute() { @@ -45,7 +45,7 @@ public void unknownRoute() { public void checkPackageAccess(final String pkg) { if (pkg.startsWith("org.hyperledger.fabric.contract")) { - if (count >= step) { + if (count >= STEP) { throw new SecurityException("Sorry I can't do that"); } count++; @@ -54,9 +54,7 @@ public void checkPackageAccess(final String pkg) { } @Override - public void checkPermission(final Permission perm) { - return; - } + public void checkPermission(final Permission perm) {} }; try { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/DataTypeDefinitionTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/DataTypeDefinitionTest.java index f08e3bd4..bc0762d3 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/DataTypeDefinitionTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/DataTypeDefinitionTest.java @@ -5,13 +5,12 @@ */ package org.hyperledger.fabric.contract.routing; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.hasKey; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import java.util.Map; import org.hyperledger.fabric.contract.MyType2; +import org.hyperledger.fabric.contract.metadata.TypeSchema; import org.hyperledger.fabric.contract.routing.impl.DataTypeDefinitionImpl; import org.junit.jupiter.api.Test; @@ -19,23 +18,25 @@ public class DataTypeDefinitionTest { @Test public void constructor() { final DataTypeDefinitionImpl dtd = new DataTypeDefinitionImpl(MyType2.class); - assertThat(dtd.getTypeClass(), equalTo(MyType2.class)); - assertThat(dtd.getName(), equalTo("org.hyperledger.fabric.contract.MyType2")); - assertThat(dtd.getSimpleName(), equalTo("MyType2")); + assertThat(dtd.getTypeClass()).isEqualTo(MyType2.class); + assertThat(dtd.getName()).isEqualTo("org.hyperledger.fabric.contract.MyType2"); + assertThat(dtd.getSimpleName()).isEqualTo("MyType2"); final Map properties = dtd.getProperties(); - assertThat(properties.size(), equalTo(2)); - assertThat(properties, hasKey("value")); - assertThat(properties, hasKey("constrainedValue")); + assertThat(properties.size()).isEqualTo(2); + assertThat(properties).containsKey("value"); + assertThat(properties).containsKey("constrainedValue"); final PropertyDefinition pd = properties.get("constrainedValue"); - final Map ts = pd.getSchema(); + final TypeSchema ts = pd.getSchema(); - assertThat(ts, hasEntry("title", "MrProperty")); - assertThat(ts, hasEntry("Pattern", "[a-z]")); - assertThat(ts, hasEntry("uniqueItems", false)); - assertThat(ts, hasEntry("required", new String[] {"true", "false"})); - assertThat(ts, hasEntry("enum", new String[] {"a", "bee", "cee", "dee"})); - assertThat(ts, hasEntry("minimum", 42)); + assertThat(ts) + .contains( + entry("title", "MrProperty"), + entry("Pattern", "[a-z]"), + entry("uniqueItems", false), + entry("required", new String[] {"true", "false"}), + entry("enum", new String[] {"a", "bee", "cee", "dee"}), + entry("minimum", 42)); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/TxFunctionTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/TxFunctionTest.java index 428a9483..dbe937d2 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/TxFunctionTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/routing/TxFunctionTest.java @@ -70,7 +70,6 @@ public void property() throws NoSuchMethodException, SecurityException { final TypeSchema ts = new TypeSchema(); txfn.setReturnSchema(ts); final TypeSchema rts = txfn.getReturnSchema(); - System.out.println(ts); assertEquals(ts, rts); } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/simplepath/ContractSimplePathTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/simplepath/ContractSimplePathTest.java index 489919d4..185a5d74 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/simplepath/ContractSimplePathTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/simplepath/ContractSimplePathTest.java @@ -78,7 +78,7 @@ public ChaincodeMessage newInvokeFn(final String[] args) { public String getLastReturnString() throws Exception { final Response resp = Response.parseFrom(server.getLastMessageRcvd().getPayload()); - return (resp.getPayload().toStringUtf8()); + return resp.getPayload().toStringUtf8(); } public void setLogLevel(final String logLevel) { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/metrics/impl/DefaultProviderTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/metrics/impl/DefaultProviderTest.java index 0da931aa..4059cfc5 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/metrics/impl/DefaultProviderTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/metrics/impl/DefaultProviderTest.java @@ -13,7 +13,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import org.hyperledger.fabric.metrics.MetricsProvider; import org.hyperledger.fabric.metrics.TaskMetricsCollector; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -22,8 +21,8 @@ public class DefaultProviderTest { @Test - public void allMethods() { - MetricsProvider provider = new DefaultProvider(); + public void allMethods() throws InterruptedException { + DefaultProvider provider = new DefaultProvider(); provider.setTaskMetricsCollector(new TaskMetricsCollector() { @Override @@ -73,13 +72,8 @@ public int getActiveCount() { perfLogger.addHandler(mockHandler); provider.initialize(new Properties()); - ((DefaultProvider) provider).logMetrics(); - try { - Thread.sleep(6000); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } + provider.logMetrics(); + Thread.sleep(6000); Mockito.verify(mockHandler, Mockito.atLeast(1)).publish(argumentCaptor.capture()); LogRecord lr = argumentCaptor.getValue(); String msg = lr.getMessage(); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeStubTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeStubTest.java index ccf3185a..fc1e8ec0 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeStubTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChaincodeStubTest.java @@ -21,7 +21,8 @@ public class ChaincodeStubTest { - class FakeStub implements ChaincodeStub { + @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull") + static final class FakeStub implements ChaincodeStub { @Override public List getArgs() { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeerTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeerTest.java index d3832502..4898d917 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeerTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ChatChaincodeWithPeerTest.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.List; import java.util.Properties; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.hyperledger.fabric.metrics.Metrics; import org.hyperledger.fabric.protos.peer.ChaincodeID; @@ -138,6 +137,7 @@ void connectNull() throws IOException { } @Test + @SuppressWarnings("PMD.SystemPrintln") void connectAndReceiveRegister() throws IOException { environmentVariables.set("CORE_CHAINCODE_ID_NAME", "mycc"); ChaincodeBase chaincodeBase = new EmptyChaincode(); @@ -167,14 +167,14 @@ public void onCompleted() {} }); assertNotNull(connect); - final ByteString payload = org.hyperledger.fabric.protos.peer.ChaincodeInput.newBuilder() + final ByteString payload = ChaincodeInput.newBuilder() .addArgs(ByteString.copyFromUtf8("")) .build() .toByteString(); final ChaincodeMessage initMsg = MessageUtil.newEventMessage(INIT, TEST_CHANNEL, "0", payload, null); connect.onNext(initMsg); - try { + { final List args = Stream.of("invoke", "a", "1").map(x -> x.getBytes(UTF_8)).collect(toList()); final ByteString invocationSpecPayload = ChaincodeSpec.newBuilder() @@ -182,7 +182,7 @@ public void onCompleted() {} .setName(chaincodeBase.getId()) .build()) .setInput(ChaincodeInput.newBuilder() - .addAllArgs(args.stream().map(ByteString::copyFrom).collect(Collectors.toList())) + .addAllArgs(args.stream().map(ByteString::copyFrom).collect(toList())) .build()) .build() .toByteString(); @@ -195,11 +195,9 @@ public void onCompleted() {} .build(); connect.onNext(invokeChaincodeMessage); System.out.println(invokeChaincodeMessage.getPayload().toStringUtf8()); - } catch (Exception e) { - } - try { + { final List args = Stream.of("invoke", "a", "1").map(x -> x.getBytes(UTF_8)).collect(toList()); final ByteString invocationSpecPayload = ChaincodeSpec.newBuilder() @@ -207,7 +205,7 @@ public void onCompleted() {} .setName(chaincodeBase.getId()) .build()) .setInput(ChaincodeInput.newBuilder() - .addAllArgs(args.stream().map(ByteString::copyFrom).collect(Collectors.toList())) + .addAllArgs(args.stream().map(ByteString::copyFrom).collect(toList())) .build()) .build() .toByteString(); @@ -220,8 +218,6 @@ public void onCompleted() {} .build(); connect.onNext(invokeChaincodeMessage); System.out.println(invokeChaincodeMessage.getPayload().toStringUtf8()); - } catch (Exception e) { - } } @@ -283,6 +279,7 @@ public void onCompleted() {} } @Test + @SuppressWarnings("PMD.AvoidThrowingRawExceptionTypes") void connectOnCompletedException() throws IOException { environmentVariables.set("CORE_CHAINCODE_ID_NAME", "mycc"); ChaincodeBase chaincodeBase = new EmptyChaincode(); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/fvt/ChaincodeFVTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/fvt/ChaincodeFVTest.java index 490be49b..e19389c3 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/fvt/ChaincodeFVTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/fvt/ChaincodeFVTest.java @@ -107,7 +107,7 @@ public Response invoke(final ChaincodeStub stub) { } }; - final ByteString payload = org.hyperledger.fabric.protos.peer.ChaincodeInput.newBuilder() + final ByteString payload = ChaincodeInput.newBuilder() .addArgs(ByteString.copyFromUtf8("")) .build() .toByteString(); @@ -553,7 +553,7 @@ public Response invoke(final ChaincodeStub stub) { } }; - final ByteString payload = org.hyperledger.fabric.protos.peer.ChaincodeInput.newBuilder() + final ByteString payload = ChaincodeInput.newBuilder() .addArgs(ByteString.copyFromUtf8("")) .build() .toByteString(); @@ -575,9 +575,9 @@ public Response invoke(final ChaincodeStub stub) { assertThat(server.getLastMessageSend().getType(), is(INIT)); assertThat(server.getLastMessageRcvd().getType(), is(COMPLETED)); - String resp1 = (Response.parseFrom(server.getLastMessageRcvd().getPayload()) + String resp1 = Response.parseFrom(server.getLastMessageRcvd().getPayload()) .getPayload() - .toStringUtf8()); + .toStringUtf8(); assertThat(resp1, is("Wrong response1")); final ByteString invokePayload = ChaincodeInput.newBuilder().build().toByteString(); @@ -602,7 +602,7 @@ public void testStreamShutdown() throws Exception { public Response init(final ChaincodeStub stub) { try { Thread.sleep(10); - } catch (final InterruptedException e) { + } catch (final InterruptedException ignored) { } return ResponseUtils.newSuccessResponse(); } @@ -613,7 +613,7 @@ public Response invoke(final ChaincodeStub stub) { } }; - final ByteString payload = org.hyperledger.fabric.protos.peer.ChaincodeInput.newBuilder() + final ByteString payload = ChaincodeInput.newBuilder() .addArgs(ByteString.copyFromUtf8("")) .build() .toByteString(); diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyModificationImplTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyModificationImplTest.java index 2dc72dc9..b0f5b6be 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyModificationImplTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyModificationImplTest.java @@ -7,17 +7,10 @@ package org.hyperledger.fabric.shim.impl; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.google.protobuf.ByteString; import com.google.protobuf.Timestamp; -import java.time.Instant; import java.util.stream.Stream; import org.hyperledger.fabric.shim.ledger.KeyModification; import org.junit.jupiter.api.Test; @@ -40,7 +33,7 @@ public void testGetTxId() { new KeyModificationImpl(org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() .setTxId("txid") .build()); - assertThat(km.getTxId(), is(equalTo("txid"))); + assertThat(km.getTxId()).isEqualTo("txid"); } @Test @@ -49,7 +42,7 @@ public void testGetValue() { new KeyModificationImpl(org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() .setValue(ByteString.copyFromUtf8("value")) .build()); - assertThat(km.getValue(), is(equalTo("value".getBytes(UTF_8)))); + assertThat(km.getValue()).isEqualTo("value".getBytes(UTF_8)); } @Test @@ -58,7 +51,7 @@ public void testGetStringValue() { new KeyModificationImpl(org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() .setValue(ByteString.copyFromUtf8("value")) .build()); - assertThat(km.getStringValue(), is(equalTo("value"))); + assertThat(km.getStringValue()).isEqualTo("value"); } @Test @@ -68,8 +61,8 @@ public void testGetTimestamp() { .setTimestamp( Timestamp.newBuilder().setSeconds(1234567890L).setNanos(123456789)) .build()); - assertThat(km.getTimestamp(), hasProperty("epochSecond", equalTo(1234567890L))); - assertThat(km.getTimestamp(), hasProperty("nano", equalTo(123456789))); + assertThat(km.getTimestamp().getEpochSecond()).isEqualTo(1234567890L); + assertThat(km.getTimestamp().getNano()).isEqualTo(123456789); } @Test @@ -79,24 +72,22 @@ public void testIsDeleted() { org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() .setIsDelete(b) .build()); - assertThat(km.isDeleted(), is(b)); + assertThat(km.isDeleted()).isEqualTo(b); }); } @Test public void testHashCode() { - final KeyModification km = + final KeyModification km1 = + new KeyModificationImpl(org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() + .setIsDelete(false) + .build()); + final KeyModification km2 = new KeyModificationImpl(org.hyperledger.fabric.protos.ledger.queryresult.KeyModification.newBuilder() .setIsDelete(false) .build()); - int expectedHashCode = 31; - expectedHashCode = expectedHashCode + 1237; - expectedHashCode = expectedHashCode * 31 + Instant.EPOCH.hashCode(); - expectedHashCode = expectedHashCode * 31 + "".hashCode(); - expectedHashCode = expectedHashCode * 31 + ByteString.copyFromUtf8("").hashCode(); - - assertEquals(expectedHashCode, km.hashCode(), "Wrong hash code"); + assertThat(km1.hashCode()).isEqualTo(km2.hashCode()); } @Test @@ -115,7 +106,7 @@ public void testEquals() { .setIsDelete(false) .build()); - assertFalse(km1.equals(km2)); - assertTrue(km1.equals(km3)); + assertThat(km1).isNotEqualTo(km2); + assertThat(km1).isEqualTo(km3); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyValueImplTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyValueImplTest.java index 3b8bbf43..e216fcfb 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyValueImplTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/KeyValueImplTest.java @@ -7,12 +7,7 @@ package org.hyperledger.fabric.shim.impl; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.google.protobuf.ByteString; import org.hyperledger.fabric.protos.ledger.queryresult.KV; @@ -34,7 +29,7 @@ public void testGetKey() { .setKey("key") .setValue(ByteString.copyFromUtf8("value")) .build()); - assertThat(kv.getKey(), is(equalTo("key"))); + assertThat(kv.getKey()).isEqualTo("key"); } @Test @@ -43,7 +38,7 @@ public void testGetValue() { .setKey("key") .setValue(ByteString.copyFromUtf8("value")) .build()); - assertThat(kv.getValue(), is(equalTo("value".getBytes(UTF_8)))); + assertThat(kv.getValue()).isEqualTo("value".getBytes(UTF_8)); } @Test @@ -52,18 +47,15 @@ public void testGetStringValue() { .setKey("key") .setValue(ByteString.copyFromUtf8("value")) .build()); - assertThat(kv.getStringValue(), is(equalTo("value"))); + assertThat(kv.getStringValue()).isEqualTo("value"); } @Test public void testHashCode() { - final KeyValueImpl kv = new KeyValueImpl(KV.newBuilder().build()); + final KeyValueImpl kv1 = new KeyValueImpl(KV.newBuilder().build()); + final KeyValueImpl kv2 = new KeyValueImpl(KV.newBuilder().build()); - int expectedHashCode = 31; - expectedHashCode = expectedHashCode + "".hashCode(); - expectedHashCode = expectedHashCode * 31 + ByteString.copyFromUtf8("").hashCode(); - - assertEquals(expectedHashCode, kv.hashCode(), "Wrong hashcode"); + assertThat(kv1.hashCode()).isEqualTo(kv2.hashCode()); } @Test @@ -88,8 +80,8 @@ public void testEquals() { .setValue(ByteString.copyFromUtf8("valueA")) .build()); - assertFalse(kv1.equals(kv2)); - assertFalse(kv1.equals(kv3)); - assertTrue(kv1.equals(kv4)); + assertThat(kv1).isNotEqualTo(kv2); + assertThat(kv1).isNotEqualTo(kv3); + assertThat(kv1).isEqualTo(kv4); } } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImplTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImplTest.java index 3d1b299f..39665da4 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImplTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/impl/QueryResultsIteratorWithMetadataImplTest.java @@ -6,9 +6,8 @@ package org.hyperledger.fabric.shim.impl; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.protobuf.ByteString; import java.util.function.Function; @@ -23,18 +22,15 @@ public class QueryResultsIteratorWithMetadataImplTest { public void getMetadata() { final QueryResultsIteratorWithMetadataImpl testIter = new QueryResultsIteratorWithMetadataImpl<>( null, "", "", prepareQueryResponse().toByteString(), queryResultBytesToKv); - assertThat(testIter.getMetadata().getBookmark(), is("asdf")); - assertThat(testIter.getMetadata().getFetchedRecordsCount(), is(2)); + assertThat(testIter.getMetadata().getBookmark()).isEqualTo("asdf"); + assertThat(testIter.getMetadata().getFetchedRecordsCount()).isEqualTo(2); } @Test public void getInvalidMetadata() { - try { - new QueryResultsIteratorWithMetadataImpl<>( - null, "", "", prepareQueryResponseWrongMeta().toByteString(), queryResultBytesToKv); - fail(); - } catch (final RuntimeException e) { - } + assertThatThrownBy(() -> new QueryResultsIteratorWithMetadataImpl<>( + null, "", "", prepareQueryResponseWrongMeta().toByteString(), queryResultBytesToKv)) + .isInstanceOf(RuntimeException.class); } private final Function queryResultBytesToKv = new Function() { diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/ChaincodeMockPeer.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/ChaincodeMockPeer.java index 710b9eb0..05a6e762 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/ChaincodeMockPeer.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/ChaincodeMockPeer.java @@ -45,13 +45,14 @@ public ChaincodeMockPeer(final List scenario, final int port) { } /** Start serving requests. */ + @SuppressWarnings("PMD.SystemPrintln") public void start() throws IOException { server.start(); - LOGGER.info("Server started, listening on " + port); + LOGGER.info(() -> "Server started, listening on " + port); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { - // Use stderr here since the logger may has been reset by its JVM shutdown hook. + // Use stderr here since the logger may have been reset by its JVM shutdown hook. System.err.println("*** shutting down gRPC server since JVM is shutting down"); ChaincodeMockPeer.this.stop(); System.err.println("*** server shut down"); @@ -65,7 +66,7 @@ public void stop() { server.shutdownNow(); try { server.awaitTermination(); - } catch (final InterruptedException e) { + } catch (final InterruptedException ignored) { } } } @@ -78,7 +79,7 @@ public void stop() { public void send(final ChaincodeMessage msg) { this.service.lastMessageSend = msg; - LOGGER.info("Mock peer => Sending message: " + msg); + LOGGER.info(() -> "Mock peer => Sending message: " + msg); this.service.send(msg); } @@ -96,7 +97,7 @@ public ChaincodeMessage getLastMessageRcvd() { return this.service.lastMessageRcvd; } - public ArrayList getAllReceivedMessages() { + public List getAllReceivedMessages() { return this.service.allMessages; } @@ -123,7 +124,7 @@ private static class ChaincodeMockPeerService extends ChaincodeSupportGrpc.Chain private int lastExecutedStepNumber; private ChaincodeMessage lastMessageRcvd; private ChaincodeMessage lastMessageSend; - private final ArrayList allMessages = new ArrayList<>(); + private final List allMessages = new ArrayList<>(); private StreamObserver observer; // create a lock, with fair property @@ -158,9 +159,10 @@ public StreamObserver register(final StreamObserver Got message: " + chaincodeMessage); + LOGGER.info(() -> "Mock peer => Got message: " + chaincodeMessage); ChaincodeMockPeerService.this.lastMessageRcvd = chaincodeMessage; ChaincodeMockPeerService.this.allMessages.add(chaincodeMessage); if (chaincodeMessage.getType().equals(PUT_STATE)) { @@ -178,11 +180,11 @@ public void onNext(final ChaincodeMessage chaincodeMessage) { final List nextSteps = step.next(); for (final ChaincodeMessage m : nextSteps) { ChaincodeMockPeerService.this.lastMessageSend = m; - LOGGER.info("Mock peer => Sending response message: " + m); + LOGGER.info(() -> "Mock peer => Sending response message: " + m); ChaincodeMockPeerService.this.send(m); } } else { - LOGGER.warning("Non expected message rcvd in step " + LOGGER.warning(() -> "Non expected message rcvd in step " + step.getClass().getSimpleName()); } ChaincodeMockPeerService.this.lastExecutedStepNumber++; @@ -194,7 +196,7 @@ public void onNext(final ChaincodeMessage chaincodeMessage) { @Override public void onError(final Throwable throwable) { - System.out.println(throwable); + throwable.printStackTrace(); } @Override @@ -203,6 +205,7 @@ public void onCompleted() {} } } + @SuppressWarnings("PMD.SystemPrintln") public static void checkScenarioStepEnded( final ChaincodeMockPeer s, final int step, final int timeout, final TimeUnit units) throws Exception { try { @@ -214,7 +217,7 @@ public static void checkScenarioStepEnded( } try { Thread.sleep(500); - } catch (final InterruptedException e) { + } catch (final InterruptedException ignored) { } } }), diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/GetHistoryForKeyStep.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/GetHistoryForKeyStep.java index 96e2fcc0..c307d6ae 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/GetHistoryForKeyStep.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/GetHistoryForKeyStep.java @@ -28,7 +28,7 @@ public final class GetHistoryForKeyStep implements ScenarioStep { * @param vals list of keys to generate ("key" => "key Value") pairs */ public GetHistoryForKeyStep(final boolean hasNext, final String... vals) { - this.values = vals; + this.values = Arrays.copyOf(vals, vals.length); this.hasNext = hasNext; } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/QueryResultStep.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/QueryResultStep.java index 26c52724..69712719 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/QueryResultStep.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/mock/peer/QueryResultStep.java @@ -29,7 +29,7 @@ public abstract class QueryResultStep implements ScenarioStep { * @param vals list of keys to generate ("key" => "key Value") pairs */ QueryResultStep(final boolean hasNext, final String... vals) { - this.values = vals; + this.values = Arrays.copyOf(vals, vals.length); this.hasNext = hasNext; } diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/traces/impl/TestSpanExporterProvider.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/traces/impl/TestSpanExporterProvider.java index 5baa2ff9..95891c67 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/traces/impl/TestSpanExporterProvider.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/traces/impl/TestSpanExporterProvider.java @@ -21,7 +21,7 @@ public final class TestSpanExporterProvider implements ConfigurableSpanExporterP @Override public CompletableResultCode export(final Collection spans) { - TestSpanExporterProvider.SPANS.addAll(spans); + SPANS.addAll(spans); return CompletableResultCode.ofSuccess(); } diff --git a/pmd-ruleset.xml b/pmd-ruleset.xml new file mode 100644 index 00000000..c440f003 --- /dev/null +++ b/pmd-ruleset.xml @@ -0,0 +1,48 @@ + + + Custom PMD ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +