Developing
+ * The {@link org.hyperledger.fabric.contract} package implements the Fabric programming model as described in the Developing
* Applications chapter of the Fabric documentation.
*
- *
- * The main interface to implement is
- * {@link org.hyperledger.fabric.contract.ContractInterface}
- *
+ *
The main interface to implement is {@link org.hyperledger.fabric.contract.ContractInterface}
*/
package org.hyperledger.fabric.contract;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ContractDefinition.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ContractDefinition.java
index ba8072cb1..4bca0f44d 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ContractDefinition.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ContractDefinition.java
@@ -8,77 +8,56 @@
import java.lang.reflect.Method;
import java.util.Collection;
-
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contract;
/**
* Definition of the Contract
*
- * A data structure that represents the contract that will be executed in the
- * chaincode. Primarily has
+ *
A data structure that represents the contract that will be executed in the chaincode. Primarily has
*
- * Name - either defined by the Contract annotation or the Class name (can be
- * referred to as Namespace) Default - is the default contract (defined by the
- * Default annotation) TxFunctions in this contract do not need the name prefix
+ *
Name - either defined by the Contract annotation or the Class name (can be referred to as Namespace) Default - is
+ * the default contract (defined by the Default annotation) TxFunctions in this contract do not need the name prefix
* when invoked TxFunctions - the transaction functions defined in this contract
*
- * Will embedded the ContractInterface instance, as well as the annotation
- * itself, and the routing for any tx function that is unknown
- *
+ *
Will embedded the ContractInterface instance, as well as the annotation itself, and the routing for any tx
+ * function that is unknown
*/
public interface ContractDefinition {
- /**
- * @return the fully qualified name of the Contract
- */
+ /** @return the fully qualified name of the Contract */
String getName();
- /**
- * @return Complete collection of all the transaction functions in this contract
- */
+ /** @return Complete collection of all the transaction functions in this contract */
Collection getTxFunctions();
- /**
- * @return Object reference to the instantiated object that is 'the contract'
- */
+ /** @return Object reference to the instantiated object that is 'the contract' */
Class extends ContractInterface> getContractImpl();
/**
- * @param m The java.lang.reflect object that is the method that is a tx
- * function
+ * @param m The java.lang.reflect object that is the method that is a tx function
* @return TxFunction object representing this method
*/
TxFunction addTxFunction(Method m);
- /**
- *
- * @return if this is contract is the default one or not
- */
+ /** @return if this is contract is the default one or not */
boolean isDefault();
/**
- *
* @param method name to be returned
* @return TxFunction that represents this requested method
*/
TxFunction getTxFunction(String method);
/**
- *
* @param method name to be checked
* @return true if this txFunction exists or not
*/
boolean hasTxFunction(String method);
- /**
- * @return The TxFunction to be used for this contract in case of unknown
- * request
- */
+ /** @return The TxFunction to be used for this contract in case of unknown request */
TxFunction getUnknownRoute();
- /**
- * @return Underlying raw annotation
- */
+ /** @return Underlying raw annotation */
Contract getAnnotation();
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/DataTypeDefinition.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/DataTypeDefinition.java
index 3267a718c..84d2e3fbf 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/DataTypeDefinition.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/DataTypeDefinition.java
@@ -6,33 +6,22 @@
package org.hyperledger.fabric.contract.routing;
import java.util.Map;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
public interface DataTypeDefinition {
- /**
- * @return String
- */
+ /** @return String */
String getName();
- /**
- * @return Map of String to PropertyDefinitions
- */
+ /** @return Map of String to PropertyDefinitions */
Map getProperties();
- /**
- * @return String
- */
+ /** @return String */
String getSimpleName();
- /**
- * @return Class object of the type
- */
+ /** @return Class object of the type */
Class> getTypeClass();
- /**
- * @return TypeSchema
- */
+ /** @return TypeSchema */
TypeSchema getSchema();
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ParameterDefinition.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ParameterDefinition.java
index bc81c234c..2411e6aad 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ParameterDefinition.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/ParameterDefinition.java
@@ -6,29 +6,19 @@
package org.hyperledger.fabric.contract.routing;
import java.lang.reflect.Parameter;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
public interface ParameterDefinition {
- /**
- * @return Class type of the parameter
- */
+ /** @return Class type of the parameter */
Class> getTypeClass();
- /**
- * @return TypeSchema of the parameter
- */
+ /** @return TypeSchema of the parameter */
TypeSchema getSchema();
- /**
- * @return Parameter
- */
+ /** @return Parameter */
Parameter getParameter();
- /**
- * @return name of the parameter
- */
+ /** @return name of the parameter */
String getName();
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/PropertyDefinition.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/PropertyDefinition.java
index dd4e7e372..4c53cdc79 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/PropertyDefinition.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/PropertyDefinition.java
@@ -6,29 +6,19 @@
package org.hyperledger.fabric.contract.routing;
import java.lang.reflect.Field;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
public interface PropertyDefinition {
- /**
- * @return Class of the Property
- */
+ /** @return Class of the Property */
Class> getTypeClass();
- /**
- * @return TypeSchema
- */
+ /** @return TypeSchema */
TypeSchema getSchema();
- /**
- * @return Field
- */
+ /** @return Field */
Field getField();
- /**
- * @return Name of the property
- */
+ /** @return Name of the property */
String getName();
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/RoutingRegistry.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/RoutingRegistry.java
index 3c4e9825e..264ff9b21 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/RoutingRegistry.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/RoutingRegistry.java
@@ -6,7 +6,6 @@
package org.hyperledger.fabric.contract.routing;
import java.util.Collection;
-
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.execution.InvocationRequest;
@@ -65,5 +64,4 @@ public interface RoutingRegistry {
* @param typeRegistry
*/
void findAndSetContracts(TypeRegistry typeRegistry);
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TransactionType.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TransactionType.java
index 80472df52..37e307b7d 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TransactionType.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TransactionType.java
@@ -6,24 +6,14 @@
package org.hyperledger.fabric.contract.routing;
public enum TransactionType {
- /**
- *
- */
- INVOKE, //deprecated
- /**
- *
- */
- QUERY, //deprecated
- /**
- *
- */
- DEFAULT, //deprecated
- /**
- *
- */
+ /** */
+ INVOKE, // deprecated
+ /** */
+ QUERY, // deprecated
+ /** */
+ DEFAULT, // deprecated
+ /** */
SUBMIT,
- /**
- *
- */
+ /** */
EVALUATE
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TxFunction.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TxFunction.java
index 860e22783..392419fae 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TxFunction.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TxFunction.java
@@ -8,7 +8,6 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
-
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.metadata.TypeSchema;
@@ -17,86 +16,68 @@ public interface TxFunction {
interface Routing {
/**
* Method to route calls to the transaction function.
+ *
* @return a method.
*/
Method getMethod();
/**
* The associated contract class.
+ *
* @return a contract class.
*/
Class extends ContractInterface> getContractClass();
/**
* The associated contract instance.
+ *
* @return a contract.
* @throws IllegalAccessException
* @throws InstantiationException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
- ContractInterface getContractInstance() throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException;
+ ContractInterface getContractInstance()
+ throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException;
/**
* Name of the serializer used for the transaction function.
+ *
* @return a serializer name.
*/
String getSerializerName();
}
- /**
- * @return is this tx to be called when request fn is unknown
- */
+ /** @return is this tx to be called when request fn is unknown */
boolean isUnknownTx();
- /**
- * @param unknown true if the transaction is to be called when the request fn is unknown; otherwise false.
- */
+ /** @param unknown true if the transaction is to be called when the request fn is unknown; otherwise false. */
void setUnknownTx(boolean unknown);
- /**
- * @return Name
- */
+ /** @return Name */
String getName();
- /**
- * @return Routing object
- */
+ /** @return Routing object */
Routing getRouting();
- /**
- * @return Class of the return type
- */
+ /** @return Class of the return type */
Class> getReturnType();
- /**
- * @return Parameter array
- */
+ /** @return Parameter array */
java.lang.reflect.Parameter[] getParameters();
- /**
- * @return Submit or Evaluate
- */
+ /** @return Submit or Evaluate */
TransactionType getType();
- /**
- * @param returnSchema
- */
+ /** @param returnSchema */
void setReturnSchema(TypeSchema returnSchema);
- /**
- * @return TypeSchema of the return type
- */
+ /** @return TypeSchema of the return type */
TypeSchema getReturnSchema();
- /**
- * @param list
- */
+ /** @param list */
void setParameterDefinitions(List list);
- /**
- * @return List of parameters
- */
+ /** @return List of parameters */
List getParamsList();
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TypeRegistry.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TypeRegistry.java
index 732719561..4b61e2d41 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TypeRegistry.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TypeRegistry.java
@@ -6,27 +6,20 @@
package org.hyperledger.fabric.contract.routing;
import java.util.Collection;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
import org.hyperledger.fabric.contract.routing.impl.TypeRegistryImpl;
public interface TypeRegistry {
- /**
- * @return TypeRegistry
- */
+ /** @return TypeRegistry */
static TypeRegistry getRegistry() {
return TypeRegistryImpl.getInstance();
}
- /**
- * @param dtd
- */
+ /** @param dtd */
void addDataType(DataTypeDefinition dtd);
- /**
- * @param cl
- */
+ /** @param cl */
void addDataType(Class> cl);
/**
@@ -41,9 +34,6 @@ static TypeRegistry getRegistry() {
*/
DataTypeDefinition getDataType(TypeSchema schema);
- /**
- * @return All datatypes
- */
+ /** @return All datatypes */
Collection getAllDataTypes();
-
}
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 09a293fcb..8df5f3ab9 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
@@ -9,7 +9,6 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
-
import org.hyperledger.fabric.Logger;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
@@ -22,28 +21,23 @@
/**
* Implementation of the ContractDefinition.
*
- * Contains information about the contract, including transaction functions and
- * unknown transaction routing
- *
+ * 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 extends ContractInterface> contractClz;
private final Contract contractAnnotation;
- private TxFunction unknownTx;
+ private final TxFunction unknownTx;
- /**
- *
- * @param cl
- */
+ /** @param cl */
public ContractDefinitionImpl(final Class extends ContractInterface> 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();
@@ -58,17 +52,18 @@ public ContractDefinitionImpl(final Class extends ContractInterface> 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));
+ final ContractRuntimeException cre =
+ new ContractRuntimeException("Failure to find unknownTransaction method", e);
+ 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
@@ -88,13 +83,13 @@ public Class extends ContractInterface> 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 78c2b9a12..8d1ed8679 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,9 +7,9 @@
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;
import org.hyperledger.fabric.contract.metadata.TypeSchema;
import org.hyperledger.fabric.contract.routing.DataTypeDefinition;
@@ -22,10 +22,8 @@ public final class DataTypeDefinitionImpl implements DataTypeDefinition {
private final String simpleName;
private final Class> clazz;
- /**
- *
- * @param componentClass
- */
+ /** @param componentClass */
+ @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
public DataTypeDefinitionImpl(final Class> componentClass) {
this.clazz = componentClass;
this.name = componentClass.getName();
@@ -43,21 +41,23 @@ public DataTypeDefinitionImpl(final Class> componentClass) {
for (int i = 0; i < userSupplied.length; i += 2) {
final String userKey = userSupplied[i];
Object userValue;
- switch (userKey.toLowerCase()) {
- case "title":
- case "pattern":
- userValue = userSupplied[i + 1];
- break;
- case "uniqueitems":
- userValue = Boolean.parseBoolean(userSupplied[i + 1]);
- break;
- case "required":
- case "enum":
- userValue = Stream.of(userSupplied[i + 1].split(",")).map(String::trim).toArray(String[]::new);
- break;
- default:
- userValue = Integer.parseInt(userSupplied[i + 1]);
- break;
+ switch (userKey.toLowerCase(Locale.getDefault())) {
+ case "title":
+ case "pattern":
+ userValue = userSupplied[i + 1];
+ break;
+ case "uniqueitems":
+ userValue = Boolean.parseBoolean(userSupplied[i + 1]);
+ break;
+ case "required":
+ case "enum":
+ userValue = Stream.of(userSupplied[i + 1].split(","))
+ .map(String::trim)
+ .toArray(String[]::new);
+ break;
+ default:
+ userValue = Integer.parseInt(userSupplied[i + 1]);
+ break;
}
ts.put(userKey, userValue);
}
@@ -66,7 +66,6 @@ public DataTypeDefinitionImpl(final Class> componentClass) {
this.properties.put(f.getName(), propDef);
}
}
-
}
@Override
@@ -115,5 +114,4 @@ public String getSimpleName() {
public String toString() {
return this.simpleName + " " + properties;
}
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ParameterDefinitionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ParameterDefinitionImpl.java
index a99765cab..7fa8f6e6a 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ParameterDefinitionImpl.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/ParameterDefinitionImpl.java
@@ -7,7 +7,6 @@
package org.hyperledger.fabric.contract.routing.impl;
import java.lang.reflect.Parameter;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
import org.hyperledger.fabric.contract.routing.ParameterDefinition;
@@ -19,13 +18,13 @@ public final class ParameterDefinitionImpl implements ParameterDefinition {
private final String name;
/**
- *
* @param name
* @param typeClass
* @param schema
* @param p
*/
- public ParameterDefinitionImpl(final String name, final Class> typeClass, final TypeSchema schema, final Parameter p) {
+ public ParameterDefinitionImpl(
+ final String name, final Class> typeClass, final TypeSchema schema, final Parameter p) {
this.typeClass = typeClass;
this.schema = schema;
this.parameter = p;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/PropertyDefinitionImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/PropertyDefinitionImpl.java
index 5ea837054..f7772d046 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/PropertyDefinitionImpl.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/PropertyDefinitionImpl.java
@@ -7,7 +7,6 @@
package org.hyperledger.fabric.contract.routing.impl;
import java.lang.reflect.Field;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
import org.hyperledger.fabric.contract.routing.PropertyDefinition;
@@ -19,7 +18,6 @@ public final class PropertyDefinitionImpl implements PropertyDefinition {
private final String name;
/**
- *
* @param name
* @param typeClass
* @param schema
@@ -51,5 +49,4 @@ public Field getField() {
public String getName() {
return this.name;
}
-
}
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 084b32802..49180d385 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
@@ -5,6 +5,9 @@
*/
package org.hyperledger.fabric.contract.routing.impl;
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ScanResult;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
@@ -13,7 +16,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-
import org.hyperledger.fabric.Logger;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.ContractRuntimeException;
@@ -26,18 +28,12 @@
import org.hyperledger.fabric.contract.routing.TxFunction;
import org.hyperledger.fabric.contract.routing.TypeRegistry;
-import io.github.classgraph.ClassGraph;
-import io.github.classgraph.ClassInfo;
-import io.github.classgraph.ScanResult;
-
/**
- * Registry to hold permit access to the routing definitions. This is the
- * primary internal data structure to permit access to information about the
- * contracts, and their transaction functions.
- *
- * Contracts are added, and processed. At runtime, this can then be accessed to
- * locate a specific 'Route' that can be handed off to the ExecutionService
+ * Registry to hold permit access to the routing definitions. This is the primary internal data structure to permit
+ * access to information about the contracts, and their transaction functions.
*
+ * Contracts are added, and processed. At runtime, this can then be accessed to locate a specific 'Route' that can be
+ * handed off to the ExecutionService
*/
public final class RoutingRegistryImpl implements RoutingRegistry {
private static Logger logger = Logger.getLogger(RoutingRegistryImpl.class);
@@ -100,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());
}
/*
@@ -131,7 +126,6 @@ public ContractDefinition getContract(final String namespace) {
@Override
public Collection getAllDefinitions() {
return contracts.values();
-
}
/*
@@ -145,14 +139,12 @@ public Collection getAllDefinitions() {
public void findAndSetContracts(final TypeRegistry typeRegistry) {
// Find all classes that are valid contract or data type instances.
- final ClassGraph classGraph = new ClassGraph()
- .enableClassInfo()
- .enableAnnotationInfo();
+ final ClassGraph classGraph = new ClassGraph().enableClassInfo().enableAnnotationInfo();
final List> contractClasses = new ArrayList<>();
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");
@@ -162,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");
@@ -188,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);
}
}
}
@@ -198,7 +190,6 @@ public void findAndSetContracts(final TypeRegistry typeRegistry) {
// now need to look for the data types have been set with the
dataTypeClasses.forEach(typeRegistry::addDataType);
-
}
private void addContracts(final List> contractClasses) {
@@ -214,10 +205,9 @@ 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);
-
}
}
@@ -225,5 +215,4 @@ private void addContracts(final List> contractClasses)
}
}
}
-
}
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 74b9a0b84..ecd406e88 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
@@ -5,35 +5,27 @@
*/
package org.hyperledger.fabric.contract.routing.impl;
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ScanResult;
+import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-
import org.hyperledger.fabric.Logger;
import org.hyperledger.fabric.contract.annotation.Serializer;
import org.hyperledger.fabric.contract.execution.SerializerInterface;
-import io.github.classgraph.ClassGraph;
-import io.github.classgraph.ClassInfo;
-import io.github.classgraph.ScanResult;
-
/**
* Registry to hold permit access to the serializer implementations.
*
- * It holds the serializers that have been defined. JSONTransactionSerializer
- * is the default.
+ * It holds the serializers that have been defined. JSONTransactionSerializer is the default.
*/
public class SerializerRegistryImpl {
- private static Logger logger = Logger.getLogger(SerializerRegistryImpl.class);
-
- private final Class annotationClass = Serializer.class;
+ private static final Logger LOGGER = Logger.getLogger(SerializerRegistryImpl.class);
- /**
- *
- */
- public SerializerRegistryImpl() {
- }
+ private static final Class ANNOTATION_CLASS = Serializer.class;
// Could index these by name and or type.
private final Map contents = new HashMap<>();
@@ -41,7 +33,7 @@ public SerializerRegistryImpl() {
/**
* Get a Serializer for the matching fully qualified classname, and the Target.
*
- * @param name fully qualified classname
+ * @param name fully qualified classname
* @param target the intended target of the serializer
* @return Serializer instance
*/
@@ -50,16 +42,19 @@ public SerializerInterface getSerializer(final String name, final Serializer.TAR
return contents.get(key);
}
- private SerializerInterface add(final String name, final Serializer.TARGET target, final Class clazz) {
- logger.debug(() -> "Adding new Class " + clazz.getCanonicalName() + " for " + target);
+ private void add(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;
try {
- final String key = name + ":" + target;
- final SerializerInterface newObj = clazz.newInstance();
+ final SerializerInterface newObj =
+ (SerializerInterface) clazz.getDeclaredConstructor().newInstance();
this.contents.put(key, newObj);
-
- return newObj;
- } catch (InstantiationException | IllegalAccessException e) {
- throw new RuntimeException(e);
+ } catch (InvocationTargetException | NoSuchMethodException e) {
+ InstantiationException wrapper = new InstantiationException(
+ "Exception constructing " + clazz.getCanonicalName() + ": " + e.getMessage());
+ wrapper.addSuppressed(e);
+ throw wrapper;
}
}
@@ -78,25 +73,18 @@ public void findAndSetContents() throws InstantiationException, IllegalAccessExc
final Set seenClass = new HashSet<>();
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");
+ for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(ANNOTATION_CLASS.getCanonicalName())) {
+ LOGGER.debug(() -> "Found class with contract annotation: " + classInfo.getName());
- final String className = cls.getCanonicalName();
- if (!seenClass.contains(className)) {
- seenClass.add(className);
- this.add(className, Serializer.TARGET.TRANSACTION, cls);
- }
+ final Class> cls = 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 b12726d23..26f336f53 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,10 +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;
@@ -24,25 +24,23 @@
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 extends ContractInterface> clazz;
private final String serializerName;
/**
- *
* @param method
* @param contract
*/
@@ -63,7 +61,9 @@ public Class extends ContractInterface> getContractClass() {
}
@Override
- public ContractInterface getContractInstance() throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
+ public ContractInterface getContractInstance()
+ throws IllegalAccessException, InstantiationException, InvocationTargetException,
+ NoSuchMethodException {
return clazz.getDeclaredConstructor().newInstance();
}
@@ -76,20 +76,19 @@ public String toString() {
public String getSerializerName() {
return serializerName;
}
-
}
/**
* New TxFunction Definition Impl.
*
- * @param m Reflect method object
+ * @param m Reflect method object
* @param contract ContractDefinition this is part of
*/
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 {
@@ -114,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())) {
+ }
+ if (!Context.class.isAssignableFrom(params[0].getType())) {
throw new ContractRuntimeException(
- "First argument should be of type Context " + method.getName() + " " + params.get(0).getType());
- } else {
-
- params.remove(0);
+ "First argument should be of type Context " + m.getName() + " " + params[0].getType());
}
// FUTURE: if ever the method of creating the instance where to change,
@@ -133,24 +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());
+ return Arrays.stream(params)
+ .skip(1)
+ .map(TxFunctionImpl::newParameterDefinition)
+ .collect(Collectors.toList());
+ }
- 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]);
- }
- }
+ 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();
}
@@ -193,11 +195,8 @@ public List getParamsList() {
return paramsList;
}
- /**
- *
- * @param paramsList
- */
- public void setParamsList(final ArrayList paramsList) {
+ /** @param paramsList */
+ public void setParamsList(final List paramsList) {
this.paramsList = paramsList;
}
@@ -209,7 +208,6 @@ public TypeSchema getReturnSchema() {
@Override
public void setParameterDefinitions(final List list) {
this.paramsList = list;
-
}
@Override
@@ -221,5 +219,4 @@ public boolean isUnknownTx() {
public void setUnknownTx(final boolean unknown) {
this.isUnknownTx = unknown;
}
-
}
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 dc50d3dc9..54d2e9958 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
@@ -8,18 +8,15 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
-
import org.hyperledger.fabric.contract.metadata.TypeSchema;
import org.hyperledger.fabric.contract.routing.DataTypeDefinition;
import org.hyperledger.fabric.contract.routing.TypeRegistry;
-/**
- * Registry to hold the complex data types as defined in the contract.
- *
- */
+/** 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.
@@ -27,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)
*
@@ -72,8 +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/routing/impl/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/package-info.java
index 108f8132d..e3d4b1ea8 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/package-info.java
@@ -4,7 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- *
- */
+/** */
package org.hyperledger.fabric.contract.routing.impl;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/package-info.java
index 32533b45b..4ab5847bb 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/package-info.java
@@ -4,7 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- *
- */
+/** */
package org.hyperledger.fabric.contract.routing;
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 f2427e226..762efe664 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
@@ -12,29 +12,21 @@
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.contract.metadata.MetadataBuilder;
-/**
- *
- */
-@Contract(name = "org.hyperledger.fabric",
- info = @Info(title = "Fabric System Contract", description = "Provides information about the contracts within this container"))
+/** */
+@Contract(
+ name = "org.hyperledger.fabric",
+ info =
+ @Info(
+ title = "Fabric System Contract",
+ 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/contract/systemcontract/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/package-info.java
index 5dcfe058a..cde12bb03 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/systemcontract/package-info.java
@@ -4,7 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- *
- */
+/** */
package org.hyperledger.fabric.contract.systemcontract;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java
index 195eb5f80..42a261074 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java
@@ -6,16 +6,15 @@
package org.hyperledger.fabric.ledger;
/** Place holder. */
+@SuppressWarnings("PMD.ImplicitFunctionalInterface")
public interface Collection {
- /**
- * Constant that can be used to refer to the 'Worldstate' collection explicitly.
- */
+ /** Constant that can be used to refer to the 'Worldstate' collection explicitly. */
String WORLD = "worldstate";
/**
- * Placeholder. Purely in place to prevent Checkstyle inferring this class is pointless.
- * will be removed in the next story
+ * Placeholder. Purely in place to prevent Checkstyle inferring this class is pointless. will be removed in the next
+ * story
*/
void placeholder();
}
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 ce3479711..1d97ec717 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
@@ -11,40 +11,35 @@
/**
* Ledger representing the overall shared Transaction Data of the Network.
*
- * It is composed of a number of collections, one being the public or world
- * state, and other private data collections, including the implicit
- * organizational collections.
- *
- * Ledger objects can be passed between methods if required. All operations on
- * the Ledger directly or via any child object such as a Collection will be
- * controlled by the supplied transactional context.
+ * It is composed of a number of collections, one being the public or world state, and other private data
+ * collections, including the implicit organizational collections.
*
+ *
Ledger objects can be passed between methods if required. All operations on the Ledger directly or via any child
+ * object such as a Collection will be controlled by the supplied transactional context.
*/
public interface Ledger {
/**
* Get the Ledger instance that represents the current ledger state.
*
- * Any interactions with the ledger will be done under the control of the
- * transactional context supplied. The ledger object may be passed to other
- * methods if required.
+ *
Any interactions with the ledger will be done under the control of the transactional context supplied. The
+ * ledger object may be passed to other methods if required.
*
- * A new instance is returned on each call.
+ *
A new instance is returned on each call.
*
- * @param ctx Context The Transactional context to use for interactions with
- * this ledger
+ * @param ctx Context The Transactional context to use for interactions with this ledger
* @return Ledger instance
*/
static Ledger getLedger(final Context ctx) {
return new LedgerImpl(ctx);
- };
+ }
/**
* Return the a collection based on the supplied name.
*
- * Private Data collections can be accessed by name.
+ *
Private Data collections can be accessed by name.
*
- * A new instance of a Collection object is returned on each call.
+ *
A new instance of a Collection object is returned on each call.
*
* @param name
* @return Collection instance
@@ -54,7 +49,7 @@ static Ledger getLedger(final Context ctx) {
/**
* Return the World State collection.
*
- * A new instance of a Collection object is returned on each call.
+ *
A new instance of a Collection object is returned on each call.
*
* @return Collection instance
*/
@@ -63,14 +58,12 @@ static Ledger getLedger(final Context ctx) {
/**
* Return a implicit organization collection.
*
- * Given the mspid of the ogranization return the private data collection that
- * is implicitly created
+ *
Given the mspid of the ogranization return the private data collection that is implicitly created
*
- * A new instance of a Collection object is returned on each call.
+ *
A new instance of a Collection object is returned on each call.
*
* @param mspid String Organization's mspid
* @return Collection instance
*/
Collection getOrganizationCollection(String mspid);
-
}
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 faea7f491..000000000
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/CollectionImpl.java
+++ /dev/null
@@ -1,33 +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 1087cd24f..347c516e3 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,26 @@
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
*/
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
@@ -39,5 +39,4 @@ public Collection getDefaultCollection() {
public Collection getOrganizationCollection(final String mspid) {
return this.getCollection("_implicit_org_" + mspid);
}
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/package-info.java
index 96b288ea9..025bb854b 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/impl/package-info.java
@@ -1,6 +1,6 @@
-/*
- * Copyright 2023 IBM All Rights Reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.hyperledger.fabric.ledger.impl;
+/*
+ * Copyright 2023 IBM All Rights Reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package org.hyperledger.fabric.ledger.impl;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/package-info.java
index ca6cfec78..129a4271c 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/package-info.java
@@ -4,9 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- *
- * Provides the API for contracts to access the shared ledger.
- *
- */
+/** Provides the API for contracts to access the shared ledger. */
package org.hyperledger.fabric.ledger;
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 56bcdab67..b13e3708b 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,19 +5,16 @@
*/
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;
import org.hyperledger.fabric.metrics.impl.NullProvider;
/**
* Metrics Interface.
*
- * Metrics setups up the provider in use from the configuration supplied If not
- * enabled, nothing happens, but if enabled but no specific logger default is
- * used that uses the org.hyperledger.Performance logger
+ *
Metrics setups up the provider in use from the configuration supplied If not enabled, nothing happens, but if
+ * enabled but no specific logger default is used that uses the org.hyperledger.Performance logger
*/
public final class Metrics {
@@ -28,16 +25,13 @@ public final class Metrics {
private static MetricsProvider provider;
-
- private Metrics() {
-
- }
+ 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,37 +40,30 @@ public static MetricsProvider initialize(final Properties props) {
final String providerClass = (String) props.get(CHAINCODE_METRICS_PROVIDER);
@SuppressWarnings("unchecked") // it must be this type otherwise an error
- final
- Class clazz = (Class) Class.forName(providerClass);
+ final Class clazz = (Class) Class.forName(providerClass);
provider = clazz.getConstructor().newInstance();
} else {
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
logger.info("Metrics disabled");
provider = new NullProvider();
-
}
provider.initialize(props);
return provider;
}
- /**
- *
- * @return MetricsProvider
- */
+ /** @return MetricsProvider */
public static MetricsProvider getProvider() {
if (provider == null) {
throw new IllegalStateException("No provider set, this should have been set");
}
return 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 482fbbdf4..aa726b964 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
@@ -9,20 +9,16 @@
import java.util.Properties;
/**
- * Interface to be implemented to send metrics on the chaincode to the
- * 'backend-of-choice'.
+ * Interface to be implemented to send metrics on the chaincode to the 'backend-of-choice'.
*
- * An instance of this will be created, and provided with the resources from
- * which chaincode specific metrics can be collected. (via the no-argument
- * constructor).
+ * An instance of this will be created, and provided with the resources from which chaincode specific metrics can be
+ * collected. (via the no-argument constructor).
*
- * The choice of when, where and what to collect etc are within the remit of the
- * provider.
+ *
The choice of when, where and what to collect etc are within the remit of the provider.
*
- * This is the effective call sequence.
+ *
This is the effective call sequence.
*
- * MyMetricsProvider mmp = new MyMetricsProvider()
- * mmp.initialize(props_from_environment); // short while later....
+ *
MyMetricsProvider mmp = new MyMetricsProvider() mmp.initialize(props_from_environment); // short while later....
* mmp.setTaskMetricsCollector(taskService);
*/
public interface MetricsProvider {
@@ -33,16 +29,16 @@ public interface MetricsProvider {
* @param 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 tasks within the chaincode. i.e. how
- * individual transactions are dispatched for execution.
+ * Pass a reference to this task service for information gathering. This is related specifically to the handling of
+ * tasks within the chaincode. i.e. how individual transactions are dispatched for execution.
*
* @param taskService
*/
default void setTaskMetricsCollector(final TaskMetricsCollector taskService) {
- };
-
+ // Do nothing by default
+ }
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/TaskMetricsCollector.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/TaskMetricsCollector.java
index bb2c6065b..ef59d6a44 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/TaskMetricsCollector.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/TaskMetricsCollector.java
@@ -8,11 +8,9 @@
/**
* Collect metrics relating to the task execution.
*
- * The task execution (of which each fabric transaction is one) is backed by a
- * thread pool that implements this interface. As that is an implementation
- * class this interface abstracts the information available from it (as far as
+ *
The task execution (of which each fabric transaction is one) is backed by a thread pool that implements this
+ * interface. As that is an implementation class this interface abstracts the information available from it (as far as
* metrics go).
- *
*/
public interface TaskMetricsCollector {
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 a2dc8a785..3f34028d3 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
@@ -9,26 +9,20 @@
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
-
import org.hyperledger.fabric.Logging;
import org.hyperledger.fabric.metrics.MetricsProvider;
import org.hyperledger.fabric.metrics.TaskMetricsCollector;
-/**
- * Simple default provider that logs to the org.hyperledger.Performance logger
- * the basic metrics.
- *
- */
+/** 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
@@ -36,36 +30,36 @@ 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);
- metricTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- DefaultProvider.this.logMetrics();
- }
- }, 0, TIME_INTERVAL);
-
+ metricTimer.scheduleAtFixedRate(
+ new TimerTask() {
+ @Override
+ public void run() {
+ DefaultProvider.this.logMetrics();
+ }
+ },
+ 0,
+ 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 f977ac67f..35be1fa61 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
@@ -7,17 +7,5 @@
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() {
- }
-
-}
+/** Very simple provider that does absolutely nothing. Used when metrics are disabled. */
+public class NullProvider implements MetricsProvider {}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/package-info.java
index 301529657..59afe468e 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/impl/package-info.java
@@ -4,7 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- *
- */
+/** */
package org.hyperledger.fabric.metrics.impl;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/package-info.java
index ec9d196aa..f9cf1f7b3 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/metrics/package-info.java
@@ -7,24 +7,17 @@
/**
* Provides interfaces and classes to support collection of metrics.
*
- *
- * The main metrics that are available are the statistics around the number of
- * tasks that are running, and how the thread pool is handling these.
+ *
The main metrics that are available are the statistics around the number of tasks that are running, and how the
+ * thread pool is handling these.
*
- *
- * Note a 'task' is a message from the Peer to the Chaincode - this message is
- * either a new transaction, or a response from a stub API, eg getState(). Query
- * apis may return more than one response.
+ *
Note a 'task' is a message from the Peer to the Chaincode - this message is either a new transaction, or a
+ * response from a stub API, eg getState(). Query apis may return more than one response.
*
- *
- * To enable metrics, add a CHAINCODE_METRICS_ENABLED=true setting
- * to the config.props chaincode configuration file.
- * See the Overview for details of how to
- * configure chaincode.
+ *
To enable metrics, add a CHAINCODE_METRICS_ENABLED=true setting to the config.props
+ * chaincode configuration file. See the Overview for details of how to configure
+ * chaincode.
*
- *
Open Telemetry
- *
- * To use Open Telemetry, set the following properties:
+ * Open Telemetry To use Open Telemetry, set the following properties:
*
*
* CHAINCODE_METRICS_ENABLED=true
@@ -34,7 +27,8 @@
* Additionally, you can set properties after the specification:
* https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sdk-environment-variables.md
*
- * Example:
+ * Example:
+ *
*
* OTEL_EXPORTER_OTLP_ENDPOINT=otelcollector:4317
* OTEL_EXPORTER_OTLP_INSECURE=true
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/package-info.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/package-info.java
index cb5d58f60..dfeb5e026 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/package-info.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/package-info.java
@@ -4,7 +4,5 @@
* SPDX-License-Identifier: Apache-2.0
*/
-/**
- * Provides logging classes.
- */
+/** Provides logging classes. */
package org.hyperledger.fabric;
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 046595df3..ca576534d 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
@@ -11,13 +11,11 @@
import java.util.HashMap;
import java.util.Map;
-/**
- * Defines methods that all chaincodes must implement.
- */
+/** Defines methods that all chaincodes must implement. */
public interface Chaincode {
/**
- * Called during an instantiate transaction after the container has been
- * established, allowing the chaincode to initialize its internal data.
+ * Called during an instantiate transaction after the container has been established, allowing the chaincode to
+ * initialize its internal data.
*
* @param stub the chaincode stub
* @return the chaincode response
@@ -25,8 +23,7 @@ public interface Chaincode {
Response init(ChaincodeStub stub);
/**
- * Called for every Invoke transaction. The chaincode may change its state
- * variables.
+ * Called for every Invoke transaction. The chaincode may change its state variables.
*
* @param stub the chaincode stub
* @return the chaincode response
@@ -34,9 +31,8 @@ public interface Chaincode {
Response invoke(ChaincodeStub stub);
/**
- * Wrapper around protobuf Response, contains status, message and payload.
- * Object returned by call to {@link #init(ChaincodeStub)}
- * and{@link #invoke(ChaincodeStub)}
+ * Wrapper around protobuf Response, contains status, message and payload. Object returned by call to
+ * {@link #init(ChaincodeStub)} and{@link #invoke(ChaincodeStub)}
*/
class Response {
private final int statusCode;
@@ -45,10 +41,12 @@ class Response {
/**
* Constructor.
+ *
* @param status a status object.
* @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;
@@ -57,10 +55,12 @@ public Response(final Status status, final String message, final byte[] payload)
/**
* Constructor.
+ *
* @param statusCode a status code.
* @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;
@@ -69,6 +69,7 @@ public Response(final int statusCode, final String message, final byte[] payload
/**
* Get the response status.
+ *
* @return status.
*/
public Status getStatus() {
@@ -81,6 +82,7 @@ public Status getStatus() {
/**
* Get the response status code.
+ *
* @return status code.
*/
public int getStatusCode() {
@@ -89,6 +91,7 @@ public int getStatusCode() {
/**
* Get the response message.
+ *
* @return a message.
*/
public String getMessage() {
@@ -97,35 +100,30 @@ public String getMessage() {
/**
* Get the response payload.
+ *
* @return payload bytes.
*/
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] getPayload() {
return payload;
}
/**
* Get the response payload as a UTF-8 string.
+ *
* @return a string.
*/
public String getStringPayload() {
return (payload == null) ? null : new String(payload, UTF_8);
}
- /**
- * {@link Response} status enum.
- */
+ /** {@link Response} status enum. */
public enum Status {
- /**
- * Successful response status.
- */
+ /** Successful response status. */
SUCCESS(200),
- /**
- * Minimum threshold for as error status code.
- */
+ /** Minimum threshold for as error status code. */
ERROR_THRESHOLD(400),
- /**
- * Server-side error status.
- */
+ /** Server-side error status. */
INTERNAL_SERVER_ERROR(500);
private static final Map CODETOSTATUS = new HashMap<>();
@@ -137,6 +135,7 @@ public enum Status {
/**
* Get the status code associated with this status object.
+ *
* @return a status code.
*/
public int getCode() {
@@ -145,6 +144,7 @@ public int getCode() {
/**
* Get a status object for a given status code.
+ *
* @param code a status code.
* @return a status object.
*/
@@ -158,6 +158,7 @@ public static Status forCode(final int code) {
/**
* Whether a status exists for a given status code.
+ *
* @param code a status code.
* @return True if a status for the code exists; otherwise false.
*/
@@ -166,12 +167,10 @@ 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 da8da55e6..b0831498a 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,9 +6,16 @@
package org.hyperledger.fabric.shim;
-import static java.lang.String.format;
import static java.util.logging.Level.ALL;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.shaded.io.grpc.netty.NegotiationType;
+import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
+import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
+import io.grpc.stub.StreamObserver;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
@@ -21,15 +28,12 @@
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;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.util.JsonFormat;
-
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
@@ -43,63 +47,39 @@
import org.hyperledger.fabric.shim.impl.InvocationTaskManager;
import org.hyperledger.fabric.traces.Traces;
-import io.grpc.ManagedChannelBuilder;
-import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
-import io.grpc.netty.shaded.io.grpc.netty.NegotiationType;
-import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
-import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
-import io.grpc.stub.StreamObserver;
-
/**
* Abstract implementation of {@link Chaincode}.
*
- *
- * All chaincode implementations must extend the abstract class
- * ChaincodeBase. It is possible to implement chaincode by
- * extending ChaincodeBase directly however new projects should
- * implement {@link org.hyperledger.fabric.contract.ContractInterface} and use
- * the contract programming model instead.
+ *
All chaincode implementations must extend the abstract class ChaincodeBase. It is possible to
+ * implement chaincode by extending ChaincodeBase directly however new projects should implement
+ * {@link org.hyperledger.fabric.contract.ContractInterface} and use the contract programming model instead.
*
* @see org.hyperledger.fabric.contract
*/
+@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.GodClass"})
public abstract class ChaincodeBase implements Chaincode {
- /**
- *
- */
+ /** */
public static final String CORE_CHAINCODE_LOGGING_SHIM = "CORE_CHAINCODE_LOGGING_SHIM";
- /**
- *
- */
+ /** */
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());
- /**
- *
- */
+ /** */
+ @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
public static final String DEFAULT_HOST = "127.0.0.1";
- /**
- *
- */
+ /** */
public static final int DEFAULT_PORT = 7051;
- /**
- * Default to 100MB for maximum inbound grpc message size.
- */
+ /** Default to 100MB for maximum inbound grpc message size. */
public static final String DEFAULT_MAX_INBOUND_MESSAGE_SIZE = "104857600";
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;
@@ -123,19 +103,26 @@ 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");
}
- final int maxMsgSize = Integer
- .parseInt(this.props.getProperty(MAX_INBOUND_MESSAGE_SIZE, DEFAULT_MAX_INBOUND_MESSAGE_SIZE));
- final String msgSizeInfo = String.format("Maximum Inbound Message Size [%s] = %d", MAX_INBOUND_MESSAGE_SIZE,
- maxMsgSize);
+ final int maxMsgSize =
+ Integer.parseInt(this.props.getProperty(MAX_INBOUND_MESSAGE_SIZE, DEFAULT_MAX_INBOUND_MESSAGE_SIZE));
+ final String msgSizeInfo =
+ String.format("Maximum Inbound Message Size [%s] = %d", MAX_INBOUND_MESSAGE_SIZE, maxMsgSize);
LOGGER.info(msgSizeInfo);
return maxMsgSize;
}
@@ -145,7 +132,7 @@ private int getMaxInboundMessageSize() {
*
* @param args command line arguments
*/
-
+ @SuppressWarnings("PMD.AvoidCatchingGenericException")
public void start(final String[] args) {
try {
initializeLogging();
@@ -173,7 +160,8 @@ protected final void connectToPeer() throws IOException {
// This is then passed to the ChaincodeSupportClient to be connected to the
// gRPC streams
- final ChaincodeID chaincodeId = ChaincodeID.newBuilder().setName(this.id).build();
+ final ChaincodeID chaincodeId =
+ ChaincodeID.newBuilder().setName(this.id).build();
final ManagedChannelBuilder> channelBuilder = newChannelBuilder();
final ChaincodeSupportClient chaincodeSupportClient = new ChaincodeSupportClient(channelBuilder);
@@ -202,9 +190,9 @@ protected final void connectToPeer() throws IOException {
// for any error - shut everything down
// as this is long lived (well forever) then any completion means something
// has stopped in the peer or the network comms, so also shutdown
- final StreamObserver requestObserver = chaincodeSupportClient.getStub().register(
-
- new StreamObserver() {
+ final StreamObserver requestObserver = chaincodeSupportClient
+ .getStub()
+ .register(new StreamObserver<>() {
@Override
public void onNext(final ChaincodeMessage chaincodeMessage) {
// message off to the ITM...
@@ -214,7 +202,7 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
@Override
public void onError(final Throwable t) {
LOGGER.severe(
- () -> "An error occured on the chaincode stream. Shutting down the chaincode stream."
+ () -> "An error occurred on the chaincode stream. Shutting down the chaincode stream."
+ Logging.formatError(t));
chaincodeSupportClient.shutdown(itm);
@@ -225,24 +213,20 @@ public void onCompleted() {
LOGGER.severe("Chaincode stream is complete. Shutting down the chaincode stream.");
chaincodeSupportClient.shutdown(itm);
}
- }
-
- );
+ });
chaincodeSupportClient.start(itm, requestObserver);
-
}
/**
* connect external chaincode to peer for chat.
*
* @param requestObserver reqeust from peer
- * @return itm - The InnvocationTask Manager handles the message level
- * communication with the peer.
+ * @return itm - The InnvocationTask Manager handles the message level communication with the peer.
* @throws IOException validation fields exception
*/
- protected StreamObserver connectToPeer(
- final StreamObserver requestObserver) throws IOException {
+ protected StreamObserver connectToPeer(final StreamObserver requestObserver)
+ throws IOException {
validateOptions();
if (requestObserver == null) {
throw new IOException("StreamObserver 'requestObserver' for chat with peer can't be null");
@@ -256,7 +240,8 @@ protected StreamObserver connectToPeer(
// This is then passed to the ChaincodeSupportClient to be connected to the
// gRPC streams
- final ChaincodeID chaincodeId = ChaincodeID.newBuilder().setName(this.id).build();
+ final ChaincodeID chaincodeId =
+ ChaincodeID.newBuilder().setName(this.id).build();
final ManagedChannelBuilder> channelBuilder = newChannelBuilder();
final ChaincodeSupportClient chaincodeSupportClient = new ChaincodeSupportClient(channelBuilder);
@@ -264,7 +249,7 @@ protected StreamObserver connectToPeer(
chaincodeSupportClient.start(itm, requestObserver);
- return new StreamObserver() {
+ return new StreamObserver<>() {
@Override
public void onNext(final ChaincodeMessage chaincodeMessage) {
itm.onChaincodeMessage(chaincodeMessage);
@@ -272,7 +257,7 @@ public void onNext(final ChaincodeMessage chaincodeMessage) {
@Override
public void onError(final Throwable t) {
- LOGGER.severe(() -> "An error occured on the chaincode stream. Shutting down the chaincode stream."
+ LOGGER.severe(() -> "An error occurred on the chaincode stream. Shutting down the chaincode stream."
+ Logging.formatError(t));
chaincodeSupportClient.shutdown(itm);
@@ -288,20 +273,20 @@ public void onCompleted() {
protected final void initializeLogging() {
// the VM wide formatting string.
- System.setProperty("java.util.logging.SimpleFormatter.format",
- "%1$tH:%1$tM:%1$tS:%1$tL %4$-7.7s %2$-80.80s %5$s%6$s%n");
+ System.setProperty(
+ "java.util.logging.SimpleFormatter.format", "%1$tH:%1$tM:%1$tS:%1$tL %4$-7.7s %2$-80.80s %5$s%6$s%n");
final Logger rootLogger = Logger.getLogger("");
+ var formatter = new SimpleFormatter() {
+ @Override
+ public String format(final LogRecord record) {
+ return Thread.currentThread() + " " + super.format(record);
+ }
+ };
+
for (final java.util.logging.Handler handler : rootLogger.getHandlers()) {
handler.setLevel(ALL);
- handler.setFormatter(new SimpleFormatter() {
-
- @Override
- public synchronized String format(final LogRecord record) {
- return Thread.currentThread() + " " + super.format(record);
- }
-
- });
+ handler.setFormatter(formatter);
}
rootLogger.info("Updated all handlers the format");
@@ -322,33 +307,31 @@ public synchronized String format(final LogRecord record) {
final Level shimLogLevel = mapLevel(System.getenv(CORE_CHAINCODE_LOGGING_SHIM));
Logger.getLogger(ChaincodeBase.class.getPackage().getName()).setLevel(shimLogLevel);
Logger.getLogger(ContractRouter.class.getPackage().getName()).setLevel(chaincodeLogLevel);
-
}
private Level mapLevel(final String level) {
if (level != null) {
- switch (level.toUpperCase().trim()) {
- case "CRITICAL":
- case "ERROR":
- return Level.SEVERE;
- case "WARNING":
- case "WARN":
- return Level.WARNING;
- case "INFO":
- return Level.INFO;
- case "NOTICE":
- return Level.CONFIG;
- case "DEBUG":
- return Level.FINEST;
- default:
- break;
+ switch (level.toUpperCase(Locale.getDefault()).trim()) {
+ case "CRITICAL":
+ case "ERROR":
+ return Level.SEVERE;
+ case "WARNING":
+ case "WARN":
+ return Level.WARNING;
+ case "INFO":
+ return Level.INFO;
+ case "NOTICE":
+ return Level.CONFIG;
+ case "DEBUG":
+ return Level.FINEST;
+ default:
+ break;
}
}
return Level.INFO;
}
-
private SocketAddress parseHostPort(final String hostAddrStr) throws URISyntaxException {
// WORKAROUND: add any scheme to make the resulting URI valid.
@@ -356,9 +339,8 @@ private SocketAddress parseHostPort(final String hostAddrStr) throws URISyntaxEx
String host = uri.getHost();
int port = uri.getPort();
- if (uri.getHost() == null || uri.getPort() == -1) {
- throw new URISyntaxException(uri.toString(),
- "URI must have host and port parts");
+ if (host == null || port == -1) {
+ throw new URISyntaxException(uri.toString(), "URI must have host and port parts");
}
// validation succeeded
@@ -374,31 +356,35 @@ public boolean isServer() {
return !chaincodeServerAddress.isEmpty();
}
- /**
- * Validate init parameters from env chaincode base.
- */
+ /** 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));
}
}
}
+ @SuppressWarnings({
+ "PMD.AvoidLiteralsInIfCondition",
+ "PMD.AvoidCatchingGenericException",
+ "PMD.ExceptionAsFlowControl"
+ })
protected final void processCommandLineOptions(final String[] args) {
final Options options = new Options();
options.addOption("a", "peer.address", true, "Address of peer to connect to");
@@ -416,7 +402,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(
@@ -432,15 +418,13 @@ 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.
- */
+ /** set fields from env. */
+ @SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
public final void processEnvironmentOptions() {
if (System.getenv().containsKey(CORE_CHAINCODE_ID_NAME)) {
@@ -449,7 +433,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(
@@ -477,24 +461,25 @@ 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);
+ }
}
/**
- * Obtains configuration specifically for running the chaincode and settable on
- * a per chaincode basis rather than taking properties from the Peers'
- * configuration.
+ * Obtains configuration specifically for running the chaincode and settable on a per chaincode basis rather than
+ * taking properties from the Peers' configuration.
*
* @return Configuration
*/
@@ -519,7 +504,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;
@@ -579,8 +564,10 @@ final SslContext createSSLContext() throws IOException {
final byte[] ckb = Files.readAllBytes(Paths.get(this.tlsClientKeyPath));
final byte[] ccb = Files.readAllBytes(Paths.get(this.tlsClientCertPath));
- return GrpcSslContexts.forClient().trustManager(new File(this.tlsClientRootCertPath))
- .keyManager(new ByteArrayInputStream(Base64.getDecoder().decode(ccb)),
+ return GrpcSslContexts.forClient()
+ .trustManager(new File(this.tlsClientRootCertPath))
+ .keyManager(
+ new ByteArrayInputStream(Base64.getDecoder().decode(ccb)),
new ByteArrayInputStream(Base64.getDecoder().decode(ckb)))
.build();
}
@@ -663,12 +650,9 @@ String getId() {
return id;
}
- /**
- * Chaincode State.
- */
+ /** Chaincode State. */
public enum CCState {
- /**
- * */
+ /** */
CREATED,
/** */
ESTABLISHED,
@@ -676,20 +660,12 @@ public enum CCState {
READY
}
- private CCState state = CCState.CREATED;
-
- /**
- *
- * @return State
- */
+ /** @return State */
public final CCState getState() {
return this.state;
}
- /**
- *
- * @param newState
- */
+ /** @param newState */
public final void setState(final CCState newState) {
this.state = newState;
}
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 fe73b5703..36ec21cf2 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
@@ -8,18 +8,13 @@
import static java.nio.charset.StandardCharsets.UTF_8;
/**
- * Contracts should use {@code ChaincodeException} to indicate when an error
- * occurs in Smart Contract logic.
+ * Contracts should use {@code ChaincodeException} to indicate when an error occurs in Smart Contract logic.
*
- *
- * When a {@code ChaincodeException} is thrown an error response will be
- * returned from the chaincode container containing the exception message and
- * payload, if specified.
+ *
When a {@code ChaincodeException} is thrown an error response will be returned from the chaincode container
+ * containing the exception message and payload, if specified.
*
- *
- * {@code ChaincodeException} may be extended to provide application specific
- * error information. Subclasses should ensure that {@link #getPayload} returns
- * a serialized representation of the error in a suitable format for client
+ *
{@code ChaincodeException} may be extended to provide application specific error information. Subclasses should
+ * ensure that {@link #getPayload} returns a serialized representation of the error in a suitable format for client
* applications to process.
*/
public class ChaincodeException extends RuntimeException {
@@ -28,16 +23,13 @@ public class ChaincodeException extends RuntimeException {
private byte[] payload;
- /**
- * Constructs a new {@code ChaincodeException} with no detail message.
- */
+ /** Constructs a new {@code ChaincodeException} with no detail message. */
public ChaincodeException() {
super();
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail
- * message.
+ * Constructs a new {@code ChaincodeException} with the specified detail message.
*
* @param message the detail message.
*/
@@ -55,23 +47,22 @@ public ChaincodeException(final Throwable cause) {
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail message
- * and cause.
+ * Constructs a new {@code ChaincodeException} with the specified detail message and cause.
*
* @param message the detail message.
- * @param cause the cause.
+ * @param cause the cause.
*/
public ChaincodeException(final String message, final Throwable cause) {
super(message, cause);
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail message
- * and response payload.
+ * Constructs a new {@code ChaincodeException} with the specified detail message and response payload.
*
* @param message the detail message.
* @param payload the response payload.
*/
+ @SuppressWarnings("PMD.ArrayIsStoredDirectly")
public ChaincodeException(final String message, final byte[] payload) {
super(message);
@@ -79,13 +70,13 @@ public ChaincodeException(final String message, final byte[] payload) {
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail
- * message, response payload and cause.
+ * Constructs a new {@code ChaincodeException} with the specified detail message, response payload and cause.
*
* @param message the detail message.
* @param payload the response payload.
- * @param cause the cause.
+ * @param cause the cause.
*/
+ @SuppressWarnings("PMD.ArrayIsStoredDirectly")
public ChaincodeException(final String message, final byte[] payload, final Throwable cause) {
super(message, cause);
@@ -93,8 +84,7 @@ public ChaincodeException(final String message, final byte[] payload, final Thro
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail message
- * and response payload.
+ * Constructs a new {@code ChaincodeException} with the specified detail message and response payload.
*
* @param message the detail message.
* @param payload the response payload.
@@ -106,12 +96,11 @@ public ChaincodeException(final String message, final String payload) {
}
/**
- * Constructs a new {@code ChaincodeException} with the specified detail
- * message, response payload and cause.
+ * Constructs a new {@code ChaincodeException} with the specified detail message, response payload and cause.
*
* @param message the detail message.
* @param payload the response payload.
- * @param cause the cause.
+ * @param cause the cause.
*/
public ChaincodeException(final String message, final String payload, final Throwable cause) {
super(message, cause);
@@ -122,15 +111,13 @@ public ChaincodeException(final String message, final String payload, final Thro
/**
* Returns the response payload or {@code null} if there is no response.
*
- *
- * The payload should represent the chaincode error in a way that client
- * applications written in different programming languages can interpret. For
- * example it could include a domain specific error code, in addition to any
- * state information which would allow client applications to respond
- * appropriately.
+ *
The payload should represent the chaincode error in a way that client applications written in different
+ * programming languages can interpret. For example it could include a domain specific error code, in addition to
+ * any state information which would allow client applications to respond appropriately.
*
* @return the response payload or {@code null} if there is no response.
*/
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] getPayload() {
return payload;
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServer.java
index 8c8ff2b35..81c7ce292 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServer.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServer.java
@@ -8,9 +8,7 @@
import java.io.IOException;
-/**
- * External chaincode server.
- */
+/** External chaincode server. */
public interface ChaincodeServer {
/**
@@ -21,9 +19,6 @@ public interface ChaincodeServer {
*/
void start() throws IOException, InterruptedException;
- /**
- * shutdown now grpc server.
- */
+ /** shutdown now grpc server. */
void stop();
-
}
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 27c842572..865c93813 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
@@ -9,41 +9,48 @@
public final class ChaincodeServerProperties {
private SocketAddress serverAddress;
- private int maxInboundMetadataSize = 100 * 1024 * 1024; // checkstyle:ignore-line:MagicNumber
- private int maxInboundMessageSize = 100 * 1024 * 1024; // checkstyle:ignore-line:MagicNumber
- private int maxConnectionAgeSeconds = 5; // checkstyle:ignore-line:MagicNumber
- private int keepAliveTimeoutSeconds = 20; // checkstyle:ignore-line:MagicNumber
- private int permitKeepAliveTimeMinutes = 1; // checkstyle:ignore-line:MagicNumber
- private int keepAliveTimeMinutes = 1; // checkstyle:ignore-line:MagicNumber
+ private int maxInboundMetadataSize = 100 * 1024 * 1024;
+ private int maxInboundMessageSize = 100 * 1024 * 1024;
+ private int maxConnectionAgeSeconds = 5;
+ private int keepAliveTimeoutSeconds = 20;
+ private int permitKeepAliveTimeMinutes = 1;
+ private int keepAliveTimeMinutes = 1;
private boolean permitKeepAliveWithoutCalls = true;
private String keyPassword;
private String keyCertChainFile;
private String keyFile;
private String trustCertCollectionFile;
- private boolean tlsEnabled = false;
+ private boolean tlsEnabled;
- /**
- * Constructor using default configuration.
- */
+ /** Constructor using default configuration. */
public ChaincodeServerProperties() {
+ // Nothing to do
}
/**
* Constructor.
+ *
* @param portChaincodeServer ignored.
* @param maxInboundMetadataSize the maximum metadata size allowed to be received by the server.
* @param maxInboundMessageSize the maximum message size allowed to be received by the server.
* @param maxConnectionAgeSeconds the maximum connection age in seconds.
* @param keepAliveTimeoutSeconds timeout for a keep-alive ping request in seconds.
- * @param permitKeepAliveTimeMinutes the most aggressive keep-alive time clients are permitted to configure in minutes.
+ * @param permitKeepAliveTimeMinutes the most aggressive keep-alive time clients are permitted to configure in
+ * minutes.
* @param keepAliveTimeMinutes delay before server sends a keep-alive in minutes.
- * @param permitKeepAliveWithoutCalls whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection.
+ * @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.NullAssignment"})
public ChaincodeServerProperties(
- final int portChaincodeServer, final int maxInboundMetadataSize, final int maxInboundMessageSize,
- final int maxConnectionAgeSeconds, final int keepAliveTimeoutSeconds, final int permitKeepAliveTimeMinutes,
- final int keepAliveTimeMinutes, final boolean permitKeepAliveWithoutCalls) {
+ final int portChaincodeServer,
+ final int maxInboundMetadataSize,
+ final int maxInboundMessageSize,
+ final int maxConnectionAgeSeconds,
+ final int keepAliveTimeoutSeconds,
+ final int permitKeepAliveTimeMinutes,
+ final int keepAliveTimeMinutes,
+ final boolean permitKeepAliveWithoutCalls) {
this.serverAddress = null;
this.maxInboundMetadataSize = maxInboundMetadataSize;
@@ -57,6 +64,7 @@ public ChaincodeServerProperties(
/**
* The maximum size of metadata allowed to be received.
+ *
* @return The maximum metadata size allowed.
*/
public int getMaxInboundMetadataSize() {
@@ -65,6 +73,7 @@ public int getMaxInboundMetadataSize() {
/**
* Sets the maximum metadata size allowed to be received by the server.
+ *
* @param maxInboundMetadataSize The new maximum size allowed for incoming metadata.
*/
public void setMaxInboundMetadataSize(final int maxInboundMetadataSize) {
@@ -73,6 +82,7 @@ public void setMaxInboundMetadataSize(final int maxInboundMetadataSize) {
/**
* The maximum message size allowed to be received by the server.
+ *
* @return the maximum message size allowed.
*/
public int getMaxInboundMessageSize() {
@@ -81,6 +91,7 @@ public int getMaxInboundMessageSize() {
/**
* Sets the maximum message size allowed to be received by the server.
+ *
* @param maxInboundMessageSize The new maximum size allowed for incoming messages.
*/
public void setMaxInboundMessageSize(final int maxInboundMessageSize) {
@@ -89,6 +100,7 @@ public void setMaxInboundMessageSize(final int maxInboundMessageSize) {
/**
* The maximum connection age.
+ *
* @return The maximum connection age in seconds.
*/
public int getMaxConnectionAgeSeconds() {
@@ -97,6 +109,7 @@ public int getMaxConnectionAgeSeconds() {
/**
* Specify a maximum connection age.
+ *
* @param maxConnectionAgeSeconds The maximum connection age in seconds.
*/
public void setMaxConnectionAgeSeconds(final int maxConnectionAgeSeconds) {
@@ -105,6 +118,7 @@ public void setMaxConnectionAgeSeconds(final int maxConnectionAgeSeconds) {
/**
* The timeout for a keep-alive ping requests.
+ *
* @return timeout in seconds.
*/
public int getKeepAliveTimeoutSeconds() {
@@ -113,6 +127,7 @@ public int getKeepAliveTimeoutSeconds() {
/**
* Set the timeout for keep-alive ping requests.
+ *
* @param keepAliveTimeoutSeconds timeout in seconds.
*/
public void setKeepAliveTimeoutSeconds(final int keepAliveTimeoutSeconds) {
@@ -121,6 +136,7 @@ public void setKeepAliveTimeoutSeconds(final int keepAliveTimeoutSeconds) {
/**
* The most aggressive keep-alive time clients are permitted to configure.
+ *
* @return time in minutes.
*/
public int getPermitKeepAliveTimeMinutes() {
@@ -129,6 +145,7 @@ public int getPermitKeepAliveTimeMinutes() {
/**
* Specify the most aggressive keep-alive time clients are permitted to configure.
+ *
* @param permitKeepAliveTimeMinutes time in minutes.
*/
public void setPermitKeepAliveTimeMinutes(final int permitKeepAliveTimeMinutes) {
@@ -137,6 +154,7 @@ public void setPermitKeepAliveTimeMinutes(final int permitKeepAliveTimeMinutes)
/**
* The delay before the server sends a keep-alive.
+ *
* @return delay in minutes.
*/
public int getKeepAliveTimeMinutes() {
@@ -145,6 +163,7 @@ public int getKeepAliveTimeMinutes() {
/**
* Set the delay before the server sends a keep-alive.
+ *
* @param keepAliveTimeMinutes delay in minutes.
*/
public void setKeepAliveTimeMinutes(final int keepAliveTimeMinutes) {
@@ -152,15 +171,19 @@ public void setKeepAliveTimeMinutes(final int keepAliveTimeMinutes) {
}
/**
- * Whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection.
+ * Whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the
+ * connection.
+ *
* @return true if clients are allowed to send keep-alive requests without calls; otherwise false.
*/
+ @SuppressWarnings("PMD.BooleanGetMethodName")
public boolean getPermitKeepAliveWithoutCalls() {
return permitKeepAliveWithoutCalls;
}
/**
* Get the server socket address.
+ *
* @return a socket address.
*/
public SocketAddress getServerAddress() {
@@ -169,6 +192,7 @@ public SocketAddress getServerAddress() {
/**
* Set the server socket address.
+ *
* @param address a socket address.
*/
public void setServerAddress(final SocketAddress address) {
@@ -176,7 +200,9 @@ public void setServerAddress(final SocketAddress address) {
}
/**
- * Whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection.
+ * Whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the
+ * connection.
+ *
* @return true if clients are allowed to send keep-alive requests without calls; otherwise false.
*/
public boolean isPermitKeepAliveWithoutCalls() {
@@ -184,7 +210,9 @@ public boolean isPermitKeepAliveWithoutCalls() {
}
/**
- * Specify whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection.
+ * Specify whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the
+ * connection.
+ *
* @param permitKeepAliveWithoutCalls Whether to allow clients to send keep-alive requests without calls.
*/
public void setPermitKeepAliveWithoutCalls(final boolean permitKeepAliveWithoutCalls) {
@@ -193,6 +221,7 @@ public void setPermitKeepAliveWithoutCalls(final boolean permitKeepAliveWithoutC
/**
* Password used to access the server key.
+ *
* @return a password.
*/
public String getKeyPassword() {
@@ -201,6 +230,7 @@ public String getKeyPassword() {
/**
* Set the password used to access the server key.
+ *
* @param keyPassword a password.
*/
public void setKeyPassword(final String keyPassword) {
@@ -209,6 +239,7 @@ public void setKeyPassword(final String keyPassword) {
/**
* Server keychain file name.
+ *
* @return a file name.
*/
public String getKeyCertChainFile() {
@@ -217,6 +248,7 @@ public String getKeyCertChainFile() {
/**
* Set the server keychain file name.
+ *
* @param keyCertChainFile a file name.
*/
public void setKeyCertChainFile(final String keyCertChainFile) {
@@ -225,6 +257,7 @@ public void setKeyCertChainFile(final String keyCertChainFile) {
/**
* Server key file name.
+ *
* @return a file name.
*/
public String getKeyFile() {
@@ -233,6 +266,7 @@ public String getKeyFile() {
/**
* Set the server key file name.
+ *
* @param keyFile a file name.
*/
public void setKeyFile(final String keyFile) {
@@ -241,6 +275,7 @@ public void setKeyFile(final String keyFile) {
/**
* Server trust certificate collection file name.
+ *
* @return a file name.
*/
public String getTrustCertCollectionFile() {
@@ -249,6 +284,7 @@ public String getTrustCertCollectionFile() {
/**
* Set the server trust certificate collection file name.
+ *
* @param trustCertCollectionFile a file name.
*/
public void setTrustCertCollectionFile(final String trustCertCollectionFile) {
@@ -257,6 +293,7 @@ public void setTrustCertCollectionFile(final String trustCertCollectionFile) {
/**
* Whether TLS is enabled for the server.
+ *
* @return true if TLS is enabled; otherwise false.
*/
public boolean isTlsEnabled() {
@@ -265,6 +302,7 @@ public boolean isTlsEnabled() {
/**
* Set whether TLS is enabled for the server.
+ *
* @param tlsEnabled true to enable TLS; otherwise false.
*/
public void setTlsEnabled(final boolean tlsEnabled) {
@@ -273,37 +311,46 @@ public void setTlsEnabled(final boolean tlsEnabled) {
/**
* Check that all the server property values are valid.
+ *
* @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");
}
if (this.getKeepAliveTimeMinutes() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getKeepAliveTimeMinutes() must be more then 0");
}
if (this.getKeepAliveTimeoutSeconds() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getKeepAliveTimeoutSeconds() must be more then 0");
}
if (this.getPermitKeepAliveTimeMinutes() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getPermitKeepAliveTimeMinutes() must be more then 0");
}
if (this.getMaxConnectionAgeSeconds() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getMaxConnectionAgeSeconds() must be more then 0");
}
if (this.getMaxInboundMetadataSize() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getMaxInboundMetadataSize() must be more then 0");
}
if (this.getMaxInboundMessageSize() <= 0) {
- throw new IllegalArgumentException("chaincodeServerProperties.getMaxInboundMessageSize() must be more then 0");
+ throw new IllegalArgumentException(
+ "chaincodeServerProperties.getMaxInboundMessageSize() must be more then 0");
}
- if (this.isTlsEnabled() && (this.getKeyCertChainFile() == null || this.getKeyCertChainFile().isEmpty()
- || this.getKeyFile() == null || this.getKeyFile().isEmpty())) {
+ if (this.isTlsEnabled()
+ && (this.getKeyCertChainFile() == null
+ || this.getKeyCertChainFile().isEmpty()
+ || this.getKeyFile() == null
+ || this.getKeyFile().isEmpty())) {
throw new IllegalArgumentException("if chaincodeServerProperties.isTlsEnabled() must be more specified"
- + " chaincodeServerProperties.getKeyCertChainFile() and chaincodeServerProperties.getKeyFile()"
- + " with optional chaincodeServerProperties.getKeyPassword()");
+ + " chaincodeServerProperties.getKeyCertChainFile() and chaincodeServerProperties.getKeyFile()"
+ + " with optional chaincodeServerProperties.getKeyPassword()");
}
}
-
-
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java
index 7c77f5daa..63a5fab40 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java
@@ -13,7 +13,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-
import org.hyperledger.fabric.protos.peer.ChaincodeEvent;
import org.hyperledger.fabric.protos.peer.SignedProposal;
import org.hyperledger.fabric.shim.Chaincode.Response;
@@ -24,23 +23,22 @@
import org.hyperledger.fabric.shim.ledger.QueryResultsIteratorWithMetadata;
/**
- * An object which manages the transaction context, provides access to state variables, and supports calls to other chaincode implementations.
+ * An object which manages the transaction context, provides access to state variables, and supports calls to other
+ * chaincode implementations.
*/
+@SuppressWarnings("PMD.ExcessivePublicCount")
public interface ChaincodeStub {
/**
- * Returns the arguments corresponding to the call to
- * {@link Chaincode#init(ChaincodeStub)} or
- * {@link Chaincode#invoke(ChaincodeStub)}, each argument represented as byte
- * array.
+ * Returns the arguments corresponding to the call to {@link Chaincode#init(ChaincodeStub)} or
+ * {@link Chaincode#invoke(ChaincodeStub)}, each argument represented as byte array.
*
* @return a list of arguments (bytes arrays)
*/
List getArgs();
/**
- * Returns the arguments corresponding to the call to
- * {@link Chaincode#init(ChaincodeStub)} or
+ * Returns the arguments corresponding to the call to {@link Chaincode#init(ChaincodeStub)} or
* {@link Chaincode#invoke(ChaincodeStub)}, cast to UTF-8 string.
*
* @return a list of arguments cast to UTF-8 strings
@@ -48,22 +46,19 @@ public interface ChaincodeStub {
List getStringArgs();
/**
- * A convenience method that returns the first argument of the chaincode
- * invocation for use as a function name.
- *
- * The bytes of the first argument are decoded as a UTF-8 string.
+ * A convenience method that returns the first argument of the chaincode invocation for use as a function name.
+ *
+ *
The bytes of the first argument are decoded as a UTF-8 string.
*
* @return the function name
*/
String getFunction();
/**
- * A convenience method that returns all except the first argument of the
- * chaincode invocation for use as the parameters to the function returned by
- * #{@link ChaincodeStub#getFunction()}.
- *
- * The bytes of the arguments are decoded as a UTF-8 strings and returned as a
- * list of string parameters.
+ * A convenience method that returns all except the first argument of the chaincode invocation for use as the
+ * parameters to the function returned by #{@link ChaincodeStub#getFunction()}.
+ *
+ *
The bytes of the arguments are decoded as a UTF-8 strings and returned as a list of string parameters.
*
* @return a list of parameters
*/
@@ -71,9 +66,8 @@ public interface ChaincodeStub {
/**
* Returns the transaction id for the current chaincode invocation request.
- *
- * The transaction id uniquely identifies the transaction within the scope of
- * the channel.
+ *
+ *
The transaction id uniquely identifies the transaction within the scope of the channel.
*
* @return the transaction id
*/
@@ -81,49 +75,45 @@ public interface ChaincodeStub {
/**
* Returns the channel id for the current proposal.
- *
- * This would be the 'channel_id' of the transaction proposal except where the
- * chaincode is calling another on a different channel.
+ *
+ *
This would be the 'channel_id' of the transaction proposal except where the chaincode is calling another on a
+ * different channel.
*
* @return the channel id
*/
String getChannelId();
/**
- * Locally calls the specified chaincode invoke() using the same
- * transaction context.
- *
- * chaincode calling chaincode doesn't create a new transaction message.
- *
- * If the called chaincode is on the same channel, it simply adds the called
- * chaincode read set and write set to the calling transaction.
- *
- * If the called chaincode is on a different channel, only the Response is
- * returned to the calling chaincode; any putState calls from the
- * called chaincode will not have any effect on the ledger; that is, the called
- * chaincode on a different channel will not have its read set and write set
- * applied to the transaction. Only the calling chaincode's read set and write
- * set will be applied to the transaction. Effectively the called chaincode on a
- * different channel is a `Query`, which does not participate in state
- * validation checks in subsequent commit phase.
- *
- * If `channel` is empty, the caller's channel is assumed.
- *
- * Invoke another chaincode using the same transaction context.
+ * Locally calls the specified chaincode invoke() using the same transaction context.
+ *
+ *
chaincode calling chaincode doesn't create a new transaction message.
+ *
+ *
If the called chaincode is on the same channel, it simply adds the called chaincode read set and write set to
+ * the calling transaction.
+ *
+ *
If the called chaincode is on a different channel, only the Response is returned to the calling chaincode; any
+ * putState calls from the called chaincode will not have any effect on the ledger; that is, the called
+ * chaincode on a different channel will not have its read set and write set applied to the transaction. Only the
+ * calling chaincode's read set and write set will be applied to the transaction. Effectively the called chaincode
+ * on a different channel is a `Query`, which does not participate in state validation checks in subsequent commit
+ * phase.
+ *
+ *
If `channel` is empty, the caller's channel is assumed.
+ *
+ *
Invoke another chaincode using the same transaction context.
*
* @param chaincodeName Name of chaincode to be invoked.
- * @param args Arguments to pass on to the called chaincode.
- * @param channel If not specified, the caller's channel is assumed.
+ * @param args Arguments to pass on to the called chaincode.
+ * @param channel If not specified, the caller's channel is assumed.
* @return {@link Response} object returned by called chaincode
*/
Response invokeChaincode(String chaincodeName, List args, String channel);
/**
* Returns the value of the specified key from the ledger.
- *
- * Note that getState doesn't read data from the writeset, which has not been
- * committed to the ledger. In other words, GetState doesn't consider data
- * modified by PutState that has not been committed.
+ *
+ *
Note that getState doesn't read data from the writeset, which has not been committed to the ledger. In other
+ * words, GetState doesn't consider data modified by PutState that has not been committed.
*
* @param key name of the value
* @return value the value read from the ledger
@@ -131,9 +121,8 @@ public interface ChaincodeStub {
byte[] getState(String key);
/**
- * retrieves the key-level endorsement policy for key. Note that
- * this will introduce a read dependency on key in the
- * transaction's readset.
+ * retrieves the key-level endorsement policy for key. Note that this will introduce a read dependency
+ * on key in the transaction's readset.
*
* @param key key to get key level endorsement
* @return endorsement policy
@@ -141,15 +130,14 @@ public interface ChaincodeStub {
byte[] getStateValidationParameter(String key);
/**
- * Puts the specified key and value into the
- * transaction's writeset as a data-write proposal.
- *
- * putState doesn't effect the ledger until the transaction is validated and
- * successfully committed. Simple keys must not be an empty string and must not
- * start with 0x00 character, in order to avoid range query collisions with
+ * Puts the specified key and value into the transaction's writeset as a data-write
+ * proposal.
+ *
+ *
putState doesn't effect the ledger until the transaction is validated and successfully committed. Simple keys
+ * must not be an empty string and must not start with 0x00 character, in order to avoid range query collisions with
* composite keys
*
- * @param key name of the value
+ * @param key name of the value
* @param value the value to write to the ledger
*/
void putState(String key, byte[] value);
@@ -157,79 +145,66 @@ public interface ChaincodeStub {
/**
* Sets the key-level endorsement policy for key.
*
- * @param key key to set key level endorsement
+ * @param key key to set key level endorsement
* @param value endorsement policy
*/
void setStateValidationParameter(String key, byte[] value);
/**
- * Records the specified key to be deleted in the writeset of the
- * transaction proposal.
- *
- * The key and its value will be deleted from the ledger when the
- * transaction is validated and successfully committed.
+ * Records the specified key to be deleted in the writeset of the transaction proposal.
+ *
+ *
The key and its value will be deleted from the ledger when the transaction is validated and
+ * successfully committed.
*
* @param key name of the value to be deleted
*/
void delState(String key);
/**
- * Returns all existing keys, and their values, that are lexicographically
- * between startkey (inclusive) and the endKey
- * (exclusive).
- *
- * The keys are returned by the iterator in lexical order. Note that startKey
- * and endKey can be empty string, which implies unbounded range query on start
- * or end.
- *
- * Call close() on the returned {@link QueryResultsIterator#close()} object when
- * done.
+ * Returns all existing keys, and their values, that are lexicographically between startkey (inclusive)
+ * and the endKey (exclusive).
+ *
+ *
The keys are returned by the iterator in lexical order. Note that startKey and endKey can be empty string,
+ * which implies unbounded range query on start or end.
+ *
+ *
Call close() on the returned {@link QueryResultsIterator#close()} object when done.
*
* @param startKey key as the start of the key range (inclusive)
- * @param endKey key as the end of the key range (exclusive)
+ * @param endKey key as the end of the key range (exclusive)
* @return an {@link Iterable} of {@link KeyValue}
*/
QueryResultsIterator getStateByRange(String startKey, String endKey);
/**
- * Returns a range iterator over a set of keys in the ledger. The iterator can
- * be used to fetch keys between the startKey (inclusive) and
- * endKey (exclusive). When an empty string is passed as a value to
- * the bookmark argument, the returned iterator can be used to
- * fetch the first pageSize keys between the startKey
- * and endKey. When the bookmark is a non-empty
- * string, the iterator can be used to fetch first pageSize keys
- * between the bookmark and endKey. Note that only the
- * bookmark present in a prior page of query results
- * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata})
- * can be used as a value to the bookmark argument. Otherwise, an empty string
- * must be passed as bookmark. The keys are returned by the iterator in lexical
- * order. Note that startKey and endKey can be empty
- * string, which implies unbounded range query on start or end. This call is
- * only supported in a read only transaction.
+ * Returns a range iterator over a set of keys in the ledger. The iterator can be used to fetch keys between the
+ * startKey (inclusive) and endKey (exclusive). When an empty string is passed as a value
+ * to the bookmark argument, the returned iterator can be used to fetch the first pageSize
+ * keys between the startKey and endKey. When the bookmark is a non-empty
+ * string, the iterator can be used to fetch first pageSize keys between the bookmark and
+ * endKey. Note that only the bookmark present in a prior page of query results
+ * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata}) can be used as a value to the bookmark
+ * argument. Otherwise, an empty string must be passed as bookmark. The keys are returned by the iterator in lexical
+ * order. Note that startKey and endKey can be empty string, which implies unbounded range
+ * query on start or end. This call is only supported in a read only transaction.
*
* @param startKey the start key
- * @param endKey the end key
+ * @param endKey the end key
* @param pageSize the page size
* @param bookmark the bookmark
* @return QueryIterator
*/
- QueryResultsIteratorWithMetadata getStateByRangeWithPagination(String startKey, String endKey, int pageSize, String bookmark);
+ QueryResultsIteratorWithMetadata getStateByRangeWithPagination(
+ String startKey, String endKey, int pageSize, String bookmark);
/**
- * Returns all existing keys, and their values, that are prefixed by the
- * specified partial {@link CompositeKey}.
- *
- * If a full composite key is specified, it will not match itself, resulting in
- * no keys being returned.
- *
- * This method takes responsibility to correctly parse the {@link CompositeKey}
- * from a String and behaves exactly as
- * {@link ChaincodeStub#getStateByPartialCompositeKey(CompositeKey)}.
- *
- *
- * Call close() on the returned {@link QueryResultsIterator#close()} object when
- * done.
+ * Returns all existing keys, and their values, that are prefixed by the specified partial {@link CompositeKey}.
+ *
+ *
If a full composite key is specified, it will not match itself, resulting in no keys being returned.
+ *
+ *
This method takes responsibility to correctly parse the {@link CompositeKey} from a String and behaves exactly
+ * as {@link ChaincodeStub#getStateByPartialCompositeKey(CompositeKey)}.
+ *
+ *
Call close() on the returned {@link QueryResultsIterator#close()} object when done.
*
* @param compositeKey partial composite key
* @return an {@link Iterable} of {@link KeyValue}
@@ -237,21 +212,15 @@ public interface ChaincodeStub {
QueryResultsIterator getStateByPartialCompositeKey(String compositeKey);
/**
- * Returns all existing keys, and their values, that are prefixed by the
- * specified partial {@link CompositeKey}.
- *
- * It combines the attributes and the objectType to form a partial composite
- * key.
- *
- * If a full composite key is specified, it will not match itself, resulting in
- * no keys being returned.
- *
- * This method takes responsibility to correctly combine Object type and
- * attributes creating a {@link CompositeKey} and behaves exactly as
- * {@link ChaincodeStub#getStateByPartialCompositeKey(CompositeKey)}.
- *
- * Call close() on the returned {@link QueryResultsIterator#close()} object when
- * done.
+ * Returns all existing keys, and their values, that are prefixed by the specified partial {@link CompositeKey}.
+ *
+ * It combines the attributes and the objectType to form a partial composite key.
+ *
+ *
If a full composite key is specified, it will not match itself, resulting in no keys being returned.
+ *
+ *
This method takes responsibility to correctly combine Object type and attributes creating a
+ * {@link CompositeKey} and behaves exactly as {@link ChaincodeStub#getStateByPartialCompositeKey(CompositeKey)}.
+ * Call close() on the returned {@link QueryResultsIterator#close()} object when done.
*
* @param objectType ObjectType of the compositeKey
* @param attributes Attributes of the composite key
@@ -260,11 +229,9 @@ public interface ChaincodeStub {
QueryResultsIterator getStateByPartialCompositeKey(String objectType, String... attributes);
/**
- * Returns all existing keys, and their values, that are prefixed by the
- * specified partial {@link CompositeKey}.
- *
- * If a full composite key is specified, it will not match itself, resulting in
- * no keys being returned.
+ * Returns all existing keys, and their values, that are prefixed by the specified partial {@link CompositeKey}.
+ *
+ *
If a full composite key is specified, it will not match itself, resulting in no keys being returned.
*
* @param compositeKey partial composite key
* @return an {@link Iterable} of {@link KeyValue}
@@ -272,36 +239,32 @@ public interface ChaincodeStub {
QueryResultsIterator getStateByPartialCompositeKey(CompositeKey compositeKey);
/**
- * Queries the state in the ledger based on a given partial composite key. This
- * function returns an iterator which can be used to iterate over the composite
- * keys whose prefix matches the given partial composite key.
- *
- * When an empty string is passed as a value to the bookmark
- * argument, the returned iterator can be used to fetch the first
- * pageSize composite keys whose prefix matches the given partial
- * composite key.
- *
- * When the bookmark is a non-empty string, the iterator can be
- * used to fetch first pageSize keys between the
- * bookmark (inclusive) and and the last matching composite key.
- *
- * Note that only the bookmark present in a prior page of query results
- * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata})
- * can be used as a value to the bookmark argument. Otherwise, an empty string
- * must be passed as bookmark.
- *
- * This call is only supported in a read only transaction.
+ * Queries the state in the ledger based on a given partial composite key. This function returns an iterator which
+ * can be used to iterate over the composite keys whose prefix matches the given partial composite key.
+ *
+ *
When an empty string is passed as a value to the bookmark argument, the returned iterator can be
+ * used to fetch the first pageSize composite keys whose prefix matches the given partial composite
+ * key.
+ *
+ *
When the bookmark is a non-empty string, the iterator can be used to fetch first pageSize
+ * keys between the bookmark (inclusive) and and the last matching composite key.
+ *
+ *
Note that only the bookmark present in a prior page of query results
+ * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata}) can be used as a value to the bookmark
+ * argument. Otherwise, an empty string must be passed as bookmark.
+ *
+ *
This call is only supported in a read only transaction.
*
* @param compositeKey the composite key
- * @param pageSize the page size
- * @param bookmark the bookmark
+ * @param pageSize the page size
+ * @param bookmark the bookmark
* @return QueryIterator
*/
- QueryResultsIteratorWithMetadata getStateByPartialCompositeKeyWithPagination(CompositeKey compositeKey, int pageSize, String bookmark);
+ QueryResultsIteratorWithMetadata getStateByPartialCompositeKeyWithPagination(
+ CompositeKey compositeKey, int pageSize, String bookmark);
/**
- * Given a set of attributes, this method combines these attributes to return a
- * composite key.
+ * Given a set of attributes, this method combines these attributes to return a composite key.
*
* @param objectType A string used as the prefix of the resulting key
* @param attributes List of attribute values to concatenate into the key
@@ -319,53 +282,46 @@ public interface ChaincodeStub {
/**
* Performs a "rich" query against a state database.
- *
- * It is only supported for state databases that support rich query, e.g.
- * CouchDB. The query string is in the native syntax of the underlying state
- * database. An {@link QueryResultsIterator} is returned which can be used to
+ *
+ *
It is only supported for state databases that support rich query, e.g. CouchDB. The query string is in the
+ * native syntax of the underlying state database. An {@link QueryResultsIterator} is returned which can be used to
* iterate (next) over the query result set.
*
- * @param query query string in a syntax supported by the underlying state
- * database
+ * @param query query string in a syntax supported by the underlying state database
* @return {@link QueryResultsIterator} object contains query results
- * @throws UnsupportedOperationException if the underlying state database does
- * not support rich queries.
+ * @throws UnsupportedOperationException if the underlying state database does not support rich queries.
*/
QueryResultsIterator getQueryResult(String query);
/**
- * Performs a "rich" query against a state database. It is only supported for
- * state databases that support rich query, e.g., CouchDB. The query string is
- * in the native syntax of the underlying state database. An iterator is
- * returned which can be used to iterate over keys in the query result set. When
- * an empty string is passed as a value to the bookmark argument,
- * the returned iterator can be used to fetch the first pageSize of
- * query results..
- *
- * When the bookmark is a non-empty string, the iterator can be
- * used to fetch first pageSize keys between the
- * bookmark (inclusive) and the last key in the query result.
- *
- * Note that only the bookmark present in a prior page of query results
- * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata})
- * can be used as a value to the bookmark argument. Otherwise, an empty string
- * must be passed as bookmark.
- *
- * This call is only supported in a read only transaction.
- *
- * @param query the query
+ * Performs a "rich" query against a state database. It is only supported for state databases that support rich
+ * query, e.g., CouchDB. The query string is in the native syntax of the underlying state database. An iterator is
+ * returned which can be used to iterate over keys in the query result set. When an empty string is passed as a
+ * value to the bookmark argument, the returned iterator can be used to fetch the first pageSize
+ * of query results..
+ *
+ *
When the bookmark is a non-empty string, the iterator can be used to fetch first pageSize
+ * keys between the bookmark (inclusive) and the last key in the query result.
+ *
+ *
Note that only the bookmark present in a prior page of query results
+ * ({@link org.hyperledger.fabric.protos.peer.QueryResponseMetadata}) can be used as a value to the bookmark
+ * argument. Otherwise, an empty string must be passed as bookmark.
+ *
+ *
This call is only supported in a read only transaction.
+ *
+ * @param query the query
* @param pageSize the page size
* @param bookmark the bookmark
* @return QueryIterator
*/
- QueryResultsIteratorWithMetadata getQueryResultWithPagination(String query, int pageSize, String bookmark);
+ QueryResultsIteratorWithMetadata getQueryResultWithPagination(
+ String query, int pageSize, String bookmark);
/**
* Returns a history of key values across time.
- *
- * For each historic key update, the historic value and associated transaction
- * id and timestamp are returned. The timestamp is the timestamp provided by the
- * client in the proposal header. This method requires peer configuration
+ *
+ *
For each historic key update, the historic value and associated transaction id and timestamp are returned. The
+ * timestamp is the timestamp provided by the client in the proposal header. This method requires peer configuration
* core.ledger.history.enableHistoryDatabase to be true.
*
* @param key The state variable key
@@ -374,227 +330,197 @@ public interface ChaincodeStub {
QueryResultsIterator getHistoryForKey(String key);
/**
- * Returns the value of the specified key from the specified
- * collection.
- *
- * Note that {@link #getPrivateData(String, String)} doesn't read data from the
- * private writeset, which has not been committed to the
- * collection. In other words,
- * {@link #getPrivateData(String, String)} doesn't consider data modified by
- * {@link #putPrivateData(String, String, byte[])} * that has not been
- * committed.
+ * Returns the value of the specified key from the specified collection.
+ *
+ *
Note that {@link #getPrivateData(String, String)} doesn't read data from the private writeset, which has not
+ * been committed to the collection. In other words, {@link #getPrivateData(String, String)} doesn't
+ * consider data modified by {@link #putPrivateData(String, String, byte[])} * that has not been committed.
*
* @param collection name of the collection
- * @param key name of the value
+ * @param key name of the value
* @return value the value read from the collection
*/
byte[] getPrivateData(String collection, String key);
/**
* @param collection name of the collection
- * @param key name of the value
+ * @param key name of the value
* @return the private data hash
*/
byte[] getPrivateDataHash(String collection, String key);
/**
- * Retrieves the key-level endorsement policy for the private data specified by
- * key. Note that this introduces a read dependency on
- * key in the transaction's readset.
+ * Retrieves the key-level endorsement policy for the private data specified by key. Note that this
+ * introduces a read dependency on key in the transaction's readset.
*
* @param collection name of the collection
- * @param key key to get endorsement policy
+ * @param key key to get endorsement policy
* @return Key Level endorsement as byte array
*/
byte[] getPrivateDataValidationParameter(String collection, String key);
/**
- * Puts the specified key and value into the
- * transaction's private writeset.
- *
- * Note that only hash of the private writeset goes into the transaction
- * proposal response (which is sent to the client who issued the transaction)
- * and the actual private writeset gets temporarily stored in a transient store.
- * putPrivateData doesn't effect the collection until the
- * transaction is validated and successfully committed. Simple keys must not be
- * an empty string and must not start with null character (0x00), in order to
- * avoid range query collisions with composite keys, which internally get
- * prefixed with 0x00 as composite key namespace.
+ * Puts the specified key and value into the transaction's private writeset.
+ *
+ *
Note that only hash of the private writeset goes into the transaction proposal response (which is sent to the
+ * client who issued the transaction) and the actual private writeset gets temporarily stored in a transient store.
+ * putPrivateData doesn't effect the collection until the transaction is validated and successfully
+ * committed. Simple keys must not be an empty string and must not start with null character (0x00), in order to
+ * avoid range query collisions with composite keys, which internally get prefixed with 0x00 as composite key
+ * namespace.
*
* @param collection name of the collection
- * @param key name of the value
- * @param value the value to write to the ledger
+ * @param key name of the value
+ * @param value the value to write to the ledger
*/
void putPrivateData(String collection, String key, byte[] value);
/**
- * Sets the key-level endorsement policy for the private data specified by
- * key.
+ * Sets the key-level endorsement policy for the private data specified by key.
*
* @param collection name of the collection
- * @param key key to set endorsement policy
- * @param value endorsement policy
+ * @param key key to set endorsement policy
+ * @param value endorsement policy
*/
void setPrivateDataValidationParameter(String collection, String key, byte[] value);
/**
- * Records the specified key to be deleted in the private writeset
- * of the transaction.
- *
- * Note that only hash of the private writeset goes into the transaction
- * proposal response (which is sent to the client who issued the transaction)
- * and the actual private writeset gets temporarily stored in a transient store.
- * The key and its value will be deleted from the collection when
- * the transaction is validated and successfully committed.
+ * Records the specified key to be deleted in the private writeset of the transaction.
+ *
+ *
Note that only hash of the private writeset goes into the transaction proposal response (which is sent to the
+ * client who issued the transaction) and the actual private writeset gets temporarily stored in a transient store.
+ * The key and its value will be deleted from the collection when the transaction is validated and
+ * successfully committed.
*
* @param collection name of the collection
- * @param key name of the value to be deleted
+ * @param key name of the value to be deleted
*/
void delPrivateData(String collection, String key);
/**
- * Reqauests purging of the specified key to be from
- * the private data stores.
- *
- * Note that only hash of the private writeset goes into the transaction
- * proposal response (which is sent to the client who issued the transaction)
- * and the actual private writeset gets temporarily stored in a transient store.
- * The key and its value will be purged from the collection. This is an
- * asynchronous activity.
- *
- * Purge is a complete removal of the history of the key. There is existing purge
- * possible mased on block height. This API allows the contract to be pro-active in
- * requesting data be purged. This can contribute towards meeting privacy requirements.
+ * Reqauests purging of the specified key to be from the private data stores.
+ *
+ *
Note that only hash of the private writeset goes into the transaction proposal response (which is sent to the
+ * client who issued the transaction) and the actual private writeset gets temporarily stored in a transient store.
+ * The key and its value will be purged from the collection. This is an asynchronous activity.
+ *
+ *
Purge is a complete removal of the history of the key. There is existing purge possible mased on block height.
+ * This API allows the contract to be pro-active in requesting data be purged. This can contribute towards meeting
+ * privacy requirements.
*
* @param collection name of the collection
- * @param key name of the value to be deleted
+ * @param key name of the value to be deleted
*/
void purgePrivateData(String collection, String key);
/**
- * Returns all existing keys, and their values, that are lexicographically
- * between startkey (inclusive) and the endKey
- * (exclusive) in a given private collection.
- *
- * Note that startKey and endKey can be empty string, which implies unbounded
- * range query on start or end. The query is re-executed during validation phase
- * to ensure result set has not changed since transaction endorsement (phantom
- * reads detected).
+ * Returns all existing keys, and their values, that are lexicographically between startkey (inclusive)
+ * and the endKey (exclusive) in a given private collection.
+ *
+ *
Note that startKey and endKey can be empty string, which implies unbounded range query on start or end. The
+ * query is re-executed during validation phase to ensure result set has not changed since transaction endorsement
+ * (phantom reads detected).
*
* @param collection name of the collection
- * @param startKey private data variable key as the start of the key range
- * (inclusive)
- * @param endKey private data variable key as the end of the key range
- * (exclusive)
+ * @param startKey private data variable key as the start of the key range (inclusive)
+ * @param endKey private data variable key as the end of the key range (exclusive)
* @return an {@link Iterable} of {@link KeyValue}
*/
QueryResultsIterator getPrivateDataByRange(String collection, String startKey, String endKey);
/**
- * Returns all existing keys, and their values, that are prefixed by the
- * specified partial {@link CompositeKey} in a given private collection.
- *
- * If a full composite key is specified, it will not match itself, resulting in
- * no keys being returned.
- *
- * The query is re-executed during validation phase to ensure result set has not
- * changed since transaction endorsement (phantom reads detected).
- *
- * This method takes responsibility to correctly parse the {@link CompositeKey}
- * from a String and behaves exactly as
- * {@link ChaincodeStub#getPrivateDataByPartialCompositeKey(String, CompositeKey)}.
- *
- *
- * @param collection name of the collection
+ * Returns all existing keys, and their values, that are prefixed by the specified partial {@link CompositeKey} in a
+ * given private collection.
+ *
+ * If a full composite key is specified, it will not match itself, resulting in no keys being returned.
+ *
+ *
The query is re-executed during validation phase to ensure result set has not changed since transaction
+ * endorsement (phantom reads detected).
+ *
+ *
This method takes responsibility to correctly parse the {@link CompositeKey} from a String and behaves exactly
+ * as {@link ChaincodeStub#getPrivateDataByPartialCompositeKey(String, CompositeKey)}.
+ *
+ * @param collection name of the collection
* @param compositeKey partial composite key
* @return an {@link Iterable} of {@link KeyValue}
*/
QueryResultsIterator