Commit a4ab1a99 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'feat/dlt-component-gateway' into 'feat/dlt-component'

DLT component sync between connector & gateway for initial integration test

See merge request teraflow-h2020/controller!135
parents cf229c7f 25668e43
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@ service DltGatewayService {
  rpc RecordToDlt   (DltRecord                 ) returns (       DltRecordStatus  ) {}
  rpc GetFromDlt    (DltRecordId               ) returns (       DltRecord        ) {}
  rpc SubscribeToDlt(DltRecordSubscription     ) returns (stream DltRecordEvent   ) {}
  rpc GetDltStatus  (context.TeraFlowController) returns (       DltPeerStatus    ) {}  // NEC is checkig if it is possible
  rpc GetDltPeers   (context.Empty             ) returns (       DltPeerStatusList) {}  // NEC is checkig if it is possible
  rpc GetDltStatus  (context.TeraFlowController) returns (       DltPeerStatus    ) {}  // NEC is checking if it is possible
  rpc GetDltPeers   (context.Empty             ) returns (       DltPeerStatusList) {}  // NEC is checking if it is possible
}

enum DltRecordTypeEnum {
+11 −20
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
 duplication of the object or source code - either totally or in
 part - is strictly prohibited.

          Copyright (c) 2021 NEC Laboratories Europe GmbH
          Copyright (c) 2022 NEC Laboratories Europe GmbH
          All Rights Reserved.

 Authors: Konstantin Munichev <konstantin.munichev@neclab.eu>
@@ -42,7 +42,7 @@
## General information
The DLT module is used to provide access to the underlying Fabric deployment. It allows clients
to add, retrieve, modify and delete blockchain-backed data, essentially working as a key-value
database. External clients should use REST API to communicate with this service, its detailed
database. External clients should use gRPC API to communicate with this service, its detailed
description available below.

## Code structure
@@ -59,26 +59,17 @@ CRUD interface.
Other files contain auxiliary code for `FabricConnector` which allows it to register/enroll
users and to obtain smart contract instances.

### HTTP package
Contains server side HTTP handler. It accepts requests from the outside and performs the
requested operation. For the detailed description see API description section.
### Grpc package
Contains server side gRPC handler. It accepts requests from the outside and performs the
requested operation. For the more detailed description see Proto package description right below.

### Proto package
The proto package contains `Config.proto` file which contains messages for REST API. The most
important ones are `DltConfig` (it defines the whole DLT configuration) and `DltRecord` which
represents data to store in the blockchain.
The proto package contains `dlt.proto` file which defines gRPC service `DltService` API and messages
it uses. There are 3 main functions: `RecordToDlt` which allows to create/modify/delete data,
`GetFromDlt` which returns already written data and `SubscribeToDlt` which allows clients subscribe
for future create/modify/delete events with provided filters.
Other proto files don't play any significant role and could be safely ignored by end users.

### Client example
This code is not necessary to the service, but it could be used to test the service. It contains
a sample REST client which connects the service and perform all the CRUD operations. 

## REST API description
| Method | URL | Input | Response code | Output |
| --- | ----------- | --- | --- | --- |
| POST | /dlt/configure | Configuration object | 201 or 400 | Status value | 
| GET | /dlt/configure | - | 200 or 404 | Configuration object |
| POST | /dlt/record | Record object | 200, 201, 400 or 404 | Status value |
| GET | /dlt/record | Record id | 200 or 404 | Record object |

Record and configuration object are defined in `proto` package.
a sample gRPC client which connects the service and perform all the CRUD operations. 
+45 −14
Original line number Diff line number Diff line
@@ -39,16 +39,19 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

import com.google.protobuf.gradle.generateProtoTasks
import com.google.protobuf.gradle.id
import com.google.protobuf.gradle.plugins
import com.google.protobuf.gradle.protobuf
import com.google.protobuf.gradle.protoc

ext["protobufVersion"] = "3.19.1"
ext["grpcVersion"] = "1.47.0"
ext["grpcKotlinVersion"] = "1.3.0" // CURRENT_GRPC_KOTLIN_VERSION
ext["protobufVersion"] = "3.20.1"
ext["ktorVersion"] = "1.6.5"

plugins {
    kotlin("jvm") version "1.5.31"
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.serialization") version "1.4.21"
    id("com.google.protobuf") version "0.8.17"
    id("com.google.protobuf") version "0.8.18"
    application
}

@@ -56,22 +59,24 @@ group = "eu.neclab"
version = "1.0-SNAPSHOT"

repositories {
    mavenLocal()
    google()
    mavenCentral()
}

dependencies {
    testImplementation("org.jetbrains.kotlin:kotlin-test:1.5.31")
    implementation("org.hyperledger.fabric:fabric-gateway-java:2.2.2")
    api("com.google.protobuf:protobuf-kotlin:${rootProject.ext["protobufVersion"]}")
    implementation("io.ktor:ktor-server-core:${rootProject.ext["ktorVersion"]}")
    implementation("io.ktor:ktor-server-netty:${rootProject.ext["ktorVersion"]}")
    implementation("io.ktor:ktor-serialization:${rootProject.ext["ktorVersion"]}")
    implementation("io.ktor:ktor-client-serialization:${rootProject.ext["ktorVersion"]}")
    implementation("io.ktor:ktor-client-core:${rootProject.ext["ktorVersion"]}")
    implementation("io.ktor:ktor-client-cio:${rootProject.ext["ktorVersion"]}")
    implementation("ch.qos.logback:logback-classic:1.2.5")
    implementation(kotlin("stdlib-jdk8"))
    testImplementation("org.jetbrains.kotlin:kotlin-test:1.6.21")
    implementation("javax.annotation:javax.annotation-api:1.3.2")
    implementation("io.grpc:grpc-kotlin-stub:1.3.0")
    implementation("io.grpc:grpc-protobuf:1.47.0")
    implementation("com.google.protobuf:protobuf-kotlin:3.21.1")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
    implementation("org.hyperledger.fabric:fabric-gateway-java:2.2.5")
    implementation("ch.qos.logback:logback-classic:1.2.11")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.3.1")
    runtimeOnly("io.grpc:grpc-netty:${rootProject.ext["grpcVersion"]}")
}

tasks.test {
@@ -93,6 +98,12 @@ application {
    mainClass.set("MainKt")
}

task("runServer", JavaExec::class) {
    main = "grpc.FabricServerKt"
    classpath = sourceSets["main"].runtimeClasspath
}


sourceSets {
    main {
        proto {
@@ -101,12 +112,32 @@ sourceSets {
    }
}

sourceSets {
    val main by getting { }
    main.java.srcDirs("build/generated/source/proto/main/grpc")
    main.java.srcDirs("build/generated/source/proto/main/grpckt")
    main.java.srcDirs("build/generated/source/proto/main/java")
    main.java.srcDirs("build/generated/source/proto/main/kotlin")
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:${rootProject.ext["protobufVersion"]}"
    }
    plugins {
        id("grpc") {
            artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}"
        }
        id("grpckt") {
            artifact = "io.grpc:protoc-gen-grpc-kotlin:${rootProject.ext["grpcKotlinVersion"]}:jdk8@jar"
        }
    }
    generateProtoTasks {
        all().forEach {
            it.plugins {
                id("grpc")
                id("grpckt")
            }
            it.builtins {
                id("kotlin")
            }
+8 −8
Original line number Diff line number Diff line
-----BEGIN CERTIFICATE-----
MIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw
MIICJjCCAc2gAwIBAgIUVSFCRQNScNJyIwJz89vi6tazYJ4wCgYIKoZIzj0EAwIw
cDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH
EwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh
Lm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw
Lm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzEzMTQ1MjAwWhcNMzcwNzA5MTQ1MjAw
WjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV
BAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT
Y2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg
yfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L
4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG
AQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD
AgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P
mbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=
Y2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLg8
zJvOKBR1fS+hrrMc3xEhOalkSG+5vGGpwzgHv5NNMlDZcbQVuEBHPmRowbLWx4nw
2CIUSfkhtQGC5GmUncOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG
AQH/AgEBMB0GA1UdDgQWBBRm7lBNvvkP8iy6f0cXwz9BTeSYDzAKBggqhkjOPQQD
AgNHADBEAiB1p8QFXHszJsMqiShmyuTA6zGPfHlnan3dgYMCTNR7mwIgFx3SqSYk
FizTEfVfOcdjIYGc3pTPTyK5PVbO1k2BW80=
-----END CERTIFICATE-----
+8 −8
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://s2:7051",
            "url": "grpcs://teraflow.nlehd.de:7051",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg\nyfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L\n4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD\nAgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P\nmbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=\n-----END CERTIFICATE-----\n"
                "pem": "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUVSFCRQNScNJyIwJz89vi6tazYJ4wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzEzMTQ1MjAwWhcNMzcwNzA5MTQ1MjAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLg8\nzJvOKBR1fS+hrrMc3xEhOalkSG+5vGGpwzgHv5NNMlDZcbQVuEBHPmRowbLWx4nw\n2CIUSfkhtQGC5GmUncOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBRm7lBNvvkP8iy6f0cXwz9BTeSYDzAKBggqhkjOPQQD\nAgNHADBEAiB1p8QFXHszJsMqiShmyuTA6zGPfHlnan3dgYMCTNR7mwIgFx3SqSYk\nFizTEfVfOcdjIYGc3pTPTyK5PVbO1k2BW80=\n-----END CERTIFICATE-----\n"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com",
@@ -34,9 +34,9 @@
            }
        },
        "peer0.org2.example.com": {
            "url": "grpcs://s2:9051",
            "url": "grpcs://teraflow.nlehd.de:9051",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICHzCCAcWgAwIBAgIUejv57h6dJkVIM2R1YnlqykkvG7gwCgYIKoZIzj0EAwIw\nbDELMAkGA1UEBhMCVUsxEjAQBgNVBAgTCUhhbXBzaGlyZTEQMA4GA1UEBxMHSHVy\nc2xleTEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eub3Jn\nMi5leGFtcGxlLmNvbTAeFw0yMjA3MDUwOTQ0MDBaFw0zNzA3MDEwOTQ0MDBaMGwx\nCzAJBgNVBAYTAlVLMRIwEAYDVQQIEwlIYW1wc2hpcmUxEDAOBgNVBAcTB0h1cnNs\nZXkxGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2NhLm9yZzIu\nZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASFZqoisCIgZyMM\n8e0YBA+jxH/+Fc4Y4OkEl5uGRXGl9s0OemCdvhlX9K+esX2DVk1st1PMfTEj/six\n9XPpVqzNo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAd\nBgNVHQ4EFgQUPEyzGBlZEjguoJB16wAmoH2bAh8wCgYIKoZIzj0EAwIDSAAwRQIh\nAL6DAWgrqRtbYoQ0oYAr/2vze0JtQcXoqiQKlyvYkUBbAiB/uSHBk3NwjzI8t8iW\nzQzr5eNy5JwOO0SWwPEv4Ev9iQ==\n-----END CERTIFICATE-----\n"
                "pem": "-----BEGIN CERTIFICATE-----\nMIICHzCCAcWgAwIBAgIUOsbw943VjFitBzBEXAcxLlOLow8wCgYIKoZIzj0EAwIw\nbDELMAkGA1UEBhMCVUsxEjAQBgNVBAgTCUhhbXBzaGlyZTEQMA4GA1UEBxMHSHVy\nc2xleTEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eub3Jn\nMi5leGFtcGxlLmNvbTAeFw0yMjA3MTMxNDUyMDBaFw0zNzA3MDkxNDUyMDBaMGwx\nCzAJBgNVBAYTAlVLMRIwEAYDVQQIEwlIYW1wc2hpcmUxEDAOBgNVBAcTB0h1cnNs\nZXkxGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2NhLm9yZzIu\nZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARKov9QrWe9dklr\nqYJxOOoqoO3EI18LtPizVCKYrG3IMqkaatM6DLc/2SBTSIqIDeTR6N8WZAPVgLKA\nboRt87Heo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAd\nBgNVHQ4EFgQUYe4sT8J0Y2iN/9Q14FcpmxK5dYcwCgYIKoZIzj0EAwIDSAAwRQIh\nAJh2+1QXc5/ZlPaN2qnh3TXbzPFeCDXjoMAoBsOYtRcMAiAF+tcoFY0NcLDfTZBm\nNuuiQDIasoTB9Wuu4PBv8T7I5w==\n-----END CERTIFICATE-----\n"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org2.example.com",
@@ -46,11 +46,11 @@
    },
    "certificateAuthorities": {
        "ca.org1.example.com": {
            "url": "https://s2:7054",
            "url": "https://teraflow.nlehd.de:7054",
            "caName": "ca-org1",
            "tlsCACerts": {
                "pem": [
                    "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg\nyfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L\n4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD\nAgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P\nmbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=\n-----END CERTIFICATE-----\n"
                    "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUVSFCRQNScNJyIwJz89vi6tazYJ4wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzEzMTQ1MjAwWhcNMzcwNzA5MTQ1MjAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLg8\nzJvOKBR1fS+hrrMc3xEhOalkSG+5vGGpwzgHv5NNMlDZcbQVuEBHPmRowbLWx4nw\n2CIUSfkhtQGC5GmUncOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBRm7lBNvvkP8iy6f0cXwz9BTeSYDzAKBggqhkjOPQQD\nAgNHADBEAiB1p8QFXHszJsMqiShmyuTA6zGPfHlnan3dgYMCTNR7mwIgFx3SqSYk\nFizTEfVfOcdjIYGc3pTPTyK5PVbO1k2BW80=\n-----END CERTIFICATE-----\n"
                ]
            },
            "httpOptions": {
@@ -60,9 +60,9 @@
    },
    "orderers": {
        "orderer0.example.com": {
            "url": "grpcs://s2:7050",
            "url": "grpcs://teraflow.nlehd.de:7050",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICCjCCAbGgAwIBAgIURV0KgZTOagIAIU7wRcSg/mKl5RUwCgYIKoZIzj0EAwIw\nYjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEUMBIGA1UEChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUu\nY29tMB4XDTIyMDcwNTA5NDQwMFoXDTM3MDcwMTA5NDQwMFowYjELMAkGA1UEBhMC\nVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UE\nChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAEWrOugtJgVLAKZRw9jaC15RUbVuTm0ZmsqNyiQrKQ\nYawLE6fs+QIU7WQ25fxlYtmGB2S8nofGCDuwaoTevW0GoaNFMEMwDgYDVR0PAQH/\nBAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFLKBzGXaQg2Irr57\npjoFYZ9F1NoNMAoGCCqGSM49BAMCA0cAMEQCIB1YdgOEsATw2GeaFmq6nqWg0JDT\np456JB/reFmnPWdJAiBPo5H9sMh+MpP4R5ue7nuwYK7SEJ1DOJqWMlPuNhVgtA==\n-----END CERTIFICATE-----\n"
                "pem": "-----BEGIN CERTIFICATE-----\nMIICCjCCAbGgAwIBAgIUA6RVRhhZD8pvcNAQJ6HWPUkbNNIwCgYIKoZIzj0EAwIw\nYjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEUMBIGA1UEChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUu\nY29tMB4XDTIyMDcxMzE0NTIwMFoXDTM3MDcwOTE0NTIwMFowYjELMAkGA1UEBhMC\nVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UE\nChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAEs7mmo5MY0oO9zCYcraUN/MXWxHiQ04xG6tWLaeWX\nqfSmFnfO8UBFq4OF5Li861UWGe+s9QxNXIELchBG8M7qLqNFMEMwDgYDVR0PAQH/\nBAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFBGG7kbCLEXzlQUF\nQfx845Qf2WKCMAoGCCqGSM49BAMCA0cAMEQCIAwABAqRopU+Qt3myyt4YiKQFpyO\nWTZifesVFe3fM/Q3AiA7oZ9XdQ5EuPhqFxSz7ASF45iyL3k078ilusjpc6IZ/g==\n-----END CERTIFICATE-----\n"
            },
            "grpcOptions": {
                "ssl-target-name-override": "orderer0.example.com",
Loading