Skip to content

Commit

Permalink
docs(examples/supply-chain): fix test infra - migrate to Fabric v2.5.6
Browse files Browse the repository at this point in the history
The supply chain app's build and execution scripts should finally be
working after this and also be much more stable than before due to the
flakiness of the Fabric V1 test ledger not being an issue anymore.

The container image is now published as:

`ghcr.io/hyperledger/cactus-example-supply-chain-app:2024-03-08--pr-3059-1`

1.The new contract is compiled with go v1.20 and therefore has to have
the contract method names capitalized insted of camelCase, otherwise
the methods are not possible to be exported and the contract deployment
fails even if everything else is correct.
2. The supply chain app now uses the newest edition of the Fabric v2 AIO
test ledger container image which uses Fabric v2.5.6 (current LTS at the
time of this writing).
3. The shipment contract's source code has been migrated to Fabric v2
meaning that instead of a stub object we get a context object for each
method's first parameter and then the stub can be acquired from that
context object.
4. The method arguments no longer need to be passed around as an array
of strings and instead the contract method's input arguments are first-class
go method parameters.
5. Re-enabled a test case that was being skipped until now due to flakiness:
...`src/test/typescript/integration/supply-chain-backend-api-calls.test.ts`

The supply chain app container image was built with this command:
```sh
DOCKER_BUILDKIT=1 docker build \
  --build-arg="NPM_PKG_VERSION=2.0.0-2945-supply-chain-app-build-failed.241+b2c306ea0" \
  -f ./examples/cactus-example-supply-chain-backend/Dockerfile \
  . \
  -t scaeb
```

The NPM_PKG_VERSION build arg is important because the image defaults to
"latest" which at the moment is packages that do not contain the fixes
made by this commit, so re-building the image without that extra arg
will not work until we issue the next official non-canary release.

Depends on hyperledger-cacti#3058
Depends on hyperledger-cacti#3054

Fixes hyperledger-cacti#2945
Fixes hyperledger-cacti#2969
Fixes hyperledger-cacti#1899
Fixes hyperledger-cacti#1521
Fixes hyperledger-cacti#1518

Signed-off-by: Peter Somogyvari <[email protected]>
  • Loading branch information
