diff --git a/asset-transfer-basic/chaincode-java/.gitattributes b/asset-transfer-basic/chaincode-java/.gitattributes deleted file mode 100644 index 00a51aff..00000000 --- a/asset-transfer-basic/chaincode-java/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/asset-transfer-basic/chaincode-java/.gitignore b/asset-transfer-basic/chaincode-java/.gitignore deleted file mode 100644 index da7b093d..00000000 --- a/asset-transfer-basic/chaincode-java/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.idea/ -.gradle/ -bin/ \ No newline at end of file diff --git a/asset-transfer-basic/chaincode-java/Dockerfile b/asset-transfer-basic/chaincode-java/Dockerfile deleted file mode 100755 index c42f3051..00000000 --- a/asset-transfer-basic/chaincode-java/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# the first stage -FROM gradle:8.6-jdk11 AS GRADLE_BUILD - -# copy the build.gradle and src code to the container -COPY src/ src/ -COPY build.gradle ./ - -# Build and package our code -RUN gradle --no-daemon build shadowJar -x checkstyleMain -x checkstyleTest - - -# the second stage of our build just needs the compiled files -FROM openjdk:11-jre -ARG CC_SERVER_PORT=9999 - -# Setup tini to work better handle signals -ENV TINI_VERSION v0.19.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini -RUN chmod +x /tini - -RUN addgroup --system javauser && useradd -g javauser javauser - -# copy only the artifacts we need from the first stage and discard the rest -COPY --chown=javauser:javauser --from=GRADLE_BUILD /home/gradle/build/libs/chaincode.jar /chaincode.jar -COPY --chown=javauser:javauser docker/docker-entrypoint.sh /docker-entrypoint.sh - -ENV PORT $CC_SERVER_PORT -EXPOSE $CC_SERVER_PORT - -USER javauser -ENTRYPOINT [ "/tini", "--", "/docker-entrypoint.sh" ] diff --git a/asset-transfer-basic/chaincode-java/README.md b/asset-transfer-basic/chaincode-java/README.md deleted file mode 100644 index e069f568..00000000 --- a/asset-transfer-basic/chaincode-java/README.md +++ /dev/null @@ -1,10 +0,0 @@ - -## Basic Asset Transfer - -This sample implements the basic asset transfer scenario, illustrating the use of the Java Contract SDKs to provide a -smart contract as a service. - -To run this chaincode contract locally on a development network, see: - -- [Debugging chaincode as a service](../../test-network-k8s/docs/CHAINCODE_AS_A_SERVICE.md) (Kube test network) -- [End-to-end with the test-network](../../test-network/CHAINCODE_AS_A_SERVICE_TUTORIAL.md#end-to-end-with-the-the-test-network) (Docker compose) diff --git a/asset-transfer-basic/chaincode-java/build.gradle b/asset-transfer-basic/chaincode-java/build.gradle deleted file mode 100644 index ae4bc4cf..00000000 --- a/asset-transfer-basic/chaincode-java/build.gradle +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -plugins { - id 'com.github.johnrengelman.shadow' version '8.1.1' - id 'application' - id 'checkstyle' - id 'jacoco' -} - -group 'org.hyperledger.fabric.samples' -version '1.0-SNAPSHOT' - -dependencies { - - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.+' - implementation 'org.json:json:+' - implementation 'com.owlike:genson:1.5' - testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' - testImplementation 'org.assertj:assertj-core:3.25.3' - testImplementation 'org.mockito:mockito-core:5.12.0' -} - -repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -application { - mainClass = 'org.hyperledger.fabric.contract.ContractRouter' -} - -checkstyle { - toolVersion '8.21' - configFile file("config/checkstyle/checkstyle.xml") -} - -checkstyleMain { - source ='src/main/java' -} - -checkstyleTest { - source ='src/test/java' -} - -jacocoTestReport { - dependsOn test -} - -jacocoTestCoverageVerification { - violationRules { - rule { - limit { - minimum = 0.9 - } - } - } - - finalizedBy jacocoTestReport -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -mainClassName = 'org.hyperledger.fabric.contract.ContractRouter' - -shadowJar { - archiveBaseName = 'chaincode' - archiveVersion = '' - archiveClassifier = '' - mergeServiceFiles() - - manifest { - attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' - } -} - -check.dependsOn jacocoTestCoverageVerification -installDist.dependsOn check diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml deleted file mode 100644 index acd5df44..00000000 --- a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml deleted file mode 100644 index 8c44b0a0..00000000 --- a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh b/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh deleted file mode 100755 index 1ff8e07e..00000000 --- a/asset-transfer-basic/chaincode-java/docker/docker-entrypoint.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -# -# SPDX-License-Identifier: Apache-2.0 -# -set -euo pipefail -: ${CORE_PEER_TLS_ENABLED:="false"} -: ${DEBUG:="false"} - -if [ "${DEBUG,,}" = "true" ]; then - exec java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000 -jar /chaincode.jar -elif [ "${CORE_PEER_TLS_ENABLED,,}" = "true" ]; then - exec java -jar /chaincode.jar # todo -else - exec java -jar /chaincode.jar -fi - diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7f93135c..00000000 Binary files a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a80b22ce..00000000 --- a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/asset-transfer-basic/chaincode-java/gradlew b/asset-transfer-basic/chaincode-java/gradlew deleted file mode 100755 index 0adc8e1a..00000000 --- a/asset-transfer-basic/chaincode-java/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/asset-transfer-basic/chaincode-java/gradlew.bat b/asset-transfer-basic/chaincode-java/gradlew.bat deleted file mode 100644 index 93e3f59f..00000000 --- a/asset-transfer-basic/chaincode-java/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/asset-transfer-basic/chaincode-java/settings.gradle b/asset-transfer-basic/chaincode-java/settings.gradle deleted file mode 100644 index b8074969..00000000 --- a/asset-transfer-basic/chaincode-java/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ -rootProject.name = System.getenv('CHAINCODE_NAME') ?: 'basic' \ No newline at end of file diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java deleted file mode 100644 index 803f22fb..00000000 --- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import java.util.Objects; - -import org.hyperledger.fabric.contract.annotation.DataType; -import org.hyperledger.fabric.contract.annotation.Property; - -import com.owlike.genson.annotation.JsonProperty; - -@DataType() -public final class Asset { - - @Property() - private final String assetID; - - @Property() - private final String color; - - @Property() - private final int size; - - @Property() - private final String owner; - - @Property() - private final int appraisedValue; - - public String getAssetID() { - return assetID; - } - - public String getColor() { - return color; - } - - public int getSize() { - return size; - } - - public String getOwner() { - return owner; - } - - public int getAppraisedValue() { - return appraisedValue; - } - - public Asset(@JsonProperty("assetID") final String assetID, @JsonProperty("color") final String color, - @JsonProperty("size") final int size, @JsonProperty("owner") final String owner, - @JsonProperty("appraisedValue") final int appraisedValue) { - this.assetID = assetID; - this.color = color; - this.size = size; - this.owner = owner; - this.appraisedValue = appraisedValue; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - - Asset other = (Asset) obj; - - return Objects.deepEquals( - new String[] {getAssetID(), getColor(), getOwner()}, - new String[] {other.getAssetID(), other.getColor(), other.getOwner()}) - && - Objects.deepEquals( - new int[] {getSize(), getAppraisedValue()}, - new int[] {other.getSize(), other.getAppraisedValue()}); - } - - @Override - public int hashCode() { - return Objects.hash(getAssetID(), getColor(), getSize(), getOwner(), getAppraisedValue()); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + " [assetID=" + assetID + ", color=" - + color + ", size=" + size + ", owner=" + owner + ", appraisedValue=" + appraisedValue + "]"; - } -} diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java deleted file mode 100644 index 41c55ddc..00000000 --- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import java.util.ArrayList; -import java.util.List; - - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.contract.ContractInterface; -import org.hyperledger.fabric.contract.annotation.Contact; -import org.hyperledger.fabric.contract.annotation.Contract; -import org.hyperledger.fabric.contract.annotation.Default; -import org.hyperledger.fabric.contract.annotation.Info; -import org.hyperledger.fabric.contract.annotation.License; -import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.KeyValue; -import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; - -import com.owlike.genson.Genson; - -@Contract( - name = "basic", - info = @Info( - title = "Asset Transfer", - description = "The hyperlegendary asset transfer", - version = "0.0.1-SNAPSHOT", - license = @License( - name = "Apache 2.0 License", - url = "http://www.apache.org/licenses/LICENSE-2.0.html"), - contact = @Contact( - email = "a.transfer@example.com", - name = "Adrian Transfer", - url = "https://hyperledger.example.com"))) -@Default -public final class AssetTransfer implements ContractInterface { - - private final Genson genson = new Genson(); - - private enum AssetTransferErrors { - ASSET_NOT_FOUND, - ASSET_ALREADY_EXISTS - } - - /** - * Creates some initial assets on the ledger. - * - * @param ctx the transaction context - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void InitLedger(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - - CreateAsset(ctx, "asset1", "blue", 5, "Tomoko", 300); - CreateAsset(ctx, "asset2", "red", 5, "Brad", 400); - CreateAsset(ctx, "asset3", "green", 10, "Jin Soo", 500); - CreateAsset(ctx, "asset4", "yellow", 10, "Max", 600); - CreateAsset(ctx, "asset5", "black", 15, "Adrian", 700); - CreateAsset(ctx, "asset6", "white", 15, "Michel", 700); - - } - - /** - * Creates a new asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the new asset - * @param color the color of the new asset - * @param size the size for the new asset - * @param owner the owner of the new asset - * @param appraisedValue the appraisedValue of the new asset - * @return the created asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset CreateAsset(final Context ctx, final String assetID, final String color, final int size, - final String owner, final int appraisedValue) { - ChaincodeStub stub = ctx.getStub(); - - if (AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s already exists", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString()); - } - - Asset asset = new Asset(assetID, color, size, owner, appraisedValue); - // Use Genson to convert the Asset into string, sort it alphabetically and serialize it into a json string - String sortedJson = genson.serialize(asset); - stub.putStringState(assetID, sortedJson); - - return asset; - } - - /** - * Retrieves an asset with the specified ID from the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return the asset found on the ledger if there was one - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public Asset ReadAsset(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - String assetJSON = stub.getStringState(assetID); - - if (assetJSON == null || assetJSON.isEmpty()) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - Asset asset = genson.deserialize(assetJSON, Asset.class); - return asset; - } - - /** - * Updates the properties of an asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being updated - * @param color the color of the asset being updated - * @param size the size of the asset being updated - * @param owner the owner of the asset being updated - * @param appraisedValue the appraisedValue of the asset being updated - * @return the transferred asset - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public Asset UpdateAsset(final Context ctx, final String assetID, final String color, final int size, - final String owner, final int appraisedValue) { - ChaincodeStub stub = ctx.getStub(); - - if (!AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - Asset newAsset = new Asset(assetID, color, size, owner, appraisedValue); - // Use Genson to convert the Asset into string, sort it alphabetically and serialize it into a json string - String sortedJson = genson.serialize(newAsset); - stub.putStringState(assetID, sortedJson); - return newAsset; - } - - /** - * Deletes asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being deleted - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public void DeleteAsset(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - - if (!AssetExists(ctx, assetID)) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - stub.delState(assetID); - } - - /** - * Checks the existence of the asset on the ledger - * - * @param ctx the transaction context - * @param assetID the ID of the asset - * @return boolean indicating the existence of the asset - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public boolean AssetExists(final Context ctx, final String assetID) { - ChaincodeStub stub = ctx.getStub(); - String assetJSON = stub.getStringState(assetID); - - return (assetJSON != null && !assetJSON.isEmpty()); - } - - /** - * Changes the owner of a asset on the ledger. - * - * @param ctx the transaction context - * @param assetID the ID of the asset being transferred - * @param newOwner the new owner - * @return the old owner - */ - @Transaction(intent = Transaction.TYPE.SUBMIT) - public String TransferAsset(final Context ctx, final String assetID, final String newOwner) { - ChaincodeStub stub = ctx.getStub(); - String assetJSON = stub.getStringState(assetID); - - if (assetJSON == null || assetJSON.isEmpty()) { - String errorMessage = String.format("Asset %s does not exist", assetID); - System.out.println(errorMessage); - throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString()); - } - - Asset asset = genson.deserialize(assetJSON, Asset.class); - - Asset newAsset = new Asset(asset.getAssetID(), asset.getColor(), asset.getSize(), newOwner, asset.getAppraisedValue()); - // Use a Genson to conver the Asset into string, sort it alphabetically and serialize it into a json string - String sortedJson = genson.serialize(newAsset); - stub.putStringState(assetID, sortedJson); - - return asset.getOwner(); - } - - /** - * Retrieves all assets from the ledger. - * - * @param ctx the transaction context - * @return array of assets found on the ledger - */ - @Transaction(intent = Transaction.TYPE.EVALUATE) - public String GetAllAssets(final Context ctx) { - ChaincodeStub stub = ctx.getStub(); - - List queryResults = new ArrayList(); - - // To retrieve all assets from the ledger use getStateByRange with empty startKey & endKey. - // Giving empty startKey & endKey is interpreted as all the keys from beginning to end. - // As another example, if you use startKey = 'asset0', endKey = 'asset9' , - // then getStateByRange will retrieve asset with keys between asset0 (inclusive) and asset9 (exclusive) in lexical order. - QueryResultsIterator results = stub.getStateByRange("", ""); - - for (KeyValue result: results) { - Asset asset = genson.deserialize(result.getStringValue(), Asset.class); - System.out.println(asset); - queryResults.add(asset); - } - - final String response = genson.serialize(queryResults); - - return response; - } -} diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java deleted file mode 100644 index 7da94caa..00000000 --- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -public final class AssetTest { - - @Nested - class Equality { - - @Test - public void isReflexive() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset).isEqualTo(asset); - } - - @Test - public void isSymmetric() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(assetA).isEqualTo(assetB); - assertThat(assetB).isEqualTo(assetA); - } - - @Test - public void isTransitive() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetC = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(assetA).isEqualTo(assetB); - assertThat(assetB).isEqualTo(assetC); - assertThat(assetA).isEqualTo(assetC); - } - - @Test - public void handlesInequality() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - Asset assetB = new Asset("asset2", "Red", 40, "Lady", 200); - - assertThat(assetA).isNotEqualTo(assetB); - } - - @Test - public void handlesOtherObjects() { - Asset assetA = new Asset("asset1", "Blue", 20, "Guy", 100); - String assetB = "not a asset"; - - assertThat(assetA).isNotEqualTo(assetB); - } - - @Test - public void handlesNull() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset).isNotEqualTo(null); - } - } - - @Test - public void toStringIdentifiesAsset() { - Asset asset = new Asset("asset1", "Blue", 20, "Guy", 100); - - assertThat(asset.toString()).isEqualTo("Asset@e04f6c53 [assetID=asset1, color=Blue, size=20, owner=Guy, appraisedValue=100]"); - } -} diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java deleted file mode 100644 index f54f3b1d..00000000 --- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.hyperledger.fabric.samples.assettransfer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.ThrowableAssert.catchThrowable; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.hyperledger.fabric.contract.Context; -import org.hyperledger.fabric.shim.ChaincodeException; -import org.hyperledger.fabric.shim.ChaincodeStub; -import org.hyperledger.fabric.shim.ledger.KeyValue; -import org.hyperledger.fabric.shim.ledger.QueryResultsIterator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; - -public final class AssetTransferTest { - - private static final class MockKeyValue implements KeyValue { - - private final String key; - private final String value; - - MockKeyValue(final String key, final String value) { - super(); - this.key = key; - this.value = value; - } - - @Override - public String getKey() { - return this.key; - } - - @Override - public String getStringValue() { - return this.value; - } - - @Override - public byte[] getValue() { - return this.value.getBytes(); - } - - } - - private static final class MockAssetResultsIterator implements QueryResultsIterator { - - private final List assetList; - - MockAssetResultsIterator() { - super(); - - assetList = new ArrayList(); - - assetList.add(new MockKeyValue("asset1", - "{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }")); - assetList.add(new MockKeyValue("asset2", - "{ \"assetID\": \"asset2\", \"color\": \"red\", \"size\": 5,\"owner\": \"Brad\", \"appraisedValue\": 400 }")); - assetList.add(new MockKeyValue("asset3", - "{ \"assetID\": \"asset3\", \"color\": \"green\", \"size\": 10,\"owner\": \"Jin Soo\", \"appraisedValue\": 500 }")); - assetList.add(new MockKeyValue("asset4", - "{ \"assetID\": \"asset4\", \"color\": \"yellow\", \"size\": 10,\"owner\": \"Max\", \"appraisedValue\": 600 }")); - assetList.add(new MockKeyValue("asset5", - "{ \"assetID\": \"asset5\", \"color\": \"black\", \"size\": 15,\"owner\": \"Adrian\", \"appraisedValue\": 700 }")); - assetList.add(new MockKeyValue("asset6", - "{ \"assetID\": \"asset6\", \"color\": \"white\", \"size\": 15,\"owner\": \"Michel\", \"appraisedValue\": 800 }")); - } - - @Override - public Iterator iterator() { - return assetList.iterator(); - } - - @Override - public void close() throws Exception { - // do nothing - } - - } - - @Test - public void invokeUnknownTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - - Throwable thrown = catchThrowable(() -> { - contract.unknownTransaction(ctx); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Undefined contract method called"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo(null); - - verifyNoInteractions(ctx); - } - - @Nested - class InvokeReadAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - Asset asset = contract.ReadAsset(ctx, "asset1"); - - assertThat(asset).isEqualTo(new Asset("asset1", "blue", 5, "Tomoko", 300)); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.ReadAsset(ctx, "asset1"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Test - void invokeInitLedgerTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - - contract.InitLedger(ctx); - - InOrder inOrder = inOrder(stub); - inOrder.verify(stub).putStringState("asset1", "{\"appraisedValue\":300,\"assetID\":\"asset1\",\"color\":\"blue\",\"owner\":\"Tomoko\",\"size\":5}"); - inOrder.verify(stub).putStringState("asset2", "{\"appraisedValue\":400,\"assetID\":\"asset2\",\"color\":\"red\",\"owner\":\"Brad\",\"size\":5}"); - inOrder.verify(stub).putStringState("asset3", "{\"appraisedValue\":500,\"assetID\":\"asset3\",\"color\":\"green\",\"owner\":\"Jin Soo\",\"size\":10}"); - inOrder.verify(stub).putStringState("asset4", "{\"appraisedValue\":600,\"assetID\":\"asset4\",\"color\":\"yellow\",\"owner\":\"Max\",\"size\":10}"); - inOrder.verify(stub).putStringState("asset5", "{\"appraisedValue\":700,\"assetID\":\"asset5\",\"color\":\"black\",\"owner\":\"Adrian\",\"size\":15}"); - - } - - @Nested - class InvokeCreateAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - Throwable thrown = catchThrowable(() -> { - contract.CreateAsset(ctx, "asset1", "blue", 45, "Siobhán", 60); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 already exists"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_ALREADY_EXISTS".getBytes()); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Asset asset = contract.CreateAsset(ctx, "asset1", "blue", 45, "Siobhán", 60); - - assertThat(asset).isEqualTo(new Asset("asset1", "blue", 45, "Siobhán", 60)); - } - } - - @Test - void invokeGetAllAssetsTransaction() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStateByRange("", "")).thenReturn(new MockAssetResultsIterator()); - - String assets = contract.GetAllAssets(ctx); - - assertThat(assets).isEqualTo("[{\"appraisedValue\":300,\"assetID\":\"asset1\",\"color\":\"blue\",\"owner\":\"Tomoko\",\"size\":5}," - + "{\"appraisedValue\":400,\"assetID\":\"asset2\",\"color\":\"red\",\"owner\":\"Brad\",\"size\":5}," - + "{\"appraisedValue\":500,\"assetID\":\"asset3\",\"color\":\"green\",\"owner\":\"Jin Soo\",\"size\":10}," - + "{\"appraisedValue\":600,\"assetID\":\"asset4\",\"color\":\"yellow\",\"owner\":\"Max\",\"size\":10}," - + "{\"appraisedValue\":700,\"assetID\":\"asset5\",\"color\":\"black\",\"owner\":\"Adrian\",\"size\":15}," - + "{\"appraisedValue\":800,\"assetID\":\"asset6\",\"color\":\"white\",\"owner\":\"Michel\",\"size\":15}]"); - - } - - @Nested - class TransferAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 5, \"owner\": \"Tomoko\", \"appraisedValue\": 300 }"); - - String oldOwner = contract.TransferAsset(ctx, "asset1", "Dr Evil"); - - assertThat(oldOwner).isEqualTo("Tomoko"); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.TransferAsset(ctx, "asset1", "Dr Evil"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Nested - class UpdateAssetTransaction { - - @Test - public void whenAssetExists() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")) - .thenReturn("{ \"assetID\": \"asset1\", \"color\": \"blue\", \"size\": 45, \"owner\": \"Arturo\", \"appraisedValue\": 60 }"); - - Asset asset = contract.UpdateAsset(ctx, "asset1", "pink", 45, "Arturo", 600); - - assertThat(asset).isEqualTo(new Asset("asset1", "pink", 45, "Arturo", 600)); - } - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.TransferAsset(ctx, "asset1", "Alex"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } - - @Nested - class DeleteAssetTransaction { - - @Test - public void whenAssetDoesNotExist() { - AssetTransfer contract = new AssetTransfer(); - Context ctx = mock(Context.class); - ChaincodeStub stub = mock(ChaincodeStub.class); - when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("asset1")).thenReturn(""); - - Throwable thrown = catchThrowable(() -> { - contract.DeleteAsset(ctx, "asset1"); - }); - - assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Asset asset1 does not exist"); - assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes()); - } - } -}