Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions docs/Troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Troubleshooting Guide: Canis Major Integration Tests

## Common Issue: Build Failure During Integration Tests

This guide addresses the most common issue encountered with the Canis Major adapter: build failure when running integration tests. If you experience a build failure while executing the `mvn clean test` command, follow these steps to resolve the issue.

### Solution: Updating 'NGSI Address' environment variable

1. **Check the IP Address of the Canis Major Container**

Run the following command to obtain the IP address of the Canis Major container:

```bash
docker inspect -f '{{range .NetworkSettings.Networks}} \
{{.IPAddress}}{{end}}'<canis_major_container_name_or_id>
```

Replace `<canis_major_container_name_or_id>` with the actual name or ID of your Canis Major container.

2. **Run Tests with Updated NGSI Address**

Navigate to the `/it` folder and execute the following command:

```bash
cd it
NGSI_ADDRESS=<ip_address_of_canis_major_container>:4000 mvn clean test
```

Replace `<ip_address_of_canis_major_container>` with the IP address obtained in step 1.

### Command Breakdown

The command used in step 2 consists of two main parts:

1. **Environment Variable Assignment**:
`NGSI_ADDRESS=<ip_address_of_canis_major_container>:4000`
- Sets the `NGSI_ADDRESS` environment variable.
- Specifies the address of the ETSI NGSI-LD API of the Canis Major.

2. **Maven Command**:
`mvn clean test`
- `clean`: Deletes the `target` directory, ensuring a clean build environment.
- `test`: Compiles the source code and runs all unit tests in the project.

By using this approach, you ensure that the integration tests are executed against the correct Canis Major endpoint, which should resolve the build failure issue.

If you continue to experience problems after following the provided steps, please open an issue in the GitHub repository with detailed information about the error you are encountering.

## Common Issue: Problem to execute the integration test again.

If you try to execute twice the integration tests, you will receive an error message like the following:

```bash
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running it.RunCucumberTest

Scenario: A test-store, created at orion-ld, is available through CanisMajor.
# it/store_transactions_on_entities_in_canis_major.feature:4
Given CanisMajor is running and available for requests.
# it.StepDefinitions.setup_canis_major_in_docker()
And Vault is configured as a signing endpoint.
# it.StepDefinitions.configure_ethereum_plugin_vault()
And Franzi is registered in vault.
# it.StepDefinitions.register_franzi_in_vault()
And Mira is registered in vault.
# it.StepDefinitions.register_mira_in_vault()
When Franzi creates the test-store.
# it.StepDefinitions.create_test_store()
Then Only one transaction should be persisted for the entity.
# it.StepDefinitions.assert_only_one_transaction()
org.awaitility.core.ConditionTimeoutException: Condition with it.StepDefinitions was not
fulfilled within 15 seconds.
at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:165)
at org.awaitility.core.CallableCondition.await(CallableCondition.java:78)
at org.awaitility.core.CallableCondition.await(CallableCondition.java:26)
at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:895)
at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:864)
at it.StepDefinitions.assert_only_one_transaction(StepDefinitions.java:559)
at ✽.Only one transaction should be persisted for the entity.
(classpath:it/store_transactions_on_entities_in_canis_major.feature:10)
And The transaction to persist test-store can be read through CanisMajor.
# it.StepDefinitions.get_test_store()
```

This is produced by the intent to save again the information of the users' credentials in the Vault.

### Solution 1: Clean the docker compose

> [!NOTE]
> This is the preferred non-invasive solution

For a docker compose clean, execute the following command:
```shell
sudo docker compose -f docker-compose-env.yaml -f docker-compose-java.yaml down -v
```
This command deletes all containers, networks, and volumes created on the corresponding compose. It is the normal way to remove resources in a compose.


### Solution 2: Remove all running containers and resources

> [!WARNING]
> The following clean up will remove multiple containers **including others not related to the deployment of Canis Major.**

In the case that you are experiencing a conflict and you want to remove all the containers, volumes, and networks you have created in your machine,
follow these commands for a complete Docker cleanup of all resources.

- Stop all running containers
```shell
sudo docker stop $(sudo docker ps -aq)
```
- Remove all containers
```shell
sudo docker rm $(sudo docker ps -aq)
```
- Remove all volumes
```shell
sudo docker volume rm $(sudo docker volume ls -q)
```
- Remove all custom networks
```shell
sudo docker network prune
```

> [!TIP]
> - You can add `-f` flag to skip confirmation prompts.
> - Root privileges `sudo` may be required depending on your Docker setup.
230 changes: 230 additions & 0 deletions docs/canis-major-integration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
# Canis Major test

Canis Major serves as a blockchain adaptor within the FIWARE ecosystem, providing secure data persistence across blockchain networks and the Context Broker. The workflow is straightforward:
- Clients submit transactions containing payload data and wallet credentials.
- Once validated, the data is stored in an ETSI Broker (e.g., Orion-LD Broker) and simultaneously processed into a Merkle tree structure for blockchain integration.
- The system then signs the transaction using the provided wallet credentials and submits it to an Oketh-compatible blockchain.

## Integration tests
Let's explore the practical implementation through a series of test commands. First, it is needed to execute the integration tests, by running the following commands:

```shell
cd it
docker-compose -f docker-compose/docker-compose-env.yaml -f docker-compose/docker-compose-java.yaml up
```

```shell
NGXI_ADDRESS=localhost:4000 mvn clean test
```

## Entity creation
After running the integration tests, create an entity by sending this POST request to Canis Major:

```shell
curl -iX POST 'http://localhost:4000/ngsi-ld/v1/entities/' \
--H 'Link: <https://raw.githubusercontent.com/smart-data-models/\
dataModel.DistributedLedgerTech/master/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context";\
type="application/ld+json"' \
--H 'Wallet-Type: vault' \
--H 'Wallet-Token: vault-plaintext-root-token' \
--H 'Wallet-Address: http://vault:8200/v1/ethereum/accounts/mira' \
--H 'Content-Type: application/json' \
--H 'Accept: application/json' \
--H 'NGSILD-TENANT: orion' \
--data '{
"id": "urn:ngsi-ld:Building:warehouse001",
"type": "Building",
"category": {
"type": "Property",
"value": ["warehouse"]
},
"address": {
"type": "Property",
"value": {
"streetAddress": "Alexanderplatz 2",
"addressRegion": "Berlin",
"addressLocality": "Mitte",
"postalCode": "10178"
}
}
}'
```

### Wallet HTTP Headers
The headers included in the HTTP request are crucial for interacting with the blockchain. Here's a breakdown of each component and its significance:

#### Wallet-Type
This header specifies the type of wallet service being used, in this case, `vault`. By specifying the wallet type, the system can ensure that it uses the appropriate methods and protocols for that specific wallet service.

#### Wallet-Token
This header provides an authentication token for accessing the vault service. This token ensures that only authorized users can access the wallet's functionalities, such as retrieving private keys or signing transactions. Without proper authentication, the system would be vulnerable to unauthorized access.

#### Wallet-Address
This header points to the specific Ethereum account associated with the wallet. The wallet address is a unique identifier for an Ethereum account. It is used to send and receive transactions on the Ethereum blockchain. By specifying the wallet address, the system knows which account to interact with for operations such as sending tokens, signing transactions, or querying account balances.

### Link Header
The Link header specifies the JSON-LD @context to be used, defining the semantic meaning of the terms used in the entity. The used link header contains three main parts:
- The URL of the context file
- The relationship type `rel="http://www.w3.org/ns/json-ld#context"`
- The content type `type="application/ld+json"`

This context helps in standardizing the data model and ensures interoperability and in our case, it's referencing a context file from the Smart Data Models initiative for Building entities. The Link Header used here is an HTTP Link Header using the `http://www.w3.org/ns/json-ld#context` link relation pointing to the `@context` file defining the data model for [Building](https://smart-data-models.github.io/dataModel.Building/context.jsonld).

### NGSILD-TENANT Header
This header is used for multi-tenancy support in NGSI-LD implementations. In our case, "orion" is the tenant identifier. However, different tenants can have their own isolated set of entities, even if they have the same entity IDs enabling multiple organizations to use the same NGSI-LD broker without data interference.

### Content Headers
- `Content-Type`: Declares the request body format as JSON
- `Accept`: Indicates the expected response format as JSON

## Retrieve the entity types in the Context broker
To retrieve the available entity types in the context broker run the following command:

```shell
curl -iX GET 'http://localhost:1026/ngsi-ld/v1/types' \
-H 'Link: <https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'NGSILD-Tenant: orion'
```
The command returns the following response, demonstrating the available entity types in the Context Broker:
```json
"@context": "https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld",
"id": "urn:ngsi-ld:EntityTypeList:d77ccfa0-b3cd-11ef-ae1b-0242ac120005",
"type": "EntityTypeList",
"typeList": ["DLTtxReceipt"]
```
The `@context` is using a definition on smart data models for a `DLTtxReceipt` and the `NGSILD-Tenant` is defined in the start-up of the tests.

## Retrieve data from Canis Major
To retrieve detailed receipt information for a specific building entity from the Canis Major, use the following HTTP request:

```shell
curl -iX GET 'http://localhost:4000/ngsi-ld/v1/entities/urn:ngsi-ld:Building:warehouse001' \
-H 'Link: <https://raw.githubusercontent.com/smart-data-models/dataModel.Building/master/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json'
```

The output will be similar to following response:

```json
{
"blockHash": "0x619433204be327dda0d4722482e44310d2f3807e1a23b1fc097ca809f7afb421",
"blockNumber": 193,
"blockNumberRaw": "0xc1",
"cumulativeGasUsed": 23866,
"cumulativeGasUsedRaw": "0x5d3a",
"from": "0xd9fe663797b75d0b3897d55d35e0b4e72307a63f",
"gasUsed": 23866,
"gasUsedRaw": "0x5d3a",
"logs": [
{
"address": "0x476059cd57800db8eb88f67c2aa38a6fcf8251e0",
"blockHash": "0x619433204be327dda0d4722482e44310d2f3807e1a23b1fc097ca809f7afb421",
"blockNumber": 193,
"blockNumberRaw": "0xc1",
"data": "0x",
"logIndex": 0,
"logIndexRaw": "0x0",
"removed": false,
"topics": [
"0xa3865c00e01495fc2b86502cae36a4edb139f748682e7d80725a3d6571a482fa",
"0xf85c55023889d6ec0b723c8220471171435040e275059f8e222dfa57a50f0dd5",
"0x33868c71f7186ea974685b553d8eee61eb1e95e0a2c70ed54fcd13db67920f74"
],
"transactionHash": "0x83f05282a30f77dcfe52ca029b10ba80aac5dad5cc46f5dc437b79e860e4dd65",
"transactionIndex": 0,
"transactionIndexRaw": "0x0",
"type": "mined"
}
],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000020000000000000008000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000004000000000000000000020000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000008000000000000000000000420000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"statusOK": true,
"to": "0x476059cd57800db8eb88f67c2aa38a6fcf8251e0",
"transactionHash": "0x83f05282a30f77dcfe52ca029b10ba80aac5dad5cc46f5dc437b79e860e4dd65",
"transactionIndexRaw": "0x0"
}
```

The JSON structure shows a blockchain transaction receipt with the following details:
### Transaction Information
- Block Number: 193 (0xc1)
- Transaction Status: Successful (statusOK: true)
- Transaction Hash: 0x83f05282a30f77dcfe52ca029b10ba80aac5dad5cc46f5dc437b79e860e4dd65
### Transaction Participants
- From Address: 0xd9fe663797b75d0b3897d55d35e0b4e72307a63f
- To Address: 0x476059cd57800db8eb88f67c2aa38a6fcf8251e0

## Retrieve data from the context broker
To retrieve specific DLT transaction receipts from the the context broker, we'll use an NGSI-LD query that filters entities by type and property values. The query targets entities of type DLTtxReceipt and filters them based on the refEntity property matching the Building entity "urn:ngsi-ld:Building:warehouse001". The attrs=TxReceipts parameter in the NGSI-LD query acts as a data filter to limit the response to only include the TxReceipts property, excluding all other properties of the entity and reducing response payload size.

```shell
curl -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/?type=DLTtxReceipt&q=refEntity%3D%3D%22urn%3Angsi-ld%3ABuilding%3Awarehouse001%22&attrs=TxReceipts' \
-H 'Link: <https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'NGSILD-Tenant: orion'
```

The output will be similar to the following json response:

```json
{
"@context": "https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld",
"id": "urn:ngsi-ld:dlttxreceipt:0xa46d2e3b190d36fbb8af5d0a1c212d8036cf007e6ec4d1309904e052d25e5499",
"type": "DLTtxReceipt",
"TxReceipts": {
"type": "Property",
"value": {
"blockHash": "0x2022f801a1c094bd3a893ac6f3087c17bb9c673a6b5663f353eded030e1e7161",
"blockNumber": 192,
"blockNumberRaw": "0xc0",
"cumulativeGasUsed": 23866,
"cumulativeGasUsedRaw": "0x5d3a",
"from": "0x34e5b3f990e55d0651b35c817bafb89d2877cb95",
"gasUsed": 23866,
"gasUsedRaw": "0x5d3a",
"logs": [
{
"address": "0x476059cd57800db8eb88f67c2aa38a6fcf8251e0",
"blockHash": "0x2022f801a1c094bd3a893ac6f3087c17bb9c673a6b5663f353eded030e1e7161",
"blockNumber": 192,
"blockNumberRaw": "0xc0",
"data": "0x",
"logIndex": 0,
"logIndexRaw": "0x0",
"removed": false,
"topics": [
"0xa3865c00e01495fc2b86502cae36a4edb139f748682e7d80725a3d6571a482fa",
"0xf85c55023889d6ec0b723c8220471171435040e275059f8e222dfa57a50f0dd5",
"0xefc7a4d4c2393e9b62ac4b93b7d199c71e0bb103fdb00fc1b37d7949ad886ddd"
],
"transactionHash": "0xa46d2e3b190d36fbb8af5d0a1c212d8036cf007e6ec4d1309904e052d25e5499",
"transactionIndex": 0,
"transactionIndexRaw": "0x0",
"type": "mined"
}
],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000020000000000000008000200000000000000000000000000000000000000000000000100000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000008000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000200000000000000000000000000000000",
"status": "0x1",
"statusOK": true,
"to": "0x476059cd57800db8eb88f67c2aa38a6fcf8251e0",
"transactionHash": "0xa46d2e3b190d36fbb8af5d0a1c212d8036cf007e6ec4d1309904e052d25e5499",
"transactionIndex": 0,
"transactionIndexRaw": "0x0"
}
}
}
```

This JSON response shows a `DLTtxReceipt` (Distributed Ledger Technology Transaction Receipt based on the following [data model](https://github.com/smart-data-models/dataModel.DistributedLedgerTec)) entity in NGSI-LD format.

### Transaction Details

- Entity ID: `urn:ngsi-ld:dlttxreceipt:0xa46d2e3b190d36fbb8af5d0a1c212d8036cf007e6ec4d1309904e052d25e5499`
- Block Number: 192 (0xc0)
- Transaction Status: Successful (statusOK: true)
- Block Hash: `0x2022f801a1c094bd3a893ac6f3087c17bb9c673a6b5663f353eded030e1e7161`
- Transaction Hash: `0xa46d2e3b190d36fbb8af5d0a1c212d8036cf007e6ec4d1309904e052d25e5499`

### Transaction Participants
- From Address: `0x34e5b3f990e55d0651b35c817bafb89d2877cb95`
- To Address: `0x476059cd57800db8eb88f67c2aa38a6fcf8251e0`

Loading
Loading