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.

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`

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 7, 2024
1 parent 21fd747 commit 079848e
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 127 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
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
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Account } from "web3-core";
import { v4 as uuidv4 } from "uuid";
import { DiscoveryOptions } from "fabric-network";
import {
Logger,
Checks,
Expand All @@ -13,38 +14,31 @@ import {
PluginLedgerConnectorQuorum,
Web3SigningCredentialType,
} from "@hyperledger/cactus-plugin-ledger-connector-quorum";
import { IPluginKeychain } from "@hyperledger/cactus-core-api";
import { FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1 } from "@hyperledger/cactus-test-tooling";
import { FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2 } from "@hyperledger/cactus-test-tooling";
import {
BesuTestLedger,
DEFAULT_FABRIC_2_AIO_IMAGE_NAME,
FABRIC_25_LTS_AIO_FABRIC_VERSION,
FABRIC_25_LTS_AIO_IMAGE_VERSION,
FabricTestLedgerV1,
QuorumTestLedger,
} from "@hyperledger/cactus-test-tooling";

import BambooHarvestRepositoryJSON from "../../json/generated/BambooHarvestRepository.json";
import BookshelfRepositoryJSON from "../../json/generated/BookshelfRepository.json";
import {
IEthContractDeployment,
ISupplyChainContractDeploymentInfo,
IFabricContractDeployment,
// OrgEnv,
} from "@hyperledger/cactus-example-supply-chain-business-logic-plugin";
import {
PluginLedgerConnectorFabric,
DefaultEventHandlerStrategy,
} from "@hyperledger/cactus-plugin-ledger-connector-fabric";
import { DiscoveryOptions } from "fabric-network";
import { SHIPMENT_CONTRACT_GO_SOURCE } from "../../go/shipment";
import { IPluginKeychain } from "@hyperledger/cactus-core-api";

export const org1Env = {
CORE_PEER_LOCALMSPID: "Org1MSP",
CORE_PEER_ADDRESS: "peer0.org1.example.com:7051",
CORE_PEER_MSPCONFIGPATH:
"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp",
CORE_PEER_TLS_ROOTCERT_FILE:
"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt",
ORDERER_TLS_ROOTCERT_FILE:
"/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem",
};
import BambooHarvestRepositoryJSON from "../../json/generated/BambooHarvestRepository.json";
import BookshelfRepositoryJSON from "../../json/generated/BookshelfRepository.json";
import { SHIPMENT_CONTRACT_GO_SOURCE } from "../../go/shipment";
import { SHIPMENT_GOLANG_CONTRACT_PINNED_DEPENDENCIES } from "./shipment-golang-contract-pinned-dependencies";

export interface ISupplyChainAppDummyInfrastructureOptions {
logLevel?: LogLevelDesc;
Expand Down Expand Up @@ -113,8 +107,10 @@ export class SupplyChainAppDummyInfrastructure {
});
this.fabric = new FabricTestLedgerV1({
publishAllPorts: true,
imageName: "ghcr.io/hyperledger/cactus-fabric-all-in-one",
imageName: DEFAULT_FABRIC_2_AIO_IMAGE_NAME,
imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION,
logLevel: level,
envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]),
emitContainerLogs: true,
});

Expand Down Expand Up @@ -292,16 +288,20 @@ export class SupplyChainAppDummyInfrastructure {
sshConfig: sshConfig,
logLevel: this.options.logLevel || "INFO",
connectionProfile: connectionProfile,
cliContainerEnv: org1Env,
cliContainerEnv: FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1,
discoveryOptions: discoveryOptions,
eventHandlerOptions: {
strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx,
},
});

const res = await connector.deployContractGoSourceV1({
tlsRootCertFiles: org1Env.CORE_PEER_TLS_ROOTCERT_FILE as string,
targetPeerAddresses: [org1Env.CORE_PEER_ADDRESS as string],
tlsRootCertFiles:
FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1.CORE_PEER_TLS_ROOTCERT_FILE,
targetPeerAddresses: [
FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1.CORE_PEER_ADDRESS,
FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2.CORE_PEER_ADDRESS,
],
policyDslSource: "OR('Org1MSP.member','Org2MSP.member')",
channelId: "mychannel",
chainCodeVersion: "1.0.0",
Expand All @@ -311,29 +311,11 @@ export class SupplyChainAppDummyInfrastructure {
filename: "shipment.go",
},
moduleName: "shipment",
targetOrganizations: [org1Env],
pinnedDeps: [
"github.com/Knetic/[email protected]+incompatible",
"github.com/Shopify/[email protected]",
"github.com/fsouza/[email protected]",
"github.com/grpc-ecosystem/[email protected]",
"github.com/hashicorp/[email protected]",
"github.com/hyperledger/[email protected]",
"github.com/hyperledger/[email protected]",
"github.com/miekg/[email protected]",
"github.com/mitchellh/[email protected]",
"github.com/onsi/[email protected]",
"github.com/onsi/[email protected]",
"github.com/op/[email protected]",
"github.com/pkg/[email protected]",
"github.com/spf13/[email protected]",
"github.com/stretchr/[email protected]",
"github.com/sykesm/[email protected]",
"go.uber.org/[email protected]",
"golang.org/x/[email protected]",
"golang.org/x/[email protected]",
"google.golang.org/[email protected]",
targetOrganizations: [
FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1,
FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2,
],
pinnedDeps: SHIPMENT_GOLANG_CONTRACT_PINNED_DEPENDENCIES,
});
this.log.debug("Supply chain app Fabric contract deployment result:", res);

Expand Down
Loading

0 comments on commit 079848e

Please sign in to comment.