petermetz committed Mar 8, 2024
1 parent dc1f407 commit 18b228d
Show file tree
Hide file tree
Showing 15 changed files with 293 additions and 152 deletions.
12 changes: 11 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"COUCHDBCONFIG",
"Creds",
"data",
"davecgh",
"dclm",
"DHTAPI",
"dids",
Expand All @@ -61,9 +62,12 @@
"fidm",
"flowdb",
"fsouza",
"genproto",
"GETHKEYCHAINPASSWORD",
"ghcr",
"gobuffalo",
"gopath",
"gopkg",
"goquorum",
"grpc",
"grpcs",
Expand All @@ -87,6 +91,7 @@
"Irohad",
"isready",
"jboss",
"joho",
"JORDI",
"jsrsa",
"jsrsasign",
Expand All @@ -101,6 +106,7 @@
"leveldb",
"lmify",
"LOCALMSPID",
"mailru",
"miekg",
"mitchellh",
"MSPCONFIGPATH",
Expand Down Expand Up @@ -129,14 +135,17 @@
"Orgs",
"ossp",
"outsh",
"Panicf",
"parameterizable",
"pmezard",
"Postgres",
"proto",
"protobuf",
"protoc",
"protos",
"qscc",
"recoverupdateackmessage",
"rogpeppe",
"RUSTC",
"Rwset",
"satp",
Expand Down Expand Up @@ -171,7 +180,8 @@
"vuln",
"wasm",
"WSPROVIDER",
"Xdai"
"Xdai",
"xeipuuv"
],
"dictionaries": [
"typescript,node,npm,go,rust"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,8 @@ jobs:
cactus-example-supply-chain-backend:
continue-on-error: false
env:
DUMP_DISK_USAGE_INFO_DISABLED: false
FREE_UP_GITHUB_RUNNER_DISK_SPACE_DISABLED: false
FULL_BUILD_DISABLED: true
JEST_TEST_PATTERN: examples/cactus-example-supply-chain-backend/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts
JEST_TEST_RUNNER_DISABLED: false
Expand Down
2 changes: 1 addition & 1 deletion README-cactus.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ As blockchain technology proliferates, blockchain integration will become an inc
-p 4000:4000 \
-p 4100:4100 \
-p 4200:4200 \
ghcr.io/hyperledger/cactus-example-supply-chain-app:2022-04-05--feat-1579
ghcr.io/hyperledger/cactus-example-supply-chain-app:2024-03-08--pr-3059-1
```
3. Wait for the output to show the message `INFO (api-server): Cactus Cockpit reachable http://0.0.0.0:3200`
4. Token generated by the application is displayed below
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/cactus/examples/supply-chain-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Usage
\-p 4000:4000 \\
\-p 4100:4100 \\
\-p 4200:4200 \\
ghcr.io/hyperledger/cactus-example-supply-chain-app:2022-04-05--feat-1579
ghcr.io/hyperledger/cactus-example-supply-chain-app:2024-03-08--pr-3059-1

2. Observe the example application pulling up in the logs

Expand Down
64 changes: 43 additions & 21 deletions examples/cactus-example-supply-chain-backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,44 +1,66 @@
FROM cruizba/ubuntu-dind:19.03.11 as runner
FROM cruizba/ubuntu-dind:jammy-24.0.7-compose-2.24.0 as runner

USER root
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update
RUN apt -y upgrade
RUN apt-get update && \
apt -y upgrade

# Need curl for healthchecks
RUN apt-get -y install --no-install-recommends curl

# The file binary is used to inspect exectubles when debugging container image issues
RUN apt-get -y install --no-install-recommends file


RUN apt-get -y install --no-install-recommends ca-certificates
RUN apt-get -y install --no-install-recommends tzdata
RUN apt-get -y install --no-install-recommends -y \
curl \
file \
ca-certificates \
tzdata \
git \
jq

ARG APP=/usr/src/app/

ENV TZ=Etc/UTC
ENV APP_USER=appuser

RUN useradd -m ${APP_USER}
RUN usermod -a -G ${APP_USER} ${APP_USER}
RUN mkdir -p ${APP}
RUN useradd -m ${APP_USER} && \
usermod -a -G ${APP_USER} ${APP_USER} && \
mkdir -p ${APP}

RUN mkdir -p "${APP}/log/"
RUN chown -R $APP_USER:$APP_USER "${APP}/"
RUN mkdir -p "${APP}/log/" && \
chown -R $APP_USER:$APP_USER "${APP}/"

# TODO: Can we hack it together so that the whole thing works rootless?
USER ${APP_USER}
WORKDIR ${APP}

# COPY --chown=${APP_USER}:${APP_USER} examples/cactus-example-supply-chain-backend/tpl.package.json /usr/src/app/package.json

# RUN touch /usr/src/app/package.json

SHELL ["/bin/bash", "--login", "-i", "-c"]
# Installing Node Version Manager (nvm)
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
ARG NPM_PKG_VERSION=latest
# Installing NodeJS via Node Version Manager (nvm)
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
ARG NPM_PKG_VERSION="latest"
RUN source ~/.bashrc && \
nvm install 16.15.1 && \
npm install -g yarn && \
yarn add @hyperledger/cactus-example-supply-chain-backend@${NPM_PKG_VERSION} --ignore-engines --production
nvm install 18.18.2 && \
npm i -g corepack && corepack enable && corepack prepare [email protected] --activate && \
yarn init --yes --private && \
yarn config set nodeLinker node-modules && \
yarn add @hyperledger/cactus-example-supply-chain-backend@${NPM_PKG_VERSION} --exact && \
yarn add [email protected] --exact && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-test-tooling": "\($NPM_PKG_VERSION)" }' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-api-client": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-cmd-api-server": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-common": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-core": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-core-api": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-example-supply-chain-business-logic-plugin": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-example-supply-chain-frontend": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-plugin-consortium-manual": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-plugin-keychain-memory": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-plugin-ledger-connector-besu": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-plugin-ledger-connector-fabric": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
cat /usr/src/app/package.json | jq --arg NPM_PKG_VERSION ${NPM_PKG_VERSION} '.resolutions += { "@hyperledger/cactus-plugin-ledger-connector-quorum": "\($NPM_PKG_VERSION)" } ' | tee /usr/src/app/package.json && \
yarn install

SHELL ["/bin/bash", "--login", "-c"]

Expand Down
2 changes: 1 addition & 1 deletion examples/cactus-example-supply-chain-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
-p 4000:4000 \
-p 4100:4100 \
-p 4200:4200 \
ghcr.io/hyperledger/cactus-example-supply-chain-app:2022-04-05--feat-1579
ghcr.io/hyperledger/cactus-example-supply-chain-app:2024-03-08--pr-3059-1
```
2. Observe the example application pulling up in the logs
1. the test ledger containers,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
export const SHIPMENT_CONTRACT_GO_SOURCE = `package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"strings"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
func isNonBlank(str *string) bool {
if str == nil {
return false
}
return strings.TrimSpace(*str) != ""
}
type ShipmentChaincode struct {
contractapi.Contract
}
type Shipment struct {
Expand All @@ -18,85 +26,79 @@ type Shipment struct {
}
func main() {
if err := shim.Start(new(ShipmentChaincode)); err != nil {
fmt.Printf("Error starting ShipmentChaincode chaincode: %s", err)
shipmentChaincode, err := contractapi.NewChaincode(&ShipmentChaincode{})
if err != nil {
log.Panicf("Error creating supply-chain shipment chaincode: %v", err)
}
}
func (t *ShipmentChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
if err := shipmentChaincode.Start(); err != nil {
log.Panicf("Error starting supply-chain shipment chaincode: %v", err)
}
}
func (t *ShipmentChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
fn, args := stub.GetFunctionAndParameters()
// InitLedger adds a base set of assets to the ledger
func (t *ShipmentChaincode) InitLedger(ctx contractapi.TransactionContextInterface) error {
if fn == "insertShipment" {
return t.insertShipment(stub, args)
} else if fn == "getListShipment" {
return t.getListShipment(stub, args)
}
return shim.Error("Unknown function")
log.Println("InitLedger ran for supply-chain shipment chaincode. %v", t)
return nil
}
func (t *ShipmentChaincode) insertShipment(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("Incorrect arguments. Expecting an id and a bookshelfId")
func (t *ShipmentChaincode) InsertShipment(ctx contractapi.TransactionContextInterface, newShipmentId string, bookshelfId string) (string, error) {
if !isNonBlank(&newShipmentId) {
return "E_NEW_SHIPMENT_ID_BLANK", fmt.Errorf("Incorrect arguments. Expecting a shipment ID as a non-blank string.")
}
if !isNonBlank(&bookshelfId) {
return "E_NEW_BOOKSHELF_ID_BLANK", fmt.Errorf("Incorrect arguments. Expecting a bookshelf ID as a non-blank string.")
}
var newShipment Shipment
newShipment.Id = args[0]
newShipment.BookshelfId = args[1]
newShipment.Id = newShipmentId
newShipment.BookshelfId = bookshelfId
newShipmentJSON, err := json.Marshal(newShipment)
if err != nil {
return shim.Error(err.Error())
return "OP_FAILED", fmt.Errorf("Failed to JSON marshal new shipment data: %v", err)
}
err2 := stub.PutState(args[0], newShipmentJSON)
stub := ctx.GetStub()
err2 := stub.PutState(newShipmentId, newShipmentJSON)
if err2 != nil {
return shim.Error("Failed to insert shipment:" + args[0] + err2.Error())
return "E_PUT_STATE_FAIL", fmt.Errorf("Failed to insert new shipment to ledger state: %v --- %v", newShipmentJSON, err2)
}
return shim.Success([]byte(args[0]))
return newShipmentId, nil
}
func (t *ShipmentChaincode) getListShipment(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 0 {
return shim.Error("Incorrect arguments. No arguments expected")
}
bookmark := ""
func (t *ShipmentChaincode) GetListShipment(ctx contractapi.TransactionContextInterface) ([]Shipment, error) {
resultsIterator, _, err := stub.GetStateByRangeWithPagination("", "", 25, bookmark)
stub := ctx.GetStub()
resultsIterator, _, err := stub.GetStateByRangeWithPagination("", "", 25, "")
if err != nil {
return shim.Error("Error in getListShipment: " + err.Error())
return nil, fmt.Errorf("Error in GetListShipment: %v", err)
}
defer resultsIterator.Close()
var listShipment []Shipment
var shipments []Shipment
for resultsIterator.HasNext() {
var buffer bytes.Buffer
var aux Shipment
response, err := resultsIterator.Next()
if err != nil {
return shim.Error("Error in iterator: " + err.Error())
return nil, fmt.Errorf("Error in shipment result iterator: %v", err)
}
buffer.WriteString(string(response.Value))
_ = json.Unmarshal(buffer.Bytes(), &aux)
listShipment = append(listShipment, aux)
}
var aux Shipment
if err := json.Unmarshal(response.Value, &aux); err != nil {
return nil, fmt.Errorf("Error un-marshalling shipment: %v", err)
}
jsonResponse, err := json.Marshal(listShipment)
if err != nil {
return shim.Error("Error get result: " + err.Error())
shipments = append(shipments, aux)
}
return shim.Success(jsonResponse)
}
`;
return shipments, nil
}`;

const exportSourceToFs = async () => {
const path = await import("path");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* These are the pinned dependencies used to build the go source code that is
* located in the file at:
* examples/cactus-example-supply-chain-backend/src/main/go/shipment.ts
*/
export const SHIPMENT_GOLANG_CONTRACT_PINNED_DEPENDENCIES = [
"github.com/hyperledger/[email protected]",
"github.com/hyperledger/[email protected]",
"github.com/hyperledger/[email protected]",
"github.com/hyperledger/fabric-samples/asset-transfer-private-data/[email protected]",
"github.com/stretchr/[email protected]",
"google.golang.org/[email protected]",
"github.com/davecgh/[email protected]", // indirect
"github.com/go-openapi/[email protected]", // indirect
"github.com/go-openapi/[email protected]", // indirect
"github.com/go-openapi/[email protected]", // indirect
"github.com/go-openapi/[email protected]", // indirect
"github.com/gobuffalo/[email protected]", // indirect
"github.com/gobuffalo/[email protected]", // indirect
"github.com/gobuffalo/[email protected]", // indirect
"github.com/golang/[email protected]", // indirect
"github.com/joho/[email protected]", // indirect
"github.com/josharian/[email protected]", // indirect
"github.com/mailru/[email protected]", // indirect
"github.com/pmezard/[email protected]", // indirect
"github.com/rogpeppe/[email protected]", // indirect
"github.com/xeipuuv/[email protected]", // indirect
"github.com/xeipuuv/[email protected]", // indirect
"github.com/xeipuuv/[email protected]", // indirect
"golang.org/x/[email protected]", // indirect
"golang.org/x/[email protected]", // indirect
"golang.org/x/[email protected]", // indirect
"golang.org/x/[email protected]", // indirect
"google.golang.org/genproto/googleapis/[email protected]", // indirect
"google.golang.org/[email protected]", // indirect
"gopkg.in/[email protected]", // indirect
];
Loading

0 comments on commit 18b228d

Please sign in to comment.