Skip to content

Commit

Permalink
feat(cacti): consortium get node by capability
Browse files Browse the repository at this point in the history
Signed-off-by: eduv09 <eduardovasques10@tecnico.ulisboa.pt>
  • Loading branch information
eduv09 committed Jun 6, 2024
1 parent 3a0ea78 commit c081da4
Show file tree
Hide file tree
Showing 10 changed files with 487 additions and 9 deletions.
12 changes: 10 additions & 2 deletions packages/cactus-api-client/src/main/typescript/api-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Checks, IAsyncProvider, Objects } from "@hyperledger/cactus-common";

import { ConsortiumDatabase, Ledger } from "@hyperledger/cactus-core-api";
import {
Capability,
ConsortiumDatabase,
Ledger,
} from "@hyperledger/cactus-core-api";

import { ConsortiumRepository } from "@hyperledger/cactus-core";
import { DefaultApi as ApiConsortium } from "@hyperledger/cactus-plugin-consortium-manual";
Expand Down Expand Up @@ -83,6 +87,8 @@ export class ApiClient extends BaseAPI {
ledgerOrId: string | Ledger,
ctor: new (configuration?: Configuration) => T,
ctorArgs: Record<string, unknown>,
consortiumDbProvider?: IAsyncProvider<ConsortiumDatabase>,
capabilities?: Capability[],
): Promise<ApiClient & T>;
/**
* Constructs a new `ApiClient` object that is tied to whichever Cactus node
Expand All @@ -100,12 +106,14 @@ export class ApiClient extends BaseAPI {
* @param consortiumDbProvider The provider that can be used to retrieve the
* consortium metadata at runtime for the purposes of looking up ledgers by
* the provided `ledgerId` parameter.
* @param capabilities The capabilities or plugins we want the nodes to have.
*/
public async ofLedger<T>(
ledgerOrId: string | Ledger,
ctor: new (configuration?: Configuration) => T,
ctorArgs: Record<string, unknown>,
consortiumDbProvider?: IAsyncProvider<ConsortiumDatabase>,
capabilities?: Capability[],
): Promise<ApiClient & T> {
const fnTags = "ApiClient#forLedgerId()";

Expand All @@ -124,7 +132,7 @@ export class ApiClient extends BaseAPI {
const db: ConsortiumDatabase = await provider.get();
const repo = new ConsortiumRepository({ db });

const nodes = repo.nodesWithLedger(ledgerId);
const nodes = repo.nodesWithLedger(ledgerId, capabilities);

// pick a random element from the array of nodes that have a connection to
// the target ledger (based on the ledger ID)
Expand Down
22 changes: 21 additions & 1 deletion packages/cactus-core-api/src/main/json/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@
"description": "String that uniquely identifies a plugin instance within a Cactus consortium so that requests can be addressed/routed directly to individual plugins when necessary.",
"$ref": "#/components/schemas/PrimaryKey"
},
"Capability": {
"description": "String that represents a capability, i.e. if the gateway has the plugin with a certain capability",
"enum": [
"org.hyperledger.cactus.capability.SATPHermes",
"org.hyperledger.cactus.capability.BUNGEEHermes",
"org.hyperledger.cactus.capability.FabricConnector",
"org.hyperledger.cactus.capability.BesuConnector",
"org.hyperledger.cactus.capability.EthConnector"
]
},
"ConsortiumDatabase": {
"required": [
"consortium",
Expand Down Expand Up @@ -317,6 +327,16 @@
"items": {
"$ref": "#/components/schemas/PluginInstanceId"
}
},
"capabilities": {
"type": "array",
"nullable": false,
"minItems": 0,
"maxItems": 2048,
"default": [],
"items": {
"$ref": "#/components/schemas/Capability"
}
}
}
}
Expand Down Expand Up @@ -809,4 +829,4 @@
}
},
"paths": {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt
src/main/kotlin/org/openapitools/client/models/CactusNode.kt
src/main/kotlin/org/openapitools/client/models/CactusNodeAllOf.kt
src/main/kotlin/org/openapitools/client/models/CactusNodeMeta.kt
src/main/kotlin/org/openapitools/client/models/Capability.kt
src/main/kotlin/org/openapitools/client/models/ConsensusAlgorithmFamiliesWithOutTxFinality.kt
src/main/kotlin/org/openapitools/client/models/ConsensusAlgorithmFamiliesWithTxFinality.kt
src/main/kotlin/org/openapitools/client/models/ConsensusAlgorithmFamily.kt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Class | Method | HTTP request | Description
- [org.openapitools.client.models.CactusNode](docs/CactusNode.md)
- [org.openapitools.client.models.CactusNodeAllOf](docs/CactusNodeAllOf.md)
- [org.openapitools.client.models.CactusNodeMeta](docs/CactusNodeMeta.md)
- [org.openapitools.client.models.Capability](docs/Capability.md)
- [org.openapitools.client.models.ConsensusAlgorithmFamiliesWithOutTxFinality](docs/ConsensusAlgorithmFamiliesWithOutTxFinality.md)
- [org.openapitools.client.models.ConsensusAlgorithmFamiliesWithTxFinality](docs/ConsensusAlgorithmFamiliesWithTxFinality.md)
- [org.openapitools.client.models.ConsensusAlgorithmFamily](docs/ConsensusAlgorithmFamily.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package org.openapitools.client.models

import org.openapitools.client.models.Capability

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
Expand All @@ -29,6 +30,7 @@ import com.squareup.moshi.JsonClass
* @param memberId
* @param ledgerIds Stores an array of Ledger entity IDs that are reachable (routable) via this Cactus Node. This information is used by the client side SDK API client to figure out at runtime where to send API requests that are specific to a certain ledger such as requests to execute transactions.
* @param pluginInstanceIds
* @param capabilities
*/


Expand All @@ -55,7 +57,10 @@ data class CactusNode (
val ledgerIds: kotlin.collections.List<kotlin.String> = arrayListOf(),

@Json(name = "pluginInstanceIds")
val pluginInstanceIds: kotlin.collections.List<kotlin.String> = arrayListOf()
val pluginInstanceIds: kotlin.collections.List<kotlin.String> = arrayListOf(),

@Json(name = "capabilities")
val capabilities: kotlin.collections.List<Capability>? = arrayListOf()

)

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package org.openapitools.client.models

import org.openapitools.client.models.Capability

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
Expand All @@ -27,6 +28,7 @@ import com.squareup.moshi.JsonClass
* @param memberId
* @param ledgerIds Stores an array of Ledger entity IDs that are reachable (routable) via this Cactus Node. This information is used by the client side SDK API client to figure out at runtime where to send API requests that are specific to a certain ledger such as requests to execute transactions.
* @param pluginInstanceIds
* @param capabilities
*/


Expand All @@ -46,7 +48,10 @@ data class CactusNodeAllOf (
val ledgerIds: kotlin.collections.List<kotlin.String> = arrayListOf(),

@Json(name = "pluginInstanceIds")
val pluginInstanceIds: kotlin.collections.List<kotlin.String> = arrayListOf()
val pluginInstanceIds: kotlin.collections.List<kotlin.String> = arrayListOf(),

@Json(name = "capabilities")
val capabilities: kotlin.collections.List<Capability>? = arrayListOf()

)

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*
*/

@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)

package org.openapitools.client.models


import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

/**
* String that represents a capability, i.e. if the gateway has the plugin with a certain capability
*
* Values: sATPHermes,bUNGEEHermes,fabricConnector,besuConnector,ethConnector
*/

@JsonClass(generateAdapter = false)
enum class Capability(val value: kotlin.String) {

@Json(name = "org.hyperledger.cactus.capability.SATPHermes")
sATPHermes("org.hyperledger.cactus.capability.SATPHermes"),

@Json(name = "org.hyperledger.cactus.capability.BUNGEEHermes")
bUNGEEHermes("org.hyperledger.cactus.capability.BUNGEEHermes"),

@Json(name = "org.hyperledger.cactus.capability.FabricConnector")
fabricConnector("org.hyperledger.cactus.capability.FabricConnector"),

@Json(name = "org.hyperledger.cactus.capability.BesuConnector")
besuConnector("org.hyperledger.cactus.capability.BesuConnector"),

@Json(name = "org.hyperledger.cactus.capability.EthConnector")
ethConnector("org.hyperledger.cactus.capability.EthConnector");

/**
* Override [toString()] to avoid using the enum variable name as the value, and instead use
* the actual value defined in the API spec file.
*
* This solves a problem when the variable name and its value are different, and ensures that
* the client sends the correct enum values to the server always.
*/
override fun toString(): String = value

companion object {
/**
* Converts the provided [data] to a [String] on success, null otherwise.
*/
fun encode(data: kotlin.Any?): kotlin.String? = if (data is Capability) "$data" else null

/**
* Returns a valid [Capability] for [data], null otherwise.
*/
fun decode(data: kotlin.Any?): Capability? = data?.let {
val normalizedData = "$it".lowercase()
values().firstOrNull { value ->
it == value || normalizedData == "$value".lowercase()
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ export interface CactusNode {
* @memberof CactusNode
*/
'pluginInstanceIds': Array<string>;
/**
*
* @type {Array<Capability>}
* @memberof CactusNode
*/
'capabilities'?: Array<Capability>;
}
/**
*
Expand Down Expand Up @@ -108,6 +114,12 @@ export interface CactusNodeAllOf {
* @memberof CactusNodeAllOf
*/
'pluginInstanceIds': Array<string>;
/**
*
* @type {Array<Capability>}
* @memberof CactusNodeAllOf
*/
'capabilities'?: Array<Capability>;
}
/**
* A Cactus node meta information
Expand All @@ -128,6 +140,23 @@ export interface CactusNodeMeta {
*/
'publicKeyPem': string;
}
/**
* String that represents a capability, i.e. if the gateway has the plugin with a certain capability
* @export
* @enum {string}
*/

export const Capability = {
SatpHermes: 'org.hyperledger.cactus.capability.SATPHermes',
BungeeHermes: 'org.hyperledger.cactus.capability.BUNGEEHermes',
FabricConnector: 'org.hyperledger.cactus.capability.FabricConnector',
BesuConnector: 'org.hyperledger.cactus.capability.BesuConnector',
EthConnector: 'org.hyperledger.cactus.capability.EthConnector'
} as const;

export type Capability = typeof Capability[keyof typeof Capability];


/**
* Enumerates a list of consensus algorithm families that do not provide immediate finality
* @export
Expand Down
21 changes: 17 additions & 4 deletions packages/cactus-core/src/main/typescript/consortium-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
LoggerProvider,
} from "@hyperledger/cactus-common";

import { CactusNode, ConsortiumDatabase } from "@hyperledger/cactus-core-api";
import {
CactusNode,
Capability,
ConsortiumDatabase,
} from "@hyperledger/cactus-core-api";

export interface IConsortiumRepositoryOptions {
logLevel?: LogLevelDesc;
Expand Down Expand Up @@ -55,10 +59,19 @@ export class ConsortiumRepository {
* @param ledgerId The ID of the ledger to filter nodes based on.
* @throws {Error} If `ledgerId` is falsy or blank.
*/
public nodesWithLedger(ledgerId: string): CactusNode[] {
public nodesWithLedger(
ledgerId: string,
capabilities: Capability[] = [],
): CactusNode[] {
const fnTag = `${this.className}#nodesWithLedger()`;
Checks.nonBlankString(ledgerId, `${fnTag}:ledgerId`);

return this.allNodes.filter((cn) => cn.ledgerIds.includes(ledgerId));
const pre_filter = this.allNodes.filter((cn) =>
cn.ledgerIds.includes(ledgerId),
);
let final = pre_filter;
for (const capability of capabilities) {
final = pre_filter.filter((cn) => cn.capabilities?.includes(capability));
}
return final;
}
}
Loading

0 comments on commit c081da4

Please sign in to comment.