From 85f7fca2b3798244b36d633e0210a0a5f3efc64b Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 19:08:27 +0100 Subject: [PATCH 01/20] add Dockerfile --- Dockerfile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..497e119 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 + + +RUN \ + microdnf update --nodocs && \ + microdnf install curl ca-certificates shadow-utils --nodocs + +COPY CREDITS /licenses/CREDITS +COPY LICENSE /licenses/LICENSE +LABEL name="HLF Operator" \ + vendor="Kung Fu Software " \ + maintainer="Kung Fu Software " \ + version="v1.1.0" \ + release="v1.1.0" + +COPY charts /charts + +COPY hlf-operator /hlf-operator + +CMD ["/hlf-operator"] \ No newline at end of file From 19cf4ea5e39cbe892661af84b7269430ff95c60b Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 19:10:38 +0100 Subject: [PATCH 02/20] update --- Dockerfile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 497e119..7f82dac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,14 +7,12 @@ RUN \ COPY CREDITS /licenses/CREDITS COPY LICENSE /licenses/LICENSE -LABEL name="HLF Operator" \ +LABEL name="HLF CC Developer" \ vendor="Kung Fu Software " \ maintainer="Kung Fu Software " \ version="v1.1.0" \ release="v1.1.0" -COPY charts /charts +COPY hlf-cc-dev /hlf-cc-dev -COPY hlf-operator /hlf-operator - -CMD ["/hlf-operator"] \ No newline at end of file +CMD ["/hlf-cc-dev"] \ No newline at end of file From 7bd7396a41ee0f58cfc08033140cd76165183de3 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 19:15:54 +0100 Subject: [PATCH 03/20] update goreleaser conf --- .goreleaser.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 03e39c4..e836cb5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -17,17 +17,6 @@ before: - go mod download builds: - - - goos: - - linux - goarch: - - amd64 - env: - - CGO_ENABLED=0 - ldflags: - - -s -w -X main.version={{.Tag}} - flags: - - -trimpath - id: hlf-cc-dev dir: hlf-cc-dev @@ -46,12 +35,6 @@ builds: flags: - -trimpath -archives: - - - id: hlf-cc-dev - format: zip - allow_different_binary_count: true - dockers: - # GOOS of the built binary that should be used. From b3e52e101ecea342cd2d8ede922771717c55f9d9 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 19:17:44 +0100 Subject: [PATCH 04/20] update gorelease conf --- .goreleaser.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index e836cb5..a74e963 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -18,9 +18,6 @@ before: builds: - - id: hlf-cc-dev - dir: hlf-cc-dev - binary: hlf-cc-dev goos: - linux - darwin From 47f487f52a792f44acf8bdccdc4b92bd101c0c93 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 19:46:45 +0100 Subject: [PATCH 05/20] use ghcr.io instead of quay.io --- .github/workflows/goreleaser.yml | 8 ++++---- .goreleaser.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index b451018..054e2e4 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -18,12 +18,12 @@ jobs: with: go-version: 1.16 - - name: Docker Login + name: Login to GitHub Container Registry uses: docker/login-action@v1 with: - registry: quay.io - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 diff --git a/.goreleaser.yml b/.goreleaser.yml index a74e963..1d06859 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -40,8 +40,8 @@ dockers: goarch: amd64 dockerfile: Dockerfile image_templates: - - "quay.io/kfsoftware/hlf-cc-dev:{{ .Tag }}" - - "quay.io/kfsoftware/hlf-cc-dev:latest" + - "ghcr.io/kfsoftware/hlf-cc-dev:{{ .Tag }}" + - "ghcr.io/kfsoftware/hlf-cc-dev:latest" extra_files: - LICENSE - README.md From 077e8eac103bd6aa8fb6354dfdf4b7073c56ee17 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 16 Jan 2022 21:17:44 +0100 Subject: [PATCH 06/20] remove ent files for db --- cmd/serve/serve.go | 32 +- ent/chaincode.go | 151 ----- ent/chaincode/chaincode.go | 58 -- ent/chaincode/where.go | 388 ------------ ent/chaincode_create.go | 282 --------- ent/chaincode_delete.go | 111 ---- ent/chaincode_query.go | 994 ------------------------------ ent/chaincode_update.go | 443 -------------- ent/client.go | 342 ----------- ent/config.go | 60 -- ent/context.go | 33 - ent/ent.go | 261 -------- ent/enttest/enttest.go | 78 --- ent/generate.go | 3 - ent/hook/hook.go | 217 ------- ent/migrate/migrate.go | 72 --- ent/migrate/schema.go | 57 -- ent/mutation.go | 1177 ------------------------------------ ent/predicate/predicate.go | 13 - ent/runtime.go | 20 - ent/runtime/runtime.go | 10 - ent/schema/chaincode.go | 29 - ent/schema/tenant.go | 31 - ent/tenant.go | 177 ------ ent/tenant/tenant.go | 54 -- ent/tenant/where.go | 776 ------------------------ ent/tenant_create.go | 328 ---------- ent/tenant_delete.go | 111 ---- ent/tenant_query.go | 987 ------------------------------ ent/tenant_update.go | 671 -------------------- ent/tx.go | 213 ------- gql/generated.go | 9 + gql/models/models.go | 1 + gql/resolvers/mutation.go | 96 +-- gql/resolvers/resolvers.go | 15 +- schema/mutation.graphql | 1 + server/server.go | 23 +- 37 files changed, 95 insertions(+), 8229 deletions(-) delete mode 100644 ent/chaincode.go delete mode 100644 ent/chaincode/chaincode.go delete mode 100644 ent/chaincode/where.go delete mode 100644 ent/chaincode_create.go delete mode 100644 ent/chaincode_delete.go delete mode 100644 ent/chaincode_query.go delete mode 100644 ent/chaincode_update.go delete mode 100644 ent/client.go delete mode 100644 ent/config.go delete mode 100644 ent/context.go delete mode 100644 ent/ent.go delete mode 100644 ent/enttest/enttest.go delete mode 100644 ent/generate.go delete mode 100644 ent/hook/hook.go delete mode 100644 ent/migrate/migrate.go delete mode 100644 ent/migrate/schema.go delete mode 100644 ent/mutation.go delete mode 100644 ent/predicate/predicate.go delete mode 100644 ent/runtime.go delete mode 100644 ent/runtime/runtime.go delete mode 100644 ent/schema/chaincode.go delete mode 100644 ent/schema/tenant.go delete mode 100644 ent/tenant.go delete mode 100644 ent/tenant/tenant.go delete mode 100644 ent/tenant/where.go delete mode 100644 ent/tenant_create.go delete mode 100644 ent/tenant_delete.go delete mode 100644 ent/tenant_query.go delete mode 100644 ent/tenant_update.go delete mode 100644 ent/tx.go diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index 1ea8074..ccd8cbe 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -2,8 +2,12 @@ package serve import ( "fmt" + "github.com/hyperledger/fabric-config/configtx" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" + "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/pkg/msp" "github.com/kfsoftware/hlf-cc-dev/server" @@ -26,7 +30,7 @@ type serveCmd struct { } type serveConfig struct { - Fabric struct { + Fabric struct { Connection string `json:"connection"` Channel string `json:"channel"` Org string `json:"org"` @@ -124,11 +128,37 @@ func (c *serveCmd) run(conf *serveConfig) error { if err != nil { return err } + resClient, err := resmgmt.New(sdkContext) + if err != nil { + return err + } + + block, err := resClient.QueryConfigBlockFromOrderer(conf.Fabric.Channel) + if err != nil { + return err + } + cfgBlock, err := resource.ExtractConfigFromBlock(block) + if err != nil { + return err + } + cftxGen := configtx.New(cfgBlock) + appConf, err := cftxGen.Application().Configuration() + if err != nil { + return err + } + mapSdkContext := map[string]context.ClientProvider{} + for _, organization := range appConf.Organizations { + mapSdkContext[organization.Name] = sdk.Context( + fabsdk.WithUser(conf.Fabric.Org), + fabsdk.WithOrg(organization.Name), + ) + } opts := server.BlockchainServerOpts{ Address: c.address, MetricsAddress: c.metricsAddress, SDK: sdk, SDKContext: sdkContext, + SDKContextMap: mapSdkContext, Channel: conf.Fabric.Channel, MSPClient: mspClient, CAConfig: caConfig, diff --git a/ent/chaincode.go b/ent/chaincode.go deleted file mode 100644 index 62e29e8..0000000 --- a/ent/chaincode.go +++ /dev/null @@ -1,151 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "fmt" - "strings" - - "entgo.io/ent/dialect/sql" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// Chaincode is the model entity for the Chaincode schema. -type Chaincode struct { - config `json:"-"` - // ID of the ent. - ID int `json:"id,omitempty"` - // PackageId holds the value of the "packageId" field. - PackageId string `json:"packageId,omitempty"` - // ChannelId holds the value of the "channelId" field. - ChannelId string `json:"channelId,omitempty"` - // Edges holds the relations/edges for other nodes in the graph. - // The values are being populated by the ChaincodeQuery when eager-loading is set. - Edges ChaincodeEdges `json:"edges"` - tenant_chaincodes *int -} - -// ChaincodeEdges holds the relations/edges for other nodes in the graph. -type ChaincodeEdges struct { - // Tenant holds the value of the tenant edge. - Tenant *Tenant `json:"tenant,omitempty"` - // loadedTypes holds the information for reporting if a - // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool -} - -// TenantOrErr returns the Tenant value or an error if the edge -// was not loaded in eager-loading, or loaded but was not found. -func (e ChaincodeEdges) TenantOrErr() (*Tenant, error) { - if e.loadedTypes[0] { - if e.Tenant == nil { - // The edge tenant was loaded in eager-loading, - // but was not found. - return nil, &NotFoundError{label: tenant.Label} - } - return e.Tenant, nil - } - return nil, &NotLoadedError{edge: "tenant"} -} - -// scanValues returns the types for scanning values from sql.Rows. -func (*Chaincode) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) - for i := range columns { - switch columns[i] { - case chaincode.FieldID: - values[i] = new(sql.NullInt64) - case chaincode.FieldPackageId, chaincode.FieldChannelId: - values[i] = new(sql.NullString) - case chaincode.ForeignKeys[0]: // tenant_chaincodes - values[i] = new(sql.NullInt64) - default: - return nil, fmt.Errorf("unexpected column %q for type Chaincode", columns[i]) - } - } - return values, nil -} - -// assignValues assigns the values that were returned from sql.Rows (after scanning) -// to the Chaincode fields. -func (c *Chaincode) assignValues(columns []string, values []interface{}) error { - if m, n := len(values), len(columns); m < n { - return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) - } - for i := range columns { - switch columns[i] { - case chaincode.FieldID: - value, ok := values[i].(*sql.NullInt64) - if !ok { - return fmt.Errorf("unexpected type %T for field id", value) - } - c.ID = int(value.Int64) - case chaincode.FieldPackageId: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field packageId", values[i]) - } else if value.Valid { - c.PackageId = value.String - } - case chaincode.FieldChannelId: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field channelId", values[i]) - } else if value.Valid { - c.ChannelId = value.String - } - case chaincode.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for edge-field tenant_chaincodes", value) - } else if value.Valid { - c.tenant_chaincodes = new(int) - *c.tenant_chaincodes = int(value.Int64) - } - } - } - return nil -} - -// QueryTenant queries the "tenant" edge of the Chaincode entity. -func (c *Chaincode) QueryTenant() *TenantQuery { - return (&ChaincodeClient{config: c.config}).QueryTenant(c) -} - -// Update returns a builder for updating this Chaincode. -// Note that you need to call Chaincode.Unwrap() before calling this method if this Chaincode -// was returned from a transaction, and the transaction was committed or rolled back. -func (c *Chaincode) Update() *ChaincodeUpdateOne { - return (&ChaincodeClient{config: c.config}).UpdateOne(c) -} - -// Unwrap unwraps the Chaincode entity that was returned from a transaction after it was closed, -// so that all future queries will be executed through the driver which created the transaction. -func (c *Chaincode) Unwrap() *Chaincode { - tx, ok := c.config.driver.(*txDriver) - if !ok { - panic("ent: Chaincode is not a transactional entity") - } - c.config.driver = tx.drv - return c -} - -// String implements the fmt.Stringer. -func (c *Chaincode) String() string { - var builder strings.Builder - builder.WriteString("Chaincode(") - builder.WriteString(fmt.Sprintf("id=%v", c.ID)) - builder.WriteString(", packageId=") - builder.WriteString(c.PackageId) - builder.WriteString(", channelId=") - builder.WriteString(c.ChannelId) - builder.WriteByte(')') - return builder.String() -} - -// Chaincodes is a parsable slice of Chaincode. -type Chaincodes []*Chaincode - -func (c Chaincodes) config(cfg config) { - for _i := range c { - c[_i].config = cfg - } -} diff --git a/ent/chaincode/chaincode.go b/ent/chaincode/chaincode.go deleted file mode 100644 index 0d64821..0000000 --- a/ent/chaincode/chaincode.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package chaincode - -const ( - // Label holds the string label denoting the chaincode type in the database. - Label = "chaincode" - // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldPackageId holds the string denoting the packageid field in the database. - FieldPackageId = "package_id" - // FieldChannelId holds the string denoting the channelid field in the database. - FieldChannelId = "channel_id" - // EdgeTenant holds the string denoting the tenant edge name in mutations. - EdgeTenant = "tenant" - // Table holds the table name of the chaincode in the database. - Table = "chaincodes" - // TenantTable is the table that holds the tenant relation/edge. - TenantTable = "chaincodes" - // TenantInverseTable is the table name for the Tenant entity. - // It exists in this package in order to avoid circular dependency with the "tenant" package. - TenantInverseTable = "tenants" - // TenantColumn is the table column denoting the tenant relation/edge. - TenantColumn = "tenant_chaincodes" -) - -// Columns holds all SQL columns for chaincode fields. -var Columns = []string{ - FieldID, - FieldPackageId, - FieldChannelId, -} - -// ForeignKeys holds the SQL foreign-keys that are owned by the "chaincodes" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "tenant_chaincodes", -} - -// ValidColumn reports if the column name is valid (part of the table columns). -func ValidColumn(column string) bool { - for i := range Columns { - if column == Columns[i] { - return true - } - } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } - return false -} - -var ( - // PackageIdValidator is a validator for the "packageId" field. It is called by the builders before save. - PackageIdValidator func(string) error -) diff --git a/ent/chaincode/where.go b/ent/chaincode/where.go deleted file mode 100644 index 2cd8e30..0000000 --- a/ent/chaincode/where.go +++ /dev/null @@ -1,388 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package chaincode - -import ( - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" -) - -// ID filters vertices based on their ID field. -func ID(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) -} - -// IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) -} - -// IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) -} - -// IDIn applies the In predicate on the ID field. -func IDIn(ids ...int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(ids) == 0 { - s.Where(sql.False()) - return - } - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) -} - -// IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(ids) == 0 { - s.Where(sql.False()) - return - } - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) -} - -// IDGT applies the GT predicate on the ID field. -func IDGT(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) -} - -// IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) -} - -// IDLT applies the LT predicate on the ID field. -func IDLT(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) -} - -// IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) -} - -// PackageId applies equality check predicate on the "packageId" field. It's identical to PackageIdEQ. -func PackageId(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPackageId), v)) - }) -} - -// ChannelId applies equality check predicate on the "channelId" field. It's identical to ChannelIdEQ. -func ChannelId(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldChannelId), v)) - }) -} - -// PackageIdEQ applies the EQ predicate on the "packageId" field. -func PackageIdEQ(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPackageId), v)) - }) -} - -// PackageIdNEQ applies the NEQ predicate on the "packageId" field. -func PackageIdNEQ(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldPackageId), v)) - }) -} - -// PackageIdIn applies the In predicate on the "packageId" field. -func PackageIdIn(vs ...string) predicate.Chaincode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldPackageId), v...)) - }) -} - -// PackageIdNotIn applies the NotIn predicate on the "packageId" field. -func PackageIdNotIn(vs ...string) predicate.Chaincode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldPackageId), v...)) - }) -} - -// PackageIdGT applies the GT predicate on the "packageId" field. -func PackageIdGT(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldPackageId), v)) - }) -} - -// PackageIdGTE applies the GTE predicate on the "packageId" field. -func PackageIdGTE(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldPackageId), v)) - }) -} - -// PackageIdLT applies the LT predicate on the "packageId" field. -func PackageIdLT(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldPackageId), v)) - }) -} - -// PackageIdLTE applies the LTE predicate on the "packageId" field. -func PackageIdLTE(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldPackageId), v)) - }) -} - -// PackageIdContains applies the Contains predicate on the "packageId" field. -func PackageIdContains(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldPackageId), v)) - }) -} - -// PackageIdHasPrefix applies the HasPrefix predicate on the "packageId" field. -func PackageIdHasPrefix(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldPackageId), v)) - }) -} - -// PackageIdHasSuffix applies the HasSuffix predicate on the "packageId" field. -func PackageIdHasSuffix(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldPackageId), v)) - }) -} - -// PackageIdEqualFold applies the EqualFold predicate on the "packageId" field. -func PackageIdEqualFold(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldPackageId), v)) - }) -} - -// PackageIdContainsFold applies the ContainsFold predicate on the "packageId" field. -func PackageIdContainsFold(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldPackageId), v)) - }) -} - -// ChannelIdEQ applies the EQ predicate on the "channelId" field. -func ChannelIdEQ(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdNEQ applies the NEQ predicate on the "channelId" field. -func ChannelIdNEQ(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdIn applies the In predicate on the "channelId" field. -func ChannelIdIn(vs ...string) predicate.Chaincode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldChannelId), v...)) - }) -} - -// ChannelIdNotIn applies the NotIn predicate on the "channelId" field. -func ChannelIdNotIn(vs ...string) predicate.Chaincode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Chaincode(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldChannelId), v...)) - }) -} - -// ChannelIdGT applies the GT predicate on the "channelId" field. -func ChannelIdGT(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdGTE applies the GTE predicate on the "channelId" field. -func ChannelIdGTE(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdLT applies the LT predicate on the "channelId" field. -func ChannelIdLT(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdLTE applies the LTE predicate on the "channelId" field. -func ChannelIdLTE(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdContains applies the Contains predicate on the "channelId" field. -func ChannelIdContains(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdHasPrefix applies the HasPrefix predicate on the "channelId" field. -func ChannelIdHasPrefix(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdHasSuffix applies the HasSuffix predicate on the "channelId" field. -func ChannelIdHasSuffix(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdEqualFold applies the EqualFold predicate on the "channelId" field. -func ChannelIdEqualFold(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldChannelId), v)) - }) -} - -// ChannelIdContainsFold applies the ContainsFold predicate on the "channelId" field. -func ChannelIdContainsFold(v string) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldChannelId), v)) - }) -} - -// HasTenant applies the HasEdge predicate on the "tenant" edge. -func HasTenant() predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(TenantTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, TenantTable, TenantColumn), - ) - sqlgraph.HasNeighbors(s, step) - }) -} - -// HasTenantWith applies the HasEdge predicate on the "tenant" edge with a given conditions (other predicates). -func HasTenantWith(preds ...predicate.Tenant) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(TenantInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, TenantTable, TenantColumn), - ) - sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { - for _, p := range preds { - p(s) - } - }) - }) -} - -// And groups predicates with the AND operator between them. -func And(predicates ...predicate.Chaincode) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) -} - -// Or groups predicates with the OR operator between them. -func Or(predicates ...predicate.Chaincode) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) -} - -// Not applies the not operator on the given predicate. -func Not(p predicate.Chaincode) predicate.Chaincode { - return predicate.Chaincode(func(s *sql.Selector) { - p(s.Not()) - }) -} diff --git a/ent/chaincode_create.go b/ent/chaincode_create.go deleted file mode 100644 index 9b03b58..0000000 --- a/ent/chaincode_create.go +++ /dev/null @@ -1,282 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// ChaincodeCreate is the builder for creating a Chaincode entity. -type ChaincodeCreate struct { - config - mutation *ChaincodeMutation - hooks []Hook -} - -// SetPackageId sets the "packageId" field. -func (cc *ChaincodeCreate) SetPackageId(s string) *ChaincodeCreate { - cc.mutation.SetPackageId(s) - return cc -} - -// SetChannelId sets the "channelId" field. -func (cc *ChaincodeCreate) SetChannelId(s string) *ChaincodeCreate { - cc.mutation.SetChannelId(s) - return cc -} - -// SetTenantID sets the "tenant" edge to the Tenant entity by ID. -func (cc *ChaincodeCreate) SetTenantID(id int) *ChaincodeCreate { - cc.mutation.SetTenantID(id) - return cc -} - -// SetNillableTenantID sets the "tenant" edge to the Tenant entity by ID if the given value is not nil. -func (cc *ChaincodeCreate) SetNillableTenantID(id *int) *ChaincodeCreate { - if id != nil { - cc = cc.SetTenantID(*id) - } - return cc -} - -// SetTenant sets the "tenant" edge to the Tenant entity. -func (cc *ChaincodeCreate) SetTenant(t *Tenant) *ChaincodeCreate { - return cc.SetTenantID(t.ID) -} - -// Mutation returns the ChaincodeMutation object of the builder. -func (cc *ChaincodeCreate) Mutation() *ChaincodeMutation { - return cc.mutation -} - -// Save creates the Chaincode in the database. -func (cc *ChaincodeCreate) Save(ctx context.Context) (*Chaincode, error) { - var ( - err error - node *Chaincode - ) - if len(cc.hooks) == 0 { - if err = cc.check(); err != nil { - return nil, err - } - node, err = cc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cc.check(); err != nil { - return nil, err - } - cc.mutation = mutation - if node, err = cc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(cc.hooks) - 1; i >= 0; i-- { - if cc.hooks[i] == nil { - return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = cc.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cc.mutation); err != nil { - return nil, err - } - } - return node, err -} - -// SaveX calls Save and panics if Save returns an error. -func (cc *ChaincodeCreate) SaveX(ctx context.Context) *Chaincode { - v, err := cc.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (cc *ChaincodeCreate) Exec(ctx context.Context) error { - _, err := cc.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (cc *ChaincodeCreate) ExecX(ctx context.Context) { - if err := cc.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (cc *ChaincodeCreate) check() error { - if _, ok := cc.mutation.PackageId(); !ok { - return &ValidationError{Name: "packageId", err: errors.New(`ent: missing required field "packageId"`)} - } - if v, ok := cc.mutation.PackageId(); ok { - if err := chaincode.PackageIdValidator(v); err != nil { - return &ValidationError{Name: "packageId", err: fmt.Errorf(`ent: validator failed for field "packageId": %w`, err)} - } - } - if _, ok := cc.mutation.ChannelId(); !ok { - return &ValidationError{Name: "channelId", err: errors.New(`ent: missing required field "channelId"`)} - } - return nil -} - -func (cc *ChaincodeCreate) sqlSave(ctx context.Context) (*Chaincode, error) { - _node, _spec := cc.createSpec() - if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return nil, err - } - id := _spec.ID.Value.(int64) - _node.ID = int(id) - return _node, nil -} - -func (cc *ChaincodeCreate) createSpec() (*Chaincode, *sqlgraph.CreateSpec) { - var ( - _node = &Chaincode{config: cc.config} - _spec = &sqlgraph.CreateSpec{ - Table: chaincode.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - } - ) - if value, ok := cc.mutation.PackageId(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldPackageId, - }) - _node.PackageId = value - } - if value, ok := cc.mutation.ChannelId(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldChannelId, - }) - _node.ChannelId = value - } - if nodes := cc.mutation.TenantIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: true, - Table: chaincode.TenantTable, - Columns: []string{chaincode.TenantColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _node.tenant_chaincodes = &nodes[0] - _spec.Edges = append(_spec.Edges, edge) - } - return _node, _spec -} - -// ChaincodeCreateBulk is the builder for creating many Chaincode entities in bulk. -type ChaincodeCreateBulk struct { - config - builders []*ChaincodeCreate -} - -// Save creates the Chaincode entities in the database. -func (ccb *ChaincodeCreateBulk) Save(ctx context.Context) ([]*Chaincode, error) { - specs := make([]*sqlgraph.CreateSpec, len(ccb.builders)) - nodes := make([]*Chaincode, len(ccb.builders)) - mutators := make([]Mutator, len(ccb.builders)) - for i := range ccb.builders { - func(i int, root context.Context) { - builder := ccb.builders[i] - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err := builder.check(); err != nil { - return nil, err - } - builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() - var err error - if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, ccb.builders[i+1].mutation) - } else { - spec := &sqlgraph.BatchCreateSpec{Nodes: specs} - // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, ccb.driver, spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - } - } - if err != nil { - return nil, err - } - mutation.id = &nodes[i].ID - mutation.done = true - if specs[i].ID.Value != nil { - id := specs[i].ID.Value.(int64) - nodes[i].ID = int(id) - } - return nodes[i], nil - }) - for i := len(builder.hooks) - 1; i >= 0; i-- { - mut = builder.hooks[i](mut) - } - mutators[i] = mut - }(i, ctx) - } - if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, ccb.builders[0].mutation); err != nil { - return nil, err - } - } - return nodes, nil -} - -// SaveX is like Save, but panics if an error occurs. -func (ccb *ChaincodeCreateBulk) SaveX(ctx context.Context) []*Chaincode { - v, err := ccb.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (ccb *ChaincodeCreateBulk) Exec(ctx context.Context) error { - _, err := ccb.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ccb *ChaincodeCreateBulk) ExecX(ctx context.Context) { - if err := ccb.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/chaincode_delete.go b/ent/chaincode_delete.go deleted file mode 100644 index d618c2e..0000000 --- a/ent/chaincode_delete.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" -) - -// ChaincodeDelete is the builder for deleting a Chaincode entity. -type ChaincodeDelete struct { - config - hooks []Hook - mutation *ChaincodeMutation -} - -// Where appends a list predicates to the ChaincodeDelete builder. -func (cd *ChaincodeDelete) Where(ps ...predicate.Chaincode) *ChaincodeDelete { - cd.mutation.Where(ps...) - return cd -} - -// Exec executes the deletion query and returns how many vertices were deleted. -func (cd *ChaincodeDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(cd.hooks) == 0 { - affected, err = cd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - cd.mutation = mutation - affected, err = cd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(cd.hooks) - 1; i >= 0; i-- { - if cd.hooks[i] == nil { - return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = cd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cd.mutation); err != nil { - return 0, err - } - } - return affected, err -} - -// ExecX is like Exec, but panics if an error occurs. -func (cd *ChaincodeDelete) ExecX(ctx context.Context) int { - n, err := cd.Exec(ctx) - if err != nil { - panic(err) - } - return n -} - -func (cd *ChaincodeDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: chaincode.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - if ps := cd.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return sqlgraph.DeleteNodes(ctx, cd.driver, _spec) -} - -// ChaincodeDeleteOne is the builder for deleting a single Chaincode entity. -type ChaincodeDeleteOne struct { - cd *ChaincodeDelete -} - -// Exec executes the deletion query. -func (cdo *ChaincodeDeleteOne) Exec(ctx context.Context) error { - n, err := cdo.cd.Exec(ctx) - switch { - case err != nil: - return err - case n == 0: - return &NotFoundError{chaincode.Label} - default: - return nil - } -} - -// ExecX is like Exec, but panics if an error occurs. -func (cdo *ChaincodeDeleteOne) ExecX(ctx context.Context) { - cdo.cd.ExecX(ctx) -} diff --git a/ent/chaincode_query.go b/ent/chaincode_query.go deleted file mode 100644 index 79d1aef..0000000 --- a/ent/chaincode_query.go +++ /dev/null @@ -1,994 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - "math" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// ChaincodeQuery is the builder for querying Chaincode entities. -type ChaincodeQuery struct { - config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string - predicates []predicate.Chaincode - // eager-loading edges. - withTenant *TenantQuery - withFKs bool - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Where adds a new predicate for the ChaincodeQuery builder. -func (cq *ChaincodeQuery) Where(ps ...predicate.Chaincode) *ChaincodeQuery { - cq.predicates = append(cq.predicates, ps...) - return cq -} - -// Limit adds a limit step to the query. -func (cq *ChaincodeQuery) Limit(limit int) *ChaincodeQuery { - cq.limit = &limit - return cq -} - -// Offset adds an offset step to the query. -func (cq *ChaincodeQuery) Offset(offset int) *ChaincodeQuery { - cq.offset = &offset - return cq -} - -// Unique configures the query builder to filter duplicate records on query. -// By default, unique is set to true, and can be disabled using this method. -func (cq *ChaincodeQuery) Unique(unique bool) *ChaincodeQuery { - cq.unique = &unique - return cq -} - -// Order adds an order step to the query. -func (cq *ChaincodeQuery) Order(o ...OrderFunc) *ChaincodeQuery { - cq.order = append(cq.order, o...) - return cq -} - -// QueryTenant chains the current query on the "tenant" edge. -func (cq *ChaincodeQuery) QueryTenant() *TenantQuery { - query := &TenantQuery{config: cq.config} - query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { - if err := cq.prepareQuery(ctx); err != nil { - return nil, err - } - selector := cq.sqlQuery(ctx) - if err := selector.Err(); err != nil { - return nil, err - } - step := sqlgraph.NewStep( - sqlgraph.From(chaincode.Table, chaincode.FieldID, selector), - sqlgraph.To(tenant.Table, tenant.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, chaincode.TenantTable, chaincode.TenantColumn), - ) - fromU = sqlgraph.SetNeighbors(cq.driver.Dialect(), step) - return fromU, nil - } - return query -} - -// First returns the first Chaincode entity from the query. -// Returns a *NotFoundError when no Chaincode was found. -func (cq *ChaincodeQuery) First(ctx context.Context) (*Chaincode, error) { - nodes, err := cq.Limit(1).All(ctx) - if err != nil { - return nil, err - } - if len(nodes) == 0 { - return nil, &NotFoundError{chaincode.Label} - } - return nodes[0], nil -} - -// FirstX is like First, but panics if an error occurs. -func (cq *ChaincodeQuery) FirstX(ctx context.Context) *Chaincode { - node, err := cq.First(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return node -} - -// FirstID returns the first Chaincode ID from the query. -// Returns a *NotFoundError when no Chaincode ID was found. -func (cq *ChaincodeQuery) FirstID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = cq.Limit(1).IDs(ctx); err != nil { - return - } - if len(ids) == 0 { - err = &NotFoundError{chaincode.Label} - return - } - return ids[0], nil -} - -// FirstIDX is like FirstID, but panics if an error occurs. -func (cq *ChaincodeQuery) FirstIDX(ctx context.Context) int { - id, err := cq.FirstID(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return id -} - -// Only returns a single Chaincode entity found by the query, ensuring it only returns one. -// Returns a *NotSingularError when exactly one Chaincode entity is not found. -// Returns a *NotFoundError when no Chaincode entities are found. -func (cq *ChaincodeQuery) Only(ctx context.Context) (*Chaincode, error) { - nodes, err := cq.Limit(2).All(ctx) - if err != nil { - return nil, err - } - switch len(nodes) { - case 1: - return nodes[0], nil - case 0: - return nil, &NotFoundError{chaincode.Label} - default: - return nil, &NotSingularError{chaincode.Label} - } -} - -// OnlyX is like Only, but panics if an error occurs. -func (cq *ChaincodeQuery) OnlyX(ctx context.Context) *Chaincode { - node, err := cq.Only(ctx) - if err != nil { - panic(err) - } - return node -} - -// OnlyID is like Only, but returns the only Chaincode ID in the query. -// Returns a *NotSingularError when exactly one Chaincode ID is not found. -// Returns a *NotFoundError when no entities are found. -func (cq *ChaincodeQuery) OnlyID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = cq.Limit(2).IDs(ctx); err != nil { - return - } - switch len(ids) { - case 1: - id = ids[0] - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = &NotSingularError{chaincode.Label} - } - return -} - -// OnlyIDX is like OnlyID, but panics if an error occurs. -func (cq *ChaincodeQuery) OnlyIDX(ctx context.Context) int { - id, err := cq.OnlyID(ctx) - if err != nil { - panic(err) - } - return id -} - -// All executes the query and returns a list of Chaincodes. -func (cq *ChaincodeQuery) All(ctx context.Context) ([]*Chaincode, error) { - if err := cq.prepareQuery(ctx); err != nil { - return nil, err - } - return cq.sqlAll(ctx) -} - -// AllX is like All, but panics if an error occurs. -func (cq *ChaincodeQuery) AllX(ctx context.Context) []*Chaincode { - nodes, err := cq.All(ctx) - if err != nil { - panic(err) - } - return nodes -} - -// IDs executes the query and returns a list of Chaincode IDs. -func (cq *ChaincodeQuery) IDs(ctx context.Context) ([]int, error) { - var ids []int - if err := cq.Select(chaincode.FieldID).Scan(ctx, &ids); err != nil { - return nil, err - } - return ids, nil -} - -// IDsX is like IDs, but panics if an error occurs. -func (cq *ChaincodeQuery) IDsX(ctx context.Context) []int { - ids, err := cq.IDs(ctx) - if err != nil { - panic(err) - } - return ids -} - -// Count returns the count of the given query. -func (cq *ChaincodeQuery) Count(ctx context.Context) (int, error) { - if err := cq.prepareQuery(ctx); err != nil { - return 0, err - } - return cq.sqlCount(ctx) -} - -// CountX is like Count, but panics if an error occurs. -func (cq *ChaincodeQuery) CountX(ctx context.Context) int { - count, err := cq.Count(ctx) - if err != nil { - panic(err) - } - return count -} - -// Exist returns true if the query has elements in the graph. -func (cq *ChaincodeQuery) Exist(ctx context.Context) (bool, error) { - if err := cq.prepareQuery(ctx); err != nil { - return false, err - } - return cq.sqlExist(ctx) -} - -// ExistX is like Exist, but panics if an error occurs. -func (cq *ChaincodeQuery) ExistX(ctx context.Context) bool { - exist, err := cq.Exist(ctx) - if err != nil { - panic(err) - } - return exist -} - -// Clone returns a duplicate of the ChaincodeQuery builder, including all associated steps. It can be -// used to prepare common query builders and use them differently after the clone is made. -func (cq *ChaincodeQuery) Clone() *ChaincodeQuery { - if cq == nil { - return nil - } - return &ChaincodeQuery{ - config: cq.config, - limit: cq.limit, - offset: cq.offset, - order: append([]OrderFunc{}, cq.order...), - predicates: append([]predicate.Chaincode{}, cq.predicates...), - withTenant: cq.withTenant.Clone(), - // clone intermediate query. - sql: cq.sql.Clone(), - path: cq.path, - } -} - -// WithTenant tells the query-builder to eager-load the nodes that are connected to -// the "tenant" edge. The optional arguments are used to configure the query builder of the edge. -func (cq *ChaincodeQuery) WithTenant(opts ...func(*TenantQuery)) *ChaincodeQuery { - query := &TenantQuery{config: cq.config} - for _, opt := range opts { - opt(query) - } - cq.withTenant = query - return cq -} - -// GroupBy is used to group vertices by one or more fields/columns. -// It is often used with aggregate functions, like: count, max, mean, min, sum. -// -// Example: -// -// var v []struct { -// PackageId string `json:"packageId,omitempty"` -// Count int `json:"count,omitempty"` -// } -// -// client.Chaincode.Query(). -// GroupBy(chaincode.FieldPackageId). -// Aggregate(ent.Count()). -// Scan(ctx, &v) -// -func (cq *ChaincodeQuery) GroupBy(field string, fields ...string) *ChaincodeGroupBy { - group := &ChaincodeGroupBy{config: cq.config} - group.fields = append([]string{field}, fields...) - group.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := cq.prepareQuery(ctx); err != nil { - return nil, err - } - return cq.sqlQuery(ctx), nil - } - return group -} - -// Select allows the selection one or more fields/columns for the given query, -// instead of selecting all fields in the entity. -// -// Example: -// -// var v []struct { -// PackageId string `json:"packageId,omitempty"` -// } -// -// client.Chaincode.Query(). -// Select(chaincode.FieldPackageId). -// Scan(ctx, &v) -// -func (cq *ChaincodeQuery) Select(fields ...string) *ChaincodeSelect { - cq.fields = append(cq.fields, fields...) - return &ChaincodeSelect{ChaincodeQuery: cq} -} - -func (cq *ChaincodeQuery) prepareQuery(ctx context.Context) error { - for _, f := range cq.fields { - if !chaincode.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - } - if cq.path != nil { - prev, err := cq.path(ctx) - if err != nil { - return err - } - cq.sql = prev - } - return nil -} - -func (cq *ChaincodeQuery) sqlAll(ctx context.Context) ([]*Chaincode, error) { - var ( - nodes = []*Chaincode{} - withFKs = cq.withFKs - _spec = cq.querySpec() - loadedTypes = [1]bool{ - cq.withTenant != nil, - } - ) - if cq.withTenant != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, chaincode.ForeignKeys...) - } - _spec.ScanValues = func(columns []string) ([]interface{}, error) { - node := &Chaincode{config: cq.config} - nodes = append(nodes, node) - return node.scanValues(columns) - } - _spec.Assign = func(columns []string, values []interface{}) error { - if len(nodes) == 0 { - return fmt.Errorf("ent: Assign called without calling ScanValues") - } - node := nodes[len(nodes)-1] - node.Edges.loadedTypes = loadedTypes - return node.assignValues(columns, values) - } - if err := sqlgraph.QueryNodes(ctx, cq.driver, _spec); err != nil { - return nil, err - } - if len(nodes) == 0 { - return nodes, nil - } - - if query := cq.withTenant; query != nil { - ids := make([]int, 0, len(nodes)) - nodeids := make(map[int][]*Chaincode) - for i := range nodes { - if nodes[i].tenant_chaincodes == nil { - continue - } - fk := *nodes[i].tenant_chaincodes - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) - } - query.Where(tenant.IDIn(ids...)) - neighbors, err := query.All(ctx) - if err != nil { - return nil, err - } - for _, n := range neighbors { - nodes, ok := nodeids[n.ID] - if !ok { - return nil, fmt.Errorf(`unexpected foreign-key "tenant_chaincodes" returned %v`, n.ID) - } - for i := range nodes { - nodes[i].Edges.Tenant = n - } - } - } - - return nodes, nil -} - -func (cq *ChaincodeQuery) sqlCount(ctx context.Context) (int, error) { - _spec := cq.querySpec() - return sqlgraph.CountNodes(ctx, cq.driver, _spec) -} - -func (cq *ChaincodeQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := cq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("ent: check existence: %w", err) - } - return n > 0, nil -} - -func (cq *ChaincodeQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: chaincode.Table, - Columns: chaincode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - From: cq.sql, - Unique: true, - } - if unique := cq.unique; unique != nil { - _spec.Unique = *unique - } - if fields := cq.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, chaincode.FieldID) - for i := range fields { - if fields[i] != chaincode.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) - } - } - } - if ps := cq.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if limit := cq.limit; limit != nil { - _spec.Limit = *limit - } - if offset := cq.offset; offset != nil { - _spec.Offset = *offset - } - if ps := cq.order; len(ps) > 0 { - _spec.Order = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return _spec -} - -func (cq *ChaincodeQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(cq.driver.Dialect()) - t1 := builder.Table(chaincode.Table) - columns := cq.fields - if len(columns) == 0 { - columns = chaincode.Columns - } - selector := builder.Select(t1.Columns(columns...)...).From(t1) - if cq.sql != nil { - selector = cq.sql - selector.Select(selector.Columns(columns...)...) - } - for _, p := range cq.predicates { - p(selector) - } - for _, p := range cq.order { - p(selector) - } - if offset := cq.offset; offset != nil { - // limit is mandatory for offset clause. We start - // with default value, and override it below if needed. - selector.Offset(*offset).Limit(math.MaxInt32) - } - if limit := cq.limit; limit != nil { - selector.Limit(*limit) - } - return selector -} - -// ChaincodeGroupBy is the group-by builder for Chaincode entities. -type ChaincodeGroupBy struct { - config - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Aggregate adds the given aggregation functions to the group-by query. -func (cgb *ChaincodeGroupBy) Aggregate(fns ...AggregateFunc) *ChaincodeGroupBy { - cgb.fns = append(cgb.fns, fns...) - return cgb -} - -// Scan applies the group-by query and scans the result into the given value. -func (cgb *ChaincodeGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := cgb.path(ctx) - if err != nil { - return err - } - cgb.sql = query - return cgb.sqlScan(ctx, v) -} - -// ScanX is like Scan, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) ScanX(ctx context.Context, v interface{}) { - if err := cgb.Scan(ctx, v); err != nil { - panic(err) - } -} - -// Strings returns list of strings from group-by. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Strings(ctx context.Context) ([]string, error) { - if len(cgb.fields) > 1 { - return nil, errors.New("ent: ChaincodeGroupBy.Strings is not achievable when grouping more than 1 field") - } - var v []string - if err := cgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// StringsX is like Strings, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) StringsX(ctx context.Context) []string { - v, err := cgb.Strings(ctx) - if err != nil { - panic(err) - } - return v -} - -// String returns a single string from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) String(ctx context.Context) (_ string, err error) { - var v []string - if v, err = cgb.Strings(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeGroupBy.Strings returned %d results when one was expected", len(v)) - } - return -} - -// StringX is like String, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) StringX(ctx context.Context) string { - v, err := cgb.String(ctx) - if err != nil { - panic(err) - } - return v -} - -// Ints returns list of ints from group-by. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Ints(ctx context.Context) ([]int, error) { - if len(cgb.fields) > 1 { - return nil, errors.New("ent: ChaincodeGroupBy.Ints is not achievable when grouping more than 1 field") - } - var v []int - if err := cgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// IntsX is like Ints, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) IntsX(ctx context.Context) []int { - v, err := cgb.Ints(ctx) - if err != nil { - panic(err) - } - return v -} - -// Int returns a single int from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Int(ctx context.Context) (_ int, err error) { - var v []int - if v, err = cgb.Ints(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeGroupBy.Ints returned %d results when one was expected", len(v)) - } - return -} - -// IntX is like Int, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) IntX(ctx context.Context) int { - v, err := cgb.Int(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64s returns list of float64s from group-by. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Float64s(ctx context.Context) ([]float64, error) { - if len(cgb.fields) > 1 { - return nil, errors.New("ent: ChaincodeGroupBy.Float64s is not achievable when grouping more than 1 field") - } - var v []float64 - if err := cgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// Float64sX is like Float64s, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) Float64sX(ctx context.Context) []float64 { - v, err := cgb.Float64s(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64 returns a single float64 from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Float64(ctx context.Context) (_ float64, err error) { - var v []float64 - if v, err = cgb.Float64s(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeGroupBy.Float64s returned %d results when one was expected", len(v)) - } - return -} - -// Float64X is like Float64, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) Float64X(ctx context.Context) float64 { - v, err := cgb.Float64(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bools returns list of bools from group-by. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Bools(ctx context.Context) ([]bool, error) { - if len(cgb.fields) > 1 { - return nil, errors.New("ent: ChaincodeGroupBy.Bools is not achievable when grouping more than 1 field") - } - var v []bool - if err := cgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// BoolsX is like Bools, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) BoolsX(ctx context.Context) []bool { - v, err := cgb.Bools(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bool returns a single bool from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (cgb *ChaincodeGroupBy) Bool(ctx context.Context) (_ bool, err error) { - var v []bool - if v, err = cgb.Bools(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeGroupBy.Bools returned %d results when one was expected", len(v)) - } - return -} - -// BoolX is like Bool, but panics if an error occurs. -func (cgb *ChaincodeGroupBy) BoolX(ctx context.Context) bool { - v, err := cgb.Bool(ctx) - if err != nil { - panic(err) - } - return v -} - -func (cgb *ChaincodeGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range cgb.fields { - if !chaincode.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} - } - } - selector := cgb.sqlQuery() - if err := selector.Err(); err != nil { - return err - } - rows := &sql.Rows{} - query, args := selector.Query() - if err := cgb.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} - -func (cgb *ChaincodeGroupBy) sqlQuery() *sql.Selector { - selector := cgb.sql.Select() - aggregation := make([]string, 0, len(cgb.fns)) - for _, fn := range cgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(cgb.fields)+len(cgb.fns)) - for _, f := range cgb.fields { - columns = append(columns, selector.C(f)) - } - for _, c := range aggregation { - columns = append(columns, c) - } - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(cgb.fields...)...) -} - -// ChaincodeSelect is the builder for selecting fields of Chaincode entities. -type ChaincodeSelect struct { - *ChaincodeQuery - // intermediate query (i.e. traversal path). - sql *sql.Selector -} - -// Scan applies the selector query and scans the result into the given value. -func (cs *ChaincodeSelect) Scan(ctx context.Context, v interface{}) error { - if err := cs.prepareQuery(ctx); err != nil { - return err - } - cs.sql = cs.ChaincodeQuery.sqlQuery(ctx) - return cs.sqlScan(ctx, v) -} - -// ScanX is like Scan, but panics if an error occurs. -func (cs *ChaincodeSelect) ScanX(ctx context.Context, v interface{}) { - if err := cs.Scan(ctx, v); err != nil { - panic(err) - } -} - -// Strings returns list of strings from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Strings(ctx context.Context) ([]string, error) { - if len(cs.fields) > 1 { - return nil, errors.New("ent: ChaincodeSelect.Strings is not achievable when selecting more than 1 field") - } - var v []string - if err := cs.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// StringsX is like Strings, but panics if an error occurs. -func (cs *ChaincodeSelect) StringsX(ctx context.Context) []string { - v, err := cs.Strings(ctx) - if err != nil { - panic(err) - } - return v -} - -// String returns a single string from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) String(ctx context.Context) (_ string, err error) { - var v []string - if v, err = cs.Strings(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeSelect.Strings returned %d results when one was expected", len(v)) - } - return -} - -// StringX is like String, but panics if an error occurs. -func (cs *ChaincodeSelect) StringX(ctx context.Context) string { - v, err := cs.String(ctx) - if err != nil { - panic(err) - } - return v -} - -// Ints returns list of ints from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Ints(ctx context.Context) ([]int, error) { - if len(cs.fields) > 1 { - return nil, errors.New("ent: ChaincodeSelect.Ints is not achievable when selecting more than 1 field") - } - var v []int - if err := cs.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// IntsX is like Ints, but panics if an error occurs. -func (cs *ChaincodeSelect) IntsX(ctx context.Context) []int { - v, err := cs.Ints(ctx) - if err != nil { - panic(err) - } - return v -} - -// Int returns a single int from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Int(ctx context.Context) (_ int, err error) { - var v []int - if v, err = cs.Ints(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeSelect.Ints returned %d results when one was expected", len(v)) - } - return -} - -// IntX is like Int, but panics if an error occurs. -func (cs *ChaincodeSelect) IntX(ctx context.Context) int { - v, err := cs.Int(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64s returns list of float64s from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Float64s(ctx context.Context) ([]float64, error) { - if len(cs.fields) > 1 { - return nil, errors.New("ent: ChaincodeSelect.Float64s is not achievable when selecting more than 1 field") - } - var v []float64 - if err := cs.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// Float64sX is like Float64s, but panics if an error occurs. -func (cs *ChaincodeSelect) Float64sX(ctx context.Context) []float64 { - v, err := cs.Float64s(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64 returns a single float64 from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Float64(ctx context.Context) (_ float64, err error) { - var v []float64 - if v, err = cs.Float64s(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeSelect.Float64s returned %d results when one was expected", len(v)) - } - return -} - -// Float64X is like Float64, but panics if an error occurs. -func (cs *ChaincodeSelect) Float64X(ctx context.Context) float64 { - v, err := cs.Float64(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bools returns list of bools from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Bools(ctx context.Context) ([]bool, error) { - if len(cs.fields) > 1 { - return nil, errors.New("ent: ChaincodeSelect.Bools is not achievable when selecting more than 1 field") - } - var v []bool - if err := cs.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// BoolsX is like Bools, but panics if an error occurs. -func (cs *ChaincodeSelect) BoolsX(ctx context.Context) []bool { - v, err := cs.Bools(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bool returns a single bool from a selector. It is only allowed when selecting one field. -func (cs *ChaincodeSelect) Bool(ctx context.Context) (_ bool, err error) { - var v []bool - if v, err = cs.Bools(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{chaincode.Label} - default: - err = fmt.Errorf("ent: ChaincodeSelect.Bools returned %d results when one was expected", len(v)) - } - return -} - -// BoolX is like Bool, but panics if an error occurs. -func (cs *ChaincodeSelect) BoolX(ctx context.Context) bool { - v, err := cs.Bool(ctx) - if err != nil { - panic(err) - } - return v -} - -func (cs *ChaincodeSelect) sqlScan(ctx context.Context, v interface{}) error { - rows := &sql.Rows{} - query, args := cs.sql.Query() - if err := cs.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} diff --git a/ent/chaincode_update.go b/ent/chaincode_update.go deleted file mode 100644 index 985cc7e..0000000 --- a/ent/chaincode_update.go +++ /dev/null @@ -1,443 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// ChaincodeUpdate is the builder for updating Chaincode entities. -type ChaincodeUpdate struct { - config - hooks []Hook - mutation *ChaincodeMutation -} - -// Where appends a list predicates to the ChaincodeUpdate builder. -func (cu *ChaincodeUpdate) Where(ps ...predicate.Chaincode) *ChaincodeUpdate { - cu.mutation.Where(ps...) - return cu -} - -// SetPackageId sets the "packageId" field. -func (cu *ChaincodeUpdate) SetPackageId(s string) *ChaincodeUpdate { - cu.mutation.SetPackageId(s) - return cu -} - -// SetChannelId sets the "channelId" field. -func (cu *ChaincodeUpdate) SetChannelId(s string) *ChaincodeUpdate { - cu.mutation.SetChannelId(s) - return cu -} - -// SetTenantID sets the "tenant" edge to the Tenant entity by ID. -func (cu *ChaincodeUpdate) SetTenantID(id int) *ChaincodeUpdate { - cu.mutation.SetTenantID(id) - return cu -} - -// SetNillableTenantID sets the "tenant" edge to the Tenant entity by ID if the given value is not nil. -func (cu *ChaincodeUpdate) SetNillableTenantID(id *int) *ChaincodeUpdate { - if id != nil { - cu = cu.SetTenantID(*id) - } - return cu -} - -// SetTenant sets the "tenant" edge to the Tenant entity. -func (cu *ChaincodeUpdate) SetTenant(t *Tenant) *ChaincodeUpdate { - return cu.SetTenantID(t.ID) -} - -// Mutation returns the ChaincodeMutation object of the builder. -func (cu *ChaincodeUpdate) Mutation() *ChaincodeMutation { - return cu.mutation -} - -// ClearTenant clears the "tenant" edge to the Tenant entity. -func (cu *ChaincodeUpdate) ClearTenant() *ChaincodeUpdate { - cu.mutation.ClearTenant() - return cu -} - -// Save executes the query and returns the number of nodes affected by the update operation. -func (cu *ChaincodeUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(cu.hooks) == 0 { - if err = cu.check(); err != nil { - return 0, err - } - affected, err = cu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cu.check(); err != nil { - return 0, err - } - cu.mutation = mutation - affected, err = cu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(cu.hooks) - 1; i >= 0; i-- { - if cu.hooks[i] == nil { - return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = cu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cu.mutation); err != nil { - return 0, err - } - } - return affected, err -} - -// SaveX is like Save, but panics if an error occurs. -func (cu *ChaincodeUpdate) SaveX(ctx context.Context) int { - affected, err := cu.Save(ctx) - if err != nil { - panic(err) - } - return affected -} - -// Exec executes the query. -func (cu *ChaincodeUpdate) Exec(ctx context.Context) error { - _, err := cu.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (cu *ChaincodeUpdate) ExecX(ctx context.Context) { - if err := cu.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (cu *ChaincodeUpdate) check() error { - if v, ok := cu.mutation.PackageId(); ok { - if err := chaincode.PackageIdValidator(v); err != nil { - return &ValidationError{Name: "packageId", err: fmt.Errorf("ent: validator failed for field \"packageId\": %w", err)} - } - } - return nil -} - -func (cu *ChaincodeUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: chaincode.Table, - Columns: chaincode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - if ps := cu.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := cu.mutation.PackageId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldPackageId, - }) - } - if value, ok := cu.mutation.ChannelId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldChannelId, - }) - } - if cu.mutation.TenantCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: true, - Table: chaincode.TenantTable, - Columns: []string{chaincode.TenantColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := cu.mutation.TenantIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: true, - Table: chaincode.TenantTable, - Columns: []string{chaincode.TenantColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - if n, err = sqlgraph.UpdateNodes(ctx, cu.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{chaincode.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return 0, err - } - return n, nil -} - -// ChaincodeUpdateOne is the builder for updating a single Chaincode entity. -type ChaincodeUpdateOne struct { - config - fields []string - hooks []Hook - mutation *ChaincodeMutation -} - -// SetPackageId sets the "packageId" field. -func (cuo *ChaincodeUpdateOne) SetPackageId(s string) *ChaincodeUpdateOne { - cuo.mutation.SetPackageId(s) - return cuo -} - -// SetChannelId sets the "channelId" field. -func (cuo *ChaincodeUpdateOne) SetChannelId(s string) *ChaincodeUpdateOne { - cuo.mutation.SetChannelId(s) - return cuo -} - -// SetTenantID sets the "tenant" edge to the Tenant entity by ID. -func (cuo *ChaincodeUpdateOne) SetTenantID(id int) *ChaincodeUpdateOne { - cuo.mutation.SetTenantID(id) - return cuo -} - -// SetNillableTenantID sets the "tenant" edge to the Tenant entity by ID if the given value is not nil. -func (cuo *ChaincodeUpdateOne) SetNillableTenantID(id *int) *ChaincodeUpdateOne { - if id != nil { - cuo = cuo.SetTenantID(*id) - } - return cuo -} - -// SetTenant sets the "tenant" edge to the Tenant entity. -func (cuo *ChaincodeUpdateOne) SetTenant(t *Tenant) *ChaincodeUpdateOne { - return cuo.SetTenantID(t.ID) -} - -// Mutation returns the ChaincodeMutation object of the builder. -func (cuo *ChaincodeUpdateOne) Mutation() *ChaincodeMutation { - return cuo.mutation -} - -// ClearTenant clears the "tenant" edge to the Tenant entity. -func (cuo *ChaincodeUpdateOne) ClearTenant() *ChaincodeUpdateOne { - cuo.mutation.ClearTenant() - return cuo -} - -// Select allows selecting one or more fields (columns) of the returned entity. -// The default is selecting all fields defined in the entity schema. -func (cuo *ChaincodeUpdateOne) Select(field string, fields ...string) *ChaincodeUpdateOne { - cuo.fields = append([]string{field}, fields...) - return cuo -} - -// Save executes the query and returns the updated Chaincode entity. -func (cuo *ChaincodeUpdateOne) Save(ctx context.Context) (*Chaincode, error) { - var ( - err error - node *Chaincode - ) - if len(cuo.hooks) == 0 { - if err = cuo.check(); err != nil { - return nil, err - } - node, err = cuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cuo.check(); err != nil { - return nil, err - } - cuo.mutation = mutation - node, err = cuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(cuo.hooks) - 1; i >= 0; i-- { - if cuo.hooks[i] == nil { - return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = cuo.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cuo.mutation); err != nil { - return nil, err - } - } - return node, err -} - -// SaveX is like Save, but panics if an error occurs. -func (cuo *ChaincodeUpdateOne) SaveX(ctx context.Context) *Chaincode { - node, err := cuo.Save(ctx) - if err != nil { - panic(err) - } - return node -} - -// Exec executes the query on the entity. -func (cuo *ChaincodeUpdateOne) Exec(ctx context.Context) error { - _, err := cuo.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (cuo *ChaincodeUpdateOne) ExecX(ctx context.Context) { - if err := cuo.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (cuo *ChaincodeUpdateOne) check() error { - if v, ok := cuo.mutation.PackageId(); ok { - if err := chaincode.PackageIdValidator(v); err != nil { - return &ValidationError{Name: "packageId", err: fmt.Errorf("ent: validator failed for field \"packageId\": %w", err)} - } - } - return nil -} - -func (cuo *ChaincodeUpdateOne) sqlSave(ctx context.Context) (_node *Chaincode, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: chaincode.Table, - Columns: chaincode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - id, ok := cuo.mutation.ID() - if !ok { - return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Chaincode.ID for update")} - } - _spec.Node.ID.Value = id - if fields := cuo.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, chaincode.FieldID) - for _, f := range fields { - if !chaincode.ValidColumn(f) { - return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - if f != chaincode.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, f) - } - } - } - if ps := cuo.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := cuo.mutation.PackageId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldPackageId, - }) - } - if value, ok := cuo.mutation.ChannelId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: chaincode.FieldChannelId, - }) - } - if cuo.mutation.TenantCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: true, - Table: chaincode.TenantTable, - Columns: []string{chaincode.TenantColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := cuo.mutation.TenantIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: true, - Table: chaincode.TenantTable, - Columns: []string{chaincode.TenantColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - _node = &Chaincode{config: cuo.config} - _spec.Assign = _node.assignValues - _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, cuo.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{chaincode.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return nil, err - } - return _node, nil -} diff --git a/ent/client.go b/ent/client.go deleted file mode 100644 index ec6324e..0000000 --- a/ent/client.go +++ /dev/null @@ -1,342 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - "log" - - "github.com/kfsoftware/hlf-cc-dev/ent/migrate" - - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" - - "entgo.io/ent/dialect" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" -) - -// Client is the client that holds all ent builders. -type Client struct { - config - // Schema is the client for creating, migrating and dropping schema. - Schema *migrate.Schema - // Chaincode is the client for interacting with the Chaincode builders. - Chaincode *ChaincodeClient - // Tenant is the client for interacting with the Tenant builders. - Tenant *TenantClient -} - -// NewClient creates a new client configured with the given options. -func NewClient(opts ...Option) *Client { - cfg := config{log: log.Println, hooks: &hooks{}} - cfg.options(opts...) - client := &Client{config: cfg} - client.init() - return client -} - -func (c *Client) init() { - c.Schema = migrate.NewSchema(c.driver) - c.Chaincode = NewChaincodeClient(c.config) - c.Tenant = NewTenantClient(c.config) -} - -// Open opens a database/sql.DB specified by the driver name and -// the data source name, and returns a new client attached to it. -// Optional parameters can be added for configuring the client. -func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { - switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: - drv, err := sql.Open(driverName, dataSourceName) - if err != nil { - return nil, err - } - return NewClient(append(options, Driver(drv))...), nil - default: - return nil, fmt.Errorf("unsupported driver: %q", driverName) - } -} - -// Tx returns a new transactional client. The provided context -// is used until the transaction is committed or rolled back. -func (c *Client) Tx(ctx context.Context) (*Tx, error) { - if _, ok := c.driver.(*txDriver); ok { - return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") - } - tx, err := newTx(ctx, c.driver) - if err != nil { - return nil, fmt.Errorf("ent: starting a transaction: %w", err) - } - cfg := c.config - cfg.driver = tx - return &Tx{ - ctx: ctx, - config: cfg, - Chaincode: NewChaincodeClient(cfg), - Tenant: NewTenantClient(cfg), - }, nil -} - -// BeginTx returns a transactional client with specified options. -func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { - if _, ok := c.driver.(*txDriver); ok { - return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") - } - tx, err := c.driver.(interface { - BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error) - }).BeginTx(ctx, opts) - if err != nil { - return nil, fmt.Errorf("ent: starting a transaction: %w", err) - } - cfg := c.config - cfg.driver = &txDriver{tx: tx, drv: c.driver} - return &Tx{ - config: cfg, - Chaincode: NewChaincodeClient(cfg), - Tenant: NewTenantClient(cfg), - }, nil -} - -// Debug returns a new debug-client. It's used to get verbose logging on specific operations. -// -// client.Debug(). -// Chaincode. -// Query(). -// Count(ctx) -// -func (c *Client) Debug() *Client { - if c.debug { - return c - } - cfg := c.config - cfg.driver = dialect.Debug(c.driver, c.log) - client := &Client{config: cfg} - client.init() - return client -} - -// Close closes the database connection and prevents new queries from starting. -func (c *Client) Close() error { - return c.driver.Close() -} - -// Use adds the mutation hooks to all the entity clients. -// In order to add hooks to a specific client, call: `client.Node.Use(...)`. -func (c *Client) Use(hooks ...Hook) { - c.Chaincode.Use(hooks...) - c.Tenant.Use(hooks...) -} - -// ChaincodeClient is a client for the Chaincode schema. -type ChaincodeClient struct { - config -} - -// NewChaincodeClient returns a client for the Chaincode from the given config. -func NewChaincodeClient(c config) *ChaincodeClient { - return &ChaincodeClient{config: c} -} - -// Use adds a list of mutation hooks to the hooks stack. -// A call to `Use(f, g, h)` equals to `chaincode.Hooks(f(g(h())))`. -func (c *ChaincodeClient) Use(hooks ...Hook) { - c.hooks.Chaincode = append(c.hooks.Chaincode, hooks...) -} - -// Create returns a create builder for Chaincode. -func (c *ChaincodeClient) Create() *ChaincodeCreate { - mutation := newChaincodeMutation(c.config, OpCreate) - return &ChaincodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// CreateBulk returns a builder for creating a bulk of Chaincode entities. -func (c *ChaincodeClient) CreateBulk(builders ...*ChaincodeCreate) *ChaincodeCreateBulk { - return &ChaincodeCreateBulk{config: c.config, builders: builders} -} - -// Update returns an update builder for Chaincode. -func (c *ChaincodeClient) Update() *ChaincodeUpdate { - mutation := newChaincodeMutation(c.config, OpUpdate) - return &ChaincodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOne returns an update builder for the given entity. -func (c *ChaincodeClient) UpdateOne(ch *Chaincode) *ChaincodeUpdateOne { - mutation := newChaincodeMutation(c.config, OpUpdateOne, withChaincode(ch)) - return &ChaincodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOneID returns an update builder for the given id. -func (c *ChaincodeClient) UpdateOneID(id int) *ChaincodeUpdateOne { - mutation := newChaincodeMutation(c.config, OpUpdateOne, withChaincodeID(id)) - return &ChaincodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// Delete returns a delete builder for Chaincode. -func (c *ChaincodeClient) Delete() *ChaincodeDelete { - mutation := newChaincodeMutation(c.config, OpDelete) - return &ChaincodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// DeleteOne returns a delete builder for the given entity. -func (c *ChaincodeClient) DeleteOne(ch *Chaincode) *ChaincodeDeleteOne { - return c.DeleteOneID(ch.ID) -} - -// DeleteOneID returns a delete builder for the given id. -func (c *ChaincodeClient) DeleteOneID(id int) *ChaincodeDeleteOne { - builder := c.Delete().Where(chaincode.ID(id)) - builder.mutation.id = &id - builder.mutation.op = OpDeleteOne - return &ChaincodeDeleteOne{builder} -} - -// Query returns a query builder for Chaincode. -func (c *ChaincodeClient) Query() *ChaincodeQuery { - return &ChaincodeQuery{ - config: c.config, - } -} - -// Get returns a Chaincode entity by its id. -func (c *ChaincodeClient) Get(ctx context.Context, id int) (*Chaincode, error) { - return c.Query().Where(chaincode.ID(id)).Only(ctx) -} - -// GetX is like Get, but panics if an error occurs. -func (c *ChaincodeClient) GetX(ctx context.Context, id int) *Chaincode { - obj, err := c.Get(ctx, id) - if err != nil { - panic(err) - } - return obj -} - -// QueryTenant queries the tenant edge of a Chaincode. -func (c *ChaincodeClient) QueryTenant(ch *Chaincode) *TenantQuery { - query := &TenantQuery{config: c.config} - query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { - id := ch.ID - step := sqlgraph.NewStep( - sqlgraph.From(chaincode.Table, chaincode.FieldID, id), - sqlgraph.To(tenant.Table, tenant.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, chaincode.TenantTable, chaincode.TenantColumn), - ) - fromV = sqlgraph.Neighbors(ch.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// Hooks returns the client hooks. -func (c *ChaincodeClient) Hooks() []Hook { - return c.hooks.Chaincode -} - -// TenantClient is a client for the Tenant schema. -type TenantClient struct { - config -} - -// NewTenantClient returns a client for the Tenant from the given config. -func NewTenantClient(c config) *TenantClient { - return &TenantClient{config: c} -} - -// Use adds a list of mutation hooks to the hooks stack. -// A call to `Use(f, g, h)` equals to `tenant.Hooks(f(g(h())))`. -func (c *TenantClient) Use(hooks ...Hook) { - c.hooks.Tenant = append(c.hooks.Tenant, hooks...) -} - -// Create returns a create builder for Tenant. -func (c *TenantClient) Create() *TenantCreate { - mutation := newTenantMutation(c.config, OpCreate) - return &TenantCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// CreateBulk returns a builder for creating a bulk of Tenant entities. -func (c *TenantClient) CreateBulk(builders ...*TenantCreate) *TenantCreateBulk { - return &TenantCreateBulk{config: c.config, builders: builders} -} - -// Update returns an update builder for Tenant. -func (c *TenantClient) Update() *TenantUpdate { - mutation := newTenantMutation(c.config, OpUpdate) - return &TenantUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOne returns an update builder for the given entity. -func (c *TenantClient) UpdateOne(t *Tenant) *TenantUpdateOne { - mutation := newTenantMutation(c.config, OpUpdateOne, withTenant(t)) - return &TenantUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOneID returns an update builder for the given id. -func (c *TenantClient) UpdateOneID(id int) *TenantUpdateOne { - mutation := newTenantMutation(c.config, OpUpdateOne, withTenantID(id)) - return &TenantUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// Delete returns a delete builder for Tenant. -func (c *TenantClient) Delete() *TenantDelete { - mutation := newTenantMutation(c.config, OpDelete) - return &TenantDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// DeleteOne returns a delete builder for the given entity. -func (c *TenantClient) DeleteOne(t *Tenant) *TenantDeleteOne { - return c.DeleteOneID(t.ID) -} - -// DeleteOneID returns a delete builder for the given id. -func (c *TenantClient) DeleteOneID(id int) *TenantDeleteOne { - builder := c.Delete().Where(tenant.ID(id)) - builder.mutation.id = &id - builder.mutation.op = OpDeleteOne - return &TenantDeleteOne{builder} -} - -// Query returns a query builder for Tenant. -func (c *TenantClient) Query() *TenantQuery { - return &TenantQuery{ - config: c.config, - } -} - -// Get returns a Tenant entity by its id. -func (c *TenantClient) Get(ctx context.Context, id int) (*Tenant, error) { - return c.Query().Where(tenant.ID(id)).Only(ctx) -} - -// GetX is like Get, but panics if an error occurs. -func (c *TenantClient) GetX(ctx context.Context, id int) *Tenant { - obj, err := c.Get(ctx, id) - if err != nil { - panic(err) - } - return obj -} - -// QueryChaincodes queries the chaincodes edge of a Tenant. -func (c *TenantClient) QueryChaincodes(t *Tenant) *ChaincodeQuery { - query := &ChaincodeQuery{config: c.config} - query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { - id := t.ID - step := sqlgraph.NewStep( - sqlgraph.From(tenant.Table, tenant.FieldID, id), - sqlgraph.To(chaincode.Table, chaincode.FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, tenant.ChaincodesTable, tenant.ChaincodesColumn), - ) - fromV = sqlgraph.Neighbors(t.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// Hooks returns the client hooks. -func (c *TenantClient) Hooks() []Hook { - return c.hooks.Tenant -} diff --git a/ent/config.go b/ent/config.go deleted file mode 100644 index 7e7e042..0000000 --- a/ent/config.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "entgo.io/ent" - "entgo.io/ent/dialect" -) - -// Option function to configure the client. -type Option func(*config) - -// Config is the configuration for the client and its builder. -type config struct { - // driver used for executing database requests. - driver dialect.Driver - // debug enable a debug logging. - debug bool - // log used for logging on debug mode. - log func(...interface{}) - // hooks to execute on mutations. - hooks *hooks -} - -// hooks per client, for fast access. -type hooks struct { - Chaincode []ent.Hook - Tenant []ent.Hook -} - -// Options applies the options on the config object. -func (c *config) options(opts ...Option) { - for _, opt := range opts { - opt(c) - } - if c.debug { - c.driver = dialect.Debug(c.driver, c.log) - } -} - -// Debug enables debug logging on the ent.Driver. -func Debug() Option { - return func(c *config) { - c.debug = true - } -} - -// Log sets the logging function for debug mode. -func Log(fn func(...interface{})) Option { - return func(c *config) { - c.log = fn - } -} - -// Driver configures the client driver. -func Driver(driver dialect.Driver) Option { - return func(c *config) { - c.driver = driver - } -} diff --git a/ent/context.go b/ent/context.go deleted file mode 100644 index 0840726..0000000 --- a/ent/context.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" -) - -type clientCtxKey struct{} - -// FromContext returns a Client stored inside a context, or nil if there isn't one. -func FromContext(ctx context.Context) *Client { - c, _ := ctx.Value(clientCtxKey{}).(*Client) - return c -} - -// NewContext returns a new context with the given Client attached. -func NewContext(parent context.Context, c *Client) context.Context { - return context.WithValue(parent, clientCtxKey{}, c) -} - -type txCtxKey struct{} - -// TxFromContext returns a Tx stored inside a context, or nil if there isn't one. -func TxFromContext(ctx context.Context) *Tx { - tx, _ := ctx.Value(txCtxKey{}).(*Tx) - return tx -} - -// NewTxContext returns a new context with the given Tx attached. -func NewTxContext(parent context.Context, tx *Tx) context.Context { - return context.WithValue(parent, txCtxKey{}, tx) -} diff --git a/ent/ent.go b/ent/ent.go deleted file mode 100644 index 2cc4f13..0000000 --- a/ent/ent.go +++ /dev/null @@ -1,261 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "errors" - "fmt" - - "entgo.io/ent" - "entgo.io/ent/dialect/sql" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// ent aliases to avoid import conflicts in user's code. -type ( - Op = ent.Op - Hook = ent.Hook - Value = ent.Value - Query = ent.Query - Policy = ent.Policy - Mutator = ent.Mutator - Mutation = ent.Mutation - MutateFunc = ent.MutateFunc -) - -// OrderFunc applies an ordering on the sql selector. -type OrderFunc func(*sql.Selector) - -// columnChecker returns a function indicates if the column exists in the given column. -func columnChecker(table string) func(string) error { - checks := map[string]func(string) bool{ - chaincode.Table: chaincode.ValidColumn, - tenant.Table: tenant.ValidColumn, - } - check, ok := checks[table] - if !ok { - return func(string) error { - return fmt.Errorf("unknown table %q", table) - } - } - return func(column string) error { - if !check(column) { - return fmt.Errorf("unknown column %q for table %q", column, table) - } - return nil - } -} - -// Asc applies the given fields in ASC order. -func Asc(fields ...string) OrderFunc { - return func(s *sql.Selector) { - check := columnChecker(s.TableName()) - for _, f := range fields { - if err := check(f); err != nil { - s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) - } - s.OrderBy(sql.Asc(s.C(f))) - } - } -} - -// Desc applies the given fields in DESC order. -func Desc(fields ...string) OrderFunc { - return func(s *sql.Selector) { - check := columnChecker(s.TableName()) - for _, f := range fields { - if err := check(f); err != nil { - s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) - } - s.OrderBy(sql.Desc(s.C(f))) - } - } -} - -// AggregateFunc applies an aggregation step on the group-by traversal/selector. -type AggregateFunc func(*sql.Selector) string - -// As is a pseudo aggregation function for renaming another other functions with custom names. For example: -// -// GroupBy(field1, field2). -// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). -// Scan(ctx, &v) -// -func As(fn AggregateFunc, end string) AggregateFunc { - return func(s *sql.Selector) string { - return sql.As(fn(s), end) - } -} - -// Count applies the "count" aggregation function on each group. -func Count() AggregateFunc { - return func(s *sql.Selector) string { - return sql.Count("*") - } -} - -// Max applies the "max" aggregation function on the given field of each group. -func Max(field string) AggregateFunc { - return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { - s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) - return "" - } - return sql.Max(s.C(field)) - } -} - -// Mean applies the "mean" aggregation function on the given field of each group. -func Mean(field string) AggregateFunc { - return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { - s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) - return "" - } - return sql.Avg(s.C(field)) - } -} - -// Min applies the "min" aggregation function on the given field of each group. -func Min(field string) AggregateFunc { - return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { - s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) - return "" - } - return sql.Min(s.C(field)) - } -} - -// Sum applies the "sum" aggregation function on the given field of each group. -func Sum(field string) AggregateFunc { - return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { - s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) - return "" - } - return sql.Sum(s.C(field)) - } -} - -// ValidationError returns when validating a field fails. -type ValidationError struct { - Name string // Field or edge name. - err error -} - -// Error implements the error interface. -func (e *ValidationError) Error() string { - return e.err.Error() -} - -// Unwrap implements the errors.Wrapper interface. -func (e *ValidationError) Unwrap() error { - return e.err -} - -// IsValidationError returns a boolean indicating whether the error is a validation error. -func IsValidationError(err error) bool { - if err == nil { - return false - } - var e *ValidationError - return errors.As(err, &e) -} - -// NotFoundError returns when trying to fetch a specific entity and it was not found in the database. -type NotFoundError struct { - label string -} - -// Error implements the error interface. -func (e *NotFoundError) Error() string { - return "ent: " + e.label + " not found" -} - -// IsNotFound returns a boolean indicating whether the error is a not found error. -func IsNotFound(err error) bool { - if err == nil { - return false - } - var e *NotFoundError - return errors.As(err, &e) -} - -// MaskNotFound masks not found error. -func MaskNotFound(err error) error { - if IsNotFound(err) { - return nil - } - return err -} - -// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. -type NotSingularError struct { - label string -} - -// Error implements the error interface. -func (e *NotSingularError) Error() string { - return "ent: " + e.label + " not singular" -} - -// IsNotSingular returns a boolean indicating whether the error is a not singular error. -func IsNotSingular(err error) bool { - if err == nil { - return false - } - var e *NotSingularError - return errors.As(err, &e) -} - -// NotLoadedError returns when trying to get a node that was not loaded by the query. -type NotLoadedError struct { - edge string -} - -// Error implements the error interface. -func (e *NotLoadedError) Error() string { - return "ent: " + e.edge + " edge was not loaded" -} - -// IsNotLoaded returns a boolean indicating whether the error is a not loaded error. -func IsNotLoaded(err error) bool { - if err == nil { - return false - } - var e *NotLoadedError - return errors.As(err, &e) -} - -// ConstraintError returns when trying to create/update one or more entities and -// one or more of their constraints failed. For example, violation of edge or -// field uniqueness. -type ConstraintError struct { - msg string - wrap error -} - -// Error implements the error interface. -func (e ConstraintError) Error() string { - return "ent: constraint failed: " + e.msg -} - -// Unwrap implements the errors.Wrapper interface. -func (e *ConstraintError) Unwrap() error { - return e.wrap -} - -// IsConstraintError returns a boolean indicating whether the error is a constraint failure. -func IsConstraintError(err error) bool { - if err == nil { - return false - } - var e *ConstraintError - return errors.As(err, &e) -} diff --git a/ent/enttest/enttest.go b/ent/enttest/enttest.go deleted file mode 100644 index 07eed0b..0000000 --- a/ent/enttest/enttest.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package enttest - -import ( - "context" - - "github.com/kfsoftware/hlf-cc-dev/ent" - // required by schema hooks. - _ "github.com/kfsoftware/hlf-cc-dev/ent/runtime" - - "entgo.io/ent/dialect/sql/schema" -) - -type ( - // TestingT is the interface that is shared between - // testing.T and testing.B and used by enttest. - TestingT interface { - FailNow() - Error(...interface{}) - } - - // Option configures client creation. - Option func(*options) - - options struct { - opts []ent.Option - migrateOpts []schema.MigrateOption - } -) - -// WithOptions forwards options to client creation. -func WithOptions(opts ...ent.Option) Option { - return func(o *options) { - o.opts = append(o.opts, opts...) - } -} - -// WithMigrateOptions forwards options to auto migration. -func WithMigrateOptions(opts ...schema.MigrateOption) Option { - return func(o *options) { - o.migrateOpts = append(o.migrateOpts, opts...) - } -} - -func newOptions(opts []Option) *options { - o := &options{} - for _, opt := range opts { - opt(o) - } - return o -} - -// Open calls ent.Open and auto-run migration. -func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client { - o := newOptions(opts) - c, err := ent.Open(driverName, dataSourceName, o.opts...) - if err != nil { - t.Error(err) - t.FailNow() - } - if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil { - t.Error(err) - t.FailNow() - } - return c -} - -// NewClient calls ent.NewClient and auto-run migration. -func NewClient(t TestingT, opts ...Option) *ent.Client { - o := newOptions(opts) - c := ent.NewClient(o.opts...) - if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil { - t.Error(err) - t.FailNow() - } - return c -} diff --git a/ent/generate.go b/ent/generate.go deleted file mode 100644 index 8d3fdfd..0000000 --- a/ent/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package ent - -//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema diff --git a/ent/hook/hook.go b/ent/hook/hook.go deleted file mode 100644 index 2137eb8..0000000 --- a/ent/hook/hook.go +++ /dev/null @@ -1,217 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package hook - -import ( - "context" - "fmt" - - "github.com/kfsoftware/hlf-cc-dev/ent" -) - -// The ChaincodeFunc type is an adapter to allow the use of ordinary -// function as Chaincode mutator. -type ChaincodeFunc func(context.Context, *ent.ChaincodeMutation) (ent.Value, error) - -// Mutate calls f(ctx, m). -func (f ChaincodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { - mv, ok := m.(*ent.ChaincodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ChaincodeMutation", m) - } - return f(ctx, mv) -} - -// The TenantFunc type is an adapter to allow the use of ordinary -// function as Tenant mutator. -type TenantFunc func(context.Context, *ent.TenantMutation) (ent.Value, error) - -// Mutate calls f(ctx, m). -func (f TenantFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { - mv, ok := m.(*ent.TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TenantMutation", m) - } - return f(ctx, mv) -} - -// Condition is a hook condition function. -type Condition func(context.Context, ent.Mutation) bool - -// And groups conditions with the AND operator. -func And(first, second Condition, rest ...Condition) Condition { - return func(ctx context.Context, m ent.Mutation) bool { - if !first(ctx, m) || !second(ctx, m) { - return false - } - for _, cond := range rest { - if !cond(ctx, m) { - return false - } - } - return true - } -} - -// Or groups conditions with the OR operator. -func Or(first, second Condition, rest ...Condition) Condition { - return func(ctx context.Context, m ent.Mutation) bool { - if first(ctx, m) || second(ctx, m) { - return true - } - for _, cond := range rest { - if cond(ctx, m) { - return true - } - } - return false - } -} - -// Not negates a given condition. -func Not(cond Condition) Condition { - return func(ctx context.Context, m ent.Mutation) bool { - return !cond(ctx, m) - } -} - -// HasOp is a condition testing mutation operation. -func HasOp(op ent.Op) Condition { - return func(_ context.Context, m ent.Mutation) bool { - return m.Op().Is(op) - } -} - -// HasAddedFields is a condition validating `.AddedField` on fields. -func HasAddedFields(field string, fields ...string) Condition { - return func(_ context.Context, m ent.Mutation) bool { - if _, exists := m.AddedField(field); !exists { - return false - } - for _, field := range fields { - if _, exists := m.AddedField(field); !exists { - return false - } - } - return true - } -} - -// HasClearedFields is a condition validating `.FieldCleared` on fields. -func HasClearedFields(field string, fields ...string) Condition { - return func(_ context.Context, m ent.Mutation) bool { - if exists := m.FieldCleared(field); !exists { - return false - } - for _, field := range fields { - if exists := m.FieldCleared(field); !exists { - return false - } - } - return true - } -} - -// HasFields is a condition validating `.Field` on fields. -func HasFields(field string, fields ...string) Condition { - return func(_ context.Context, m ent.Mutation) bool { - if _, exists := m.Field(field); !exists { - return false - } - for _, field := range fields { - if _, exists := m.Field(field); !exists { - return false - } - } - return true - } -} - -// If executes the given hook under condition. -// -// hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...))) -// -func If(hk ent.Hook, cond Condition) ent.Hook { - return func(next ent.Mutator) ent.Mutator { - return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { - if cond(ctx, m) { - return hk(next).Mutate(ctx, m) - } - return next.Mutate(ctx, m) - }) - } -} - -// On executes the given hook only for the given operation. -// -// hook.On(Log, ent.Delete|ent.Create) -// -func On(hk ent.Hook, op ent.Op) ent.Hook { - return If(hk, HasOp(op)) -} - -// Unless skips the given hook only for the given operation. -// -// hook.Unless(Log, ent.Update|ent.UpdateOne) -// -func Unless(hk ent.Hook, op ent.Op) ent.Hook { - return If(hk, Not(HasOp(op))) -} - -// FixedError is a hook returning a fixed error. -func FixedError(err error) ent.Hook { - return func(ent.Mutator) ent.Mutator { - return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) { - return nil, err - }) - } -} - -// Reject returns a hook that rejects all operations that match op. -// -// func (T) Hooks() []ent.Hook { -// return []ent.Hook{ -// Reject(ent.Delete|ent.Update), -// } -// } -// -func Reject(op ent.Op) ent.Hook { - hk := FixedError(fmt.Errorf("%s operation is not allowed", op)) - return On(hk, op) -} - -// Chain acts as a list of hooks and is effectively immutable. -// Once created, it will always hold the same set of hooks in the same order. -type Chain struct { - hooks []ent.Hook -} - -// NewChain creates a new chain of hooks. -func NewChain(hooks ...ent.Hook) Chain { - return Chain{append([]ent.Hook(nil), hooks...)} -} - -// Hook chains the list of hooks and returns the final hook. -func (c Chain) Hook() ent.Hook { - return func(mutator ent.Mutator) ent.Mutator { - for i := len(c.hooks) - 1; i >= 0; i-- { - mutator = c.hooks[i](mutator) - } - return mutator - } -} - -// Append extends a chain, adding the specified hook -// as the last ones in the mutation flow. -func (c Chain) Append(hooks ...ent.Hook) Chain { - newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks)) - newHooks = append(newHooks, c.hooks...) - newHooks = append(newHooks, hooks...) - return Chain{newHooks} -} - -// Extend extends a chain, adding the specified chain -// as the last ones in the mutation flow. -func (c Chain) Extend(chain Chain) Chain { - return c.Append(chain.hooks...) -} diff --git a/ent/migrate/migrate.go b/ent/migrate/migrate.go deleted file mode 100644 index e4a9a22..0000000 --- a/ent/migrate/migrate.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package migrate - -import ( - "context" - "fmt" - "io" - - "entgo.io/ent/dialect" - "entgo.io/ent/dialect/sql/schema" -) - -var ( - // WithGlobalUniqueID sets the universal ids options to the migration. - // If this option is enabled, ent migration will allocate a 1<<32 range - // for the ids of each entity (table). - // Note that this option cannot be applied on tables that already exist. - WithGlobalUniqueID = schema.WithGlobalUniqueID - // WithDropColumn sets the drop column option to the migration. - // If this option is enabled, ent migration will drop old columns - // that were used for both fields and edges. This defaults to false. - WithDropColumn = schema.WithDropColumn - // WithDropIndex sets the drop index option to the migration. - // If this option is enabled, ent migration will drop old indexes - // that were defined in the schema. This defaults to false. - // Note that unique constraints are defined using `UNIQUE INDEX`, - // and therefore, it's recommended to enable this option to get more - // flexibility in the schema changes. - WithDropIndex = schema.WithDropIndex - // WithFixture sets the foreign-key renaming option to the migration when upgrading - // ent from v0.1.0 (issue-#285). Defaults to false. - WithFixture = schema.WithFixture - // WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true. - WithForeignKeys = schema.WithForeignKeys -) - -// Schema is the API for creating, migrating and dropping a schema. -type Schema struct { - drv dialect.Driver - universalID bool -} - -// NewSchema creates a new schema client. -func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } - -// Create creates all schema resources. -func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { - migrate, err := schema.NewMigrate(s.drv, opts...) - if err != nil { - return fmt.Errorf("ent/migrate: %w", err) - } - return migrate.Create(ctx, Tables...) -} - -// WriteTo writes the schema changes to w instead of running them against the database. -// -// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { -// log.Fatal(err) -// } -// -func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { - drv := &schema.WriteDriver{ - Writer: w, - Driver: s.drv, - } - migrate, err := schema.NewMigrate(drv, opts...) - if err != nil { - return fmt.Errorf("ent/migrate: %w", err) - } - return migrate.Create(ctx, Tables...) -} diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go deleted file mode 100644 index c14ef6b..0000000 --- a/ent/migrate/schema.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package migrate - -import ( - "entgo.io/ent/dialect/sql/schema" - "entgo.io/ent/schema/field" -) - -var ( - // ChaincodesColumns holds the columns for the "chaincodes" table. - ChaincodesColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "package_id", Type: field.TypeString}, - {Name: "channel_id", Type: field.TypeString}, - {Name: "tenant_chaincodes", Type: field.TypeInt, Nullable: true}, - } - // ChaincodesTable holds the schema information for the "chaincodes" table. - ChaincodesTable = &schema.Table{ - Name: "chaincodes", - Columns: ChaincodesColumns, - PrimaryKey: []*schema.Column{ChaincodesColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "chaincodes_tenants_chaincodes", - Columns: []*schema.Column{ChaincodesColumns[3]}, - RefColumns: []*schema.Column{TenantsColumns[0]}, - OnDelete: schema.SetNull, - }, - }, - } - // TenantsColumns holds the columns for the "tenants" table. - TenantsColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "name", Type: field.TypeString, Unique: true}, - {Name: "msp_id", Type: field.TypeString}, - {Name: "sign_cert_ca_private_key", Type: field.TypeBytes, Nullable: true}, - {Name: "sign_cert_ca_cert", Type: field.TypeBytes, Nullable: true}, - {Name: "tls_cert_ca_private_key", Type: field.TypeBytes, Nullable: true}, - {Name: "tls_cert_ca_cert", Type: field.TypeBytes, Nullable: true}, - } - // TenantsTable holds the schema information for the "tenants" table. - TenantsTable = &schema.Table{ - Name: "tenants", - Columns: TenantsColumns, - PrimaryKey: []*schema.Column{TenantsColumns[0]}, - } - // Tables holds all the tables in the schema. - Tables = []*schema.Table{ - ChaincodesTable, - TenantsTable, - } -) - -func init() { - ChaincodesTable.ForeignKeys[0].RefTable = TenantsTable -} diff --git a/ent/mutation.go b/ent/mutation.go deleted file mode 100644 index 295011b..0000000 --- a/ent/mutation.go +++ /dev/null @@ -1,1177 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - "sync" - - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" - - "entgo.io/ent" -) - -const ( - // Operation types. - OpCreate = ent.OpCreate - OpDelete = ent.OpDelete - OpDeleteOne = ent.OpDeleteOne - OpUpdate = ent.OpUpdate - OpUpdateOne = ent.OpUpdateOne - - // Node types. - TypeChaincode = "Chaincode" - TypeTenant = "Tenant" -) - -// ChaincodeMutation represents an operation that mutates the Chaincode nodes in the graph. -type ChaincodeMutation struct { - config - op Op - typ string - id *int - packageId *string - channelId *string - clearedFields map[string]struct{} - tenant *int - clearedtenant bool - done bool - oldValue func(context.Context) (*Chaincode, error) - predicates []predicate.Chaincode -} - -var _ ent.Mutation = (*ChaincodeMutation)(nil) - -// chaincodeOption allows management of the mutation configuration using functional options. -type chaincodeOption func(*ChaincodeMutation) - -// newChaincodeMutation creates new mutation for the Chaincode entity. -func newChaincodeMutation(c config, op Op, opts ...chaincodeOption) *ChaincodeMutation { - m := &ChaincodeMutation{ - config: c, - op: op, - typ: TypeChaincode, - clearedFields: make(map[string]struct{}), - } - for _, opt := range opts { - opt(m) - } - return m -} - -// withChaincodeID sets the ID field of the mutation. -func withChaincodeID(id int) chaincodeOption { - return func(m *ChaincodeMutation) { - var ( - err error - once sync.Once - value *Chaincode - ) - m.oldValue = func(ctx context.Context) (*Chaincode, error) { - once.Do(func() { - if m.done { - err = fmt.Errorf("querying old values post mutation is not allowed") - } else { - value, err = m.Client().Chaincode.Get(ctx, id) - } - }) - return value, err - } - m.id = &id - } -} - -// withChaincode sets the old Chaincode of the mutation. -func withChaincode(node *Chaincode) chaincodeOption { - return func(m *ChaincodeMutation) { - m.oldValue = func(context.Context) (*Chaincode, error) { - return node, nil - } - m.id = &node.ID - } -} - -// Client returns a new `ent.Client` from the mutation. If the mutation was -// executed in a transaction (ent.Tx), a transactional client is returned. -func (m ChaincodeMutation) Client() *Client { - client := &Client{config: m.config} - client.init() - return client -} - -// Tx returns an `ent.Tx` for mutations that were executed in transactions; -// it returns an error otherwise. -func (m ChaincodeMutation) Tx() (*Tx, error) { - if _, ok := m.driver.(*txDriver); !ok { - return nil, fmt.Errorf("ent: mutation is not running in a transaction") - } - tx := &Tx{config: m.config} - tx.init() - return tx, nil -} - -// ID returns the ID value in the mutation. Note that the ID is only available -// if it was provided to the builder or after it was returned from the database. -func (m *ChaincodeMutation) ID() (id int, exists bool) { - if m.id == nil { - return - } - return *m.id, true -} - -// SetPackageId sets the "packageId" field. -func (m *ChaincodeMutation) SetPackageId(s string) { - m.packageId = &s -} - -// PackageId returns the value of the "packageId" field in the mutation. -func (m *ChaincodeMutation) PackageId() (r string, exists bool) { - v := m.packageId - if v == nil { - return - } - return *v, true -} - -// OldPackageId returns the old "packageId" field's value of the Chaincode entity. -// If the Chaincode object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *ChaincodeMutation) OldPackageId(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldPackageId is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldPackageId requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldPackageId: %w", err) - } - return oldValue.PackageId, nil -} - -// ResetPackageId resets all changes to the "packageId" field. -func (m *ChaincodeMutation) ResetPackageId() { - m.packageId = nil -} - -// SetChannelId sets the "channelId" field. -func (m *ChaincodeMutation) SetChannelId(s string) { - m.channelId = &s -} - -// ChannelId returns the value of the "channelId" field in the mutation. -func (m *ChaincodeMutation) ChannelId() (r string, exists bool) { - v := m.channelId - if v == nil { - return - } - return *v, true -} - -// OldChannelId returns the old "channelId" field's value of the Chaincode entity. -// If the Chaincode object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *ChaincodeMutation) OldChannelId(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldChannelId is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldChannelId requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldChannelId: %w", err) - } - return oldValue.ChannelId, nil -} - -// ResetChannelId resets all changes to the "channelId" field. -func (m *ChaincodeMutation) ResetChannelId() { - m.channelId = nil -} - -// SetTenantID sets the "tenant" edge to the Tenant entity by id. -func (m *ChaincodeMutation) SetTenantID(id int) { - m.tenant = &id -} - -// ClearTenant clears the "tenant" edge to the Tenant entity. -func (m *ChaincodeMutation) ClearTenant() { - m.clearedtenant = true -} - -// TenantCleared reports if the "tenant" edge to the Tenant entity was cleared. -func (m *ChaincodeMutation) TenantCleared() bool { - return m.clearedtenant -} - -// TenantID returns the "tenant" edge ID in the mutation. -func (m *ChaincodeMutation) TenantID() (id int, exists bool) { - if m.tenant != nil { - return *m.tenant, true - } - return -} - -// TenantIDs returns the "tenant" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// TenantID instead. It exists only for internal usage by the builders. -func (m *ChaincodeMutation) TenantIDs() (ids []int) { - if id := m.tenant; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetTenant resets all changes to the "tenant" edge. -func (m *ChaincodeMutation) ResetTenant() { - m.tenant = nil - m.clearedtenant = false -} - -// Where appends a list predicates to the ChaincodeMutation builder. -func (m *ChaincodeMutation) Where(ps ...predicate.Chaincode) { - m.predicates = append(m.predicates, ps...) -} - -// Op returns the operation name. -func (m *ChaincodeMutation) Op() Op { - return m.op -} - -// Type returns the node type of this mutation (Chaincode). -func (m *ChaincodeMutation) Type() string { - return m.typ -} - -// Fields returns all fields that were changed during this mutation. Note that in -// order to get all numeric fields that were incremented/decremented, call -// AddedFields(). -func (m *ChaincodeMutation) Fields() []string { - fields := make([]string, 0, 2) - if m.packageId != nil { - fields = append(fields, chaincode.FieldPackageId) - } - if m.channelId != nil { - fields = append(fields, chaincode.FieldChannelId) - } - return fields -} - -// Field returns the value of a field with the given name. The second boolean -// return value indicates that this field was not set, or was not defined in the -// schema. -func (m *ChaincodeMutation) Field(name string) (ent.Value, bool) { - switch name { - case chaincode.FieldPackageId: - return m.PackageId() - case chaincode.FieldChannelId: - return m.ChannelId() - } - return nil, false -} - -// OldField returns the old value of the field from the database. An error is -// returned if the mutation operation is not UpdateOne, or the query to the -// database failed. -func (m *ChaincodeMutation) OldField(ctx context.Context, name string) (ent.Value, error) { - switch name { - case chaincode.FieldPackageId: - return m.OldPackageId(ctx) - case chaincode.FieldChannelId: - return m.OldChannelId(ctx) - } - return nil, fmt.Errorf("unknown Chaincode field %s", name) -} - -// SetField sets the value of a field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *ChaincodeMutation) SetField(name string, value ent.Value) error { - switch name { - case chaincode.FieldPackageId: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetPackageId(v) - return nil - case chaincode.FieldChannelId: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetChannelId(v) - return nil - } - return fmt.Errorf("unknown Chaincode field %s", name) -} - -// AddedFields returns all numeric fields that were incremented/decremented during -// this mutation. -func (m *ChaincodeMutation) AddedFields() []string { - return nil -} - -// AddedField returns the numeric value that was incremented/decremented on a field -// with the given name. The second boolean return value indicates that this field -// was not set, or was not defined in the schema. -func (m *ChaincodeMutation) AddedField(name string) (ent.Value, bool) { - return nil, false -} - -// AddField adds the value to the field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *ChaincodeMutation) AddField(name string, value ent.Value) error { - switch name { - } - return fmt.Errorf("unknown Chaincode numeric field %s", name) -} - -// ClearedFields returns all nullable fields that were cleared during this -// mutation. -func (m *ChaincodeMutation) ClearedFields() []string { - return nil -} - -// FieldCleared returns a boolean indicating if a field with the given name was -// cleared in this mutation. -func (m *ChaincodeMutation) FieldCleared(name string) bool { - _, ok := m.clearedFields[name] - return ok -} - -// ClearField clears the value of the field with the given name. It returns an -// error if the field is not defined in the schema. -func (m *ChaincodeMutation) ClearField(name string) error { - return fmt.Errorf("unknown Chaincode nullable field %s", name) -} - -// ResetField resets all changes in the mutation for the field with the given name. -// It returns an error if the field is not defined in the schema. -func (m *ChaincodeMutation) ResetField(name string) error { - switch name { - case chaincode.FieldPackageId: - m.ResetPackageId() - return nil - case chaincode.FieldChannelId: - m.ResetChannelId() - return nil - } - return fmt.Errorf("unknown Chaincode field %s", name) -} - -// AddedEdges returns all edge names that were set/added in this mutation. -func (m *ChaincodeMutation) AddedEdges() []string { - edges := make([]string, 0, 1) - if m.tenant != nil { - edges = append(edges, chaincode.EdgeTenant) - } - return edges -} - -// AddedIDs returns all IDs (to other nodes) that were added for the given edge -// name in this mutation. -func (m *ChaincodeMutation) AddedIDs(name string) []ent.Value { - switch name { - case chaincode.EdgeTenant: - if id := m.tenant; id != nil { - return []ent.Value{*id} - } - } - return nil -} - -// RemovedEdges returns all edge names that were removed in this mutation. -func (m *ChaincodeMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) - return edges -} - -// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with -// the given name in this mutation. -func (m *ChaincodeMutation) RemovedIDs(name string) []ent.Value { - switch name { - } - return nil -} - -// ClearedEdges returns all edge names that were cleared in this mutation. -func (m *ChaincodeMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) - if m.clearedtenant { - edges = append(edges, chaincode.EdgeTenant) - } - return edges -} - -// EdgeCleared returns a boolean which indicates if the edge with the given name -// was cleared in this mutation. -func (m *ChaincodeMutation) EdgeCleared(name string) bool { - switch name { - case chaincode.EdgeTenant: - return m.clearedtenant - } - return false -} - -// ClearEdge clears the value of the edge with the given name. It returns an error -// if that edge is not defined in the schema. -func (m *ChaincodeMutation) ClearEdge(name string) error { - switch name { - case chaincode.EdgeTenant: - m.ClearTenant() - return nil - } - return fmt.Errorf("unknown Chaincode unique edge %s", name) -} - -// ResetEdge resets all changes to the edge with the given name in this mutation. -// It returns an error if the edge is not defined in the schema. -func (m *ChaincodeMutation) ResetEdge(name string) error { - switch name { - case chaincode.EdgeTenant: - m.ResetTenant() - return nil - } - return fmt.Errorf("unknown Chaincode edge %s", name) -} - -// TenantMutation represents an operation that mutates the Tenant nodes in the graph. -type TenantMutation struct { - config - op Op - typ string - id *int - name *string - mspId *string - signCertCAPrivateKey *[]byte - signCertCACert *[]byte - tlsCertCAPrivateKey *[]byte - tlsCertCACert *[]byte - clearedFields map[string]struct{} - chaincodes map[int]struct{} - removedchaincodes map[int]struct{} - clearedchaincodes bool - done bool - oldValue func(context.Context) (*Tenant, error) - predicates []predicate.Tenant -} - -var _ ent.Mutation = (*TenantMutation)(nil) - -// tenantOption allows management of the mutation configuration using functional options. -type tenantOption func(*TenantMutation) - -// newTenantMutation creates new mutation for the Tenant entity. -func newTenantMutation(c config, op Op, opts ...tenantOption) *TenantMutation { - m := &TenantMutation{ - config: c, - op: op, - typ: TypeTenant, - clearedFields: make(map[string]struct{}), - } - for _, opt := range opts { - opt(m) - } - return m -} - -// withTenantID sets the ID field of the mutation. -func withTenantID(id int) tenantOption { - return func(m *TenantMutation) { - var ( - err error - once sync.Once - value *Tenant - ) - m.oldValue = func(ctx context.Context) (*Tenant, error) { - once.Do(func() { - if m.done { - err = fmt.Errorf("querying old values post mutation is not allowed") - } else { - value, err = m.Client().Tenant.Get(ctx, id) - } - }) - return value, err - } - m.id = &id - } -} - -// withTenant sets the old Tenant of the mutation. -func withTenant(node *Tenant) tenantOption { - return func(m *TenantMutation) { - m.oldValue = func(context.Context) (*Tenant, error) { - return node, nil - } - m.id = &node.ID - } -} - -// Client returns a new `ent.Client` from the mutation. If the mutation was -// executed in a transaction (ent.Tx), a transactional client is returned. -func (m TenantMutation) Client() *Client { - client := &Client{config: m.config} - client.init() - return client -} - -// Tx returns an `ent.Tx` for mutations that were executed in transactions; -// it returns an error otherwise. -func (m TenantMutation) Tx() (*Tx, error) { - if _, ok := m.driver.(*txDriver); !ok { - return nil, fmt.Errorf("ent: mutation is not running in a transaction") - } - tx := &Tx{config: m.config} - tx.init() - return tx, nil -} - -// ID returns the ID value in the mutation. Note that the ID is only available -// if it was provided to the builder or after it was returned from the database. -func (m *TenantMutation) ID() (id int, exists bool) { - if m.id == nil { - return - } - return *m.id, true -} - -// SetName sets the "name" field. -func (m *TenantMutation) SetName(s string) { - m.name = &s -} - -// Name returns the value of the "name" field in the mutation. -func (m *TenantMutation) Name() (r string, exists bool) { - v := m.name - if v == nil { - return - } - return *v, true -} - -// OldName returns the old "name" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldName(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldName is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldName requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldName: %w", err) - } - return oldValue.Name, nil -} - -// ResetName resets all changes to the "name" field. -func (m *TenantMutation) ResetName() { - m.name = nil -} - -// SetMspId sets the "mspId" field. -func (m *TenantMutation) SetMspId(s string) { - m.mspId = &s -} - -// MspId returns the value of the "mspId" field in the mutation. -func (m *TenantMutation) MspId() (r string, exists bool) { - v := m.mspId - if v == nil { - return - } - return *v, true -} - -// OldMspId returns the old "mspId" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldMspId(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldMspId is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldMspId requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldMspId: %w", err) - } - return oldValue.MspId, nil -} - -// ResetMspId resets all changes to the "mspId" field. -func (m *TenantMutation) ResetMspId() { - m.mspId = nil -} - -// SetSignCertCAPrivateKey sets the "signCertCAPrivateKey" field. -func (m *TenantMutation) SetSignCertCAPrivateKey(b []byte) { - m.signCertCAPrivateKey = &b -} - -// SignCertCAPrivateKey returns the value of the "signCertCAPrivateKey" field in the mutation. -func (m *TenantMutation) SignCertCAPrivateKey() (r []byte, exists bool) { - v := m.signCertCAPrivateKey - if v == nil { - return - } - return *v, true -} - -// OldSignCertCAPrivateKey returns the old "signCertCAPrivateKey" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldSignCertCAPrivateKey(ctx context.Context) (v []byte, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldSignCertCAPrivateKey is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldSignCertCAPrivateKey requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldSignCertCAPrivateKey: %w", err) - } - return oldValue.SignCertCAPrivateKey, nil -} - -// ClearSignCertCAPrivateKey clears the value of the "signCertCAPrivateKey" field. -func (m *TenantMutation) ClearSignCertCAPrivateKey() { - m.signCertCAPrivateKey = nil - m.clearedFields[tenant.FieldSignCertCAPrivateKey] = struct{}{} -} - -// SignCertCAPrivateKeyCleared returns if the "signCertCAPrivateKey" field was cleared in this mutation. -func (m *TenantMutation) SignCertCAPrivateKeyCleared() bool { - _, ok := m.clearedFields[tenant.FieldSignCertCAPrivateKey] - return ok -} - -// ResetSignCertCAPrivateKey resets all changes to the "signCertCAPrivateKey" field. -func (m *TenantMutation) ResetSignCertCAPrivateKey() { - m.signCertCAPrivateKey = nil - delete(m.clearedFields, tenant.FieldSignCertCAPrivateKey) -} - -// SetSignCertCACert sets the "signCertCACert" field. -func (m *TenantMutation) SetSignCertCACert(b []byte) { - m.signCertCACert = &b -} - -// SignCertCACert returns the value of the "signCertCACert" field in the mutation. -func (m *TenantMutation) SignCertCACert() (r []byte, exists bool) { - v := m.signCertCACert - if v == nil { - return - } - return *v, true -} - -// OldSignCertCACert returns the old "signCertCACert" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldSignCertCACert(ctx context.Context) (v []byte, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldSignCertCACert is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldSignCertCACert requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldSignCertCACert: %w", err) - } - return oldValue.SignCertCACert, nil -} - -// ClearSignCertCACert clears the value of the "signCertCACert" field. -func (m *TenantMutation) ClearSignCertCACert() { - m.signCertCACert = nil - m.clearedFields[tenant.FieldSignCertCACert] = struct{}{} -} - -// SignCertCACertCleared returns if the "signCertCACert" field was cleared in this mutation. -func (m *TenantMutation) SignCertCACertCleared() bool { - _, ok := m.clearedFields[tenant.FieldSignCertCACert] - return ok -} - -// ResetSignCertCACert resets all changes to the "signCertCACert" field. -func (m *TenantMutation) ResetSignCertCACert() { - m.signCertCACert = nil - delete(m.clearedFields, tenant.FieldSignCertCACert) -} - -// SetTlsCertCAPrivateKey sets the "tlsCertCAPrivateKey" field. -func (m *TenantMutation) SetTlsCertCAPrivateKey(b []byte) { - m.tlsCertCAPrivateKey = &b -} - -// TlsCertCAPrivateKey returns the value of the "tlsCertCAPrivateKey" field in the mutation. -func (m *TenantMutation) TlsCertCAPrivateKey() (r []byte, exists bool) { - v := m.tlsCertCAPrivateKey - if v == nil { - return - } - return *v, true -} - -// OldTlsCertCAPrivateKey returns the old "tlsCertCAPrivateKey" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldTlsCertCAPrivateKey(ctx context.Context) (v []byte, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldTlsCertCAPrivateKey is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldTlsCertCAPrivateKey requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldTlsCertCAPrivateKey: %w", err) - } - return oldValue.TlsCertCAPrivateKey, nil -} - -// ClearTlsCertCAPrivateKey clears the value of the "tlsCertCAPrivateKey" field. -func (m *TenantMutation) ClearTlsCertCAPrivateKey() { - m.tlsCertCAPrivateKey = nil - m.clearedFields[tenant.FieldTlsCertCAPrivateKey] = struct{}{} -} - -// TlsCertCAPrivateKeyCleared returns if the "tlsCertCAPrivateKey" field was cleared in this mutation. -func (m *TenantMutation) TlsCertCAPrivateKeyCleared() bool { - _, ok := m.clearedFields[tenant.FieldTlsCertCAPrivateKey] - return ok -} - -// ResetTlsCertCAPrivateKey resets all changes to the "tlsCertCAPrivateKey" field. -func (m *TenantMutation) ResetTlsCertCAPrivateKey() { - m.tlsCertCAPrivateKey = nil - delete(m.clearedFields, tenant.FieldTlsCertCAPrivateKey) -} - -// SetTlsCertCACert sets the "tlsCertCACert" field. -func (m *TenantMutation) SetTlsCertCACert(b []byte) { - m.tlsCertCACert = &b -} - -// TlsCertCACert returns the value of the "tlsCertCACert" field in the mutation. -func (m *TenantMutation) TlsCertCACert() (r []byte, exists bool) { - v := m.tlsCertCACert - if v == nil { - return - } - return *v, true -} - -// OldTlsCertCACert returns the old "tlsCertCACert" field's value of the Tenant entity. -// If the Tenant object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *TenantMutation) OldTlsCertCACert(ctx context.Context) (v []byte, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldTlsCertCACert is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldTlsCertCACert requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldTlsCertCACert: %w", err) - } - return oldValue.TlsCertCACert, nil -} - -// ClearTlsCertCACert clears the value of the "tlsCertCACert" field. -func (m *TenantMutation) ClearTlsCertCACert() { - m.tlsCertCACert = nil - m.clearedFields[tenant.FieldTlsCertCACert] = struct{}{} -} - -// TlsCertCACertCleared returns if the "tlsCertCACert" field was cleared in this mutation. -func (m *TenantMutation) TlsCertCACertCleared() bool { - _, ok := m.clearedFields[tenant.FieldTlsCertCACert] - return ok -} - -// ResetTlsCertCACert resets all changes to the "tlsCertCACert" field. -func (m *TenantMutation) ResetTlsCertCACert() { - m.tlsCertCACert = nil - delete(m.clearedFields, tenant.FieldTlsCertCACert) -} - -// AddChaincodeIDs adds the "chaincodes" edge to the Chaincode entity by ids. -func (m *TenantMutation) AddChaincodeIDs(ids ...int) { - if m.chaincodes == nil { - m.chaincodes = make(map[int]struct{}) - } - for i := range ids { - m.chaincodes[ids[i]] = struct{}{} - } -} - -// ClearChaincodes clears the "chaincodes" edge to the Chaincode entity. -func (m *TenantMutation) ClearChaincodes() { - m.clearedchaincodes = true -} - -// ChaincodesCleared reports if the "chaincodes" edge to the Chaincode entity was cleared. -func (m *TenantMutation) ChaincodesCleared() bool { - return m.clearedchaincodes -} - -// RemoveChaincodeIDs removes the "chaincodes" edge to the Chaincode entity by IDs. -func (m *TenantMutation) RemoveChaincodeIDs(ids ...int) { - if m.removedchaincodes == nil { - m.removedchaincodes = make(map[int]struct{}) - } - for i := range ids { - delete(m.chaincodes, ids[i]) - m.removedchaincodes[ids[i]] = struct{}{} - } -} - -// RemovedChaincodes returns the removed IDs of the "chaincodes" edge to the Chaincode entity. -func (m *TenantMutation) RemovedChaincodesIDs() (ids []int) { - for id := range m.removedchaincodes { - ids = append(ids, id) - } - return -} - -// ChaincodesIDs returns the "chaincodes" edge IDs in the mutation. -func (m *TenantMutation) ChaincodesIDs() (ids []int) { - for id := range m.chaincodes { - ids = append(ids, id) - } - return -} - -// ResetChaincodes resets all changes to the "chaincodes" edge. -func (m *TenantMutation) ResetChaincodes() { - m.chaincodes = nil - m.clearedchaincodes = false - m.removedchaincodes = nil -} - -// Where appends a list predicates to the TenantMutation builder. -func (m *TenantMutation) Where(ps ...predicate.Tenant) { - m.predicates = append(m.predicates, ps...) -} - -// Op returns the operation name. -func (m *TenantMutation) Op() Op { - return m.op -} - -// Type returns the node type of this mutation (Tenant). -func (m *TenantMutation) Type() string { - return m.typ -} - -// Fields returns all fields that were changed during this mutation. Note that in -// order to get all numeric fields that were incremented/decremented, call -// AddedFields(). -func (m *TenantMutation) Fields() []string { - fields := make([]string, 0, 6) - if m.name != nil { - fields = append(fields, tenant.FieldName) - } - if m.mspId != nil { - fields = append(fields, tenant.FieldMspId) - } - if m.signCertCAPrivateKey != nil { - fields = append(fields, tenant.FieldSignCertCAPrivateKey) - } - if m.signCertCACert != nil { - fields = append(fields, tenant.FieldSignCertCACert) - } - if m.tlsCertCAPrivateKey != nil { - fields = append(fields, tenant.FieldTlsCertCAPrivateKey) - } - if m.tlsCertCACert != nil { - fields = append(fields, tenant.FieldTlsCertCACert) - } - return fields -} - -// Field returns the value of a field with the given name. The second boolean -// return value indicates that this field was not set, or was not defined in the -// schema. -func (m *TenantMutation) Field(name string) (ent.Value, bool) { - switch name { - case tenant.FieldName: - return m.Name() - case tenant.FieldMspId: - return m.MspId() - case tenant.FieldSignCertCAPrivateKey: - return m.SignCertCAPrivateKey() - case tenant.FieldSignCertCACert: - return m.SignCertCACert() - case tenant.FieldTlsCertCAPrivateKey: - return m.TlsCertCAPrivateKey() - case tenant.FieldTlsCertCACert: - return m.TlsCertCACert() - } - return nil, false -} - -// OldField returns the old value of the field from the database. An error is -// returned if the mutation operation is not UpdateOne, or the query to the -// database failed. -func (m *TenantMutation) OldField(ctx context.Context, name string) (ent.Value, error) { - switch name { - case tenant.FieldName: - return m.OldName(ctx) - case tenant.FieldMspId: - return m.OldMspId(ctx) - case tenant.FieldSignCertCAPrivateKey: - return m.OldSignCertCAPrivateKey(ctx) - case tenant.FieldSignCertCACert: - return m.OldSignCertCACert(ctx) - case tenant.FieldTlsCertCAPrivateKey: - return m.OldTlsCertCAPrivateKey(ctx) - case tenant.FieldTlsCertCACert: - return m.OldTlsCertCACert(ctx) - } - return nil, fmt.Errorf("unknown Tenant field %s", name) -} - -// SetField sets the value of a field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *TenantMutation) SetField(name string, value ent.Value) error { - switch name { - case tenant.FieldName: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetName(v) - return nil - case tenant.FieldMspId: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetMspId(v) - return nil - case tenant.FieldSignCertCAPrivateKey: - v, ok := value.([]byte) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetSignCertCAPrivateKey(v) - return nil - case tenant.FieldSignCertCACert: - v, ok := value.([]byte) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetSignCertCACert(v) - return nil - case tenant.FieldTlsCertCAPrivateKey: - v, ok := value.([]byte) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetTlsCertCAPrivateKey(v) - return nil - case tenant.FieldTlsCertCACert: - v, ok := value.([]byte) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetTlsCertCACert(v) - return nil - } - return fmt.Errorf("unknown Tenant field %s", name) -} - -// AddedFields returns all numeric fields that were incremented/decremented during -// this mutation. -func (m *TenantMutation) AddedFields() []string { - return nil -} - -// AddedField returns the numeric value that was incremented/decremented on a field -// with the given name. The second boolean return value indicates that this field -// was not set, or was not defined in the schema. -func (m *TenantMutation) AddedField(name string) (ent.Value, bool) { - return nil, false -} - -// AddField adds the value to the field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *TenantMutation) AddField(name string, value ent.Value) error { - switch name { - } - return fmt.Errorf("unknown Tenant numeric field %s", name) -} - -// ClearedFields returns all nullable fields that were cleared during this -// mutation. -func (m *TenantMutation) ClearedFields() []string { - var fields []string - if m.FieldCleared(tenant.FieldSignCertCAPrivateKey) { - fields = append(fields, tenant.FieldSignCertCAPrivateKey) - } - if m.FieldCleared(tenant.FieldSignCertCACert) { - fields = append(fields, tenant.FieldSignCertCACert) - } - if m.FieldCleared(tenant.FieldTlsCertCAPrivateKey) { - fields = append(fields, tenant.FieldTlsCertCAPrivateKey) - } - if m.FieldCleared(tenant.FieldTlsCertCACert) { - fields = append(fields, tenant.FieldTlsCertCACert) - } - return fields -} - -// FieldCleared returns a boolean indicating if a field with the given name was -// cleared in this mutation. -func (m *TenantMutation) FieldCleared(name string) bool { - _, ok := m.clearedFields[name] - return ok -} - -// ClearField clears the value of the field with the given name. It returns an -// error if the field is not defined in the schema. -func (m *TenantMutation) ClearField(name string) error { - switch name { - case tenant.FieldSignCertCAPrivateKey: - m.ClearSignCertCAPrivateKey() - return nil - case tenant.FieldSignCertCACert: - m.ClearSignCertCACert() - return nil - case tenant.FieldTlsCertCAPrivateKey: - m.ClearTlsCertCAPrivateKey() - return nil - case tenant.FieldTlsCertCACert: - m.ClearTlsCertCACert() - return nil - } - return fmt.Errorf("unknown Tenant nullable field %s", name) -} - -// ResetField resets all changes in the mutation for the field with the given name. -// It returns an error if the field is not defined in the schema. -func (m *TenantMutation) ResetField(name string) error { - switch name { - case tenant.FieldName: - m.ResetName() - return nil - case tenant.FieldMspId: - m.ResetMspId() - return nil - case tenant.FieldSignCertCAPrivateKey: - m.ResetSignCertCAPrivateKey() - return nil - case tenant.FieldSignCertCACert: - m.ResetSignCertCACert() - return nil - case tenant.FieldTlsCertCAPrivateKey: - m.ResetTlsCertCAPrivateKey() - return nil - case tenant.FieldTlsCertCACert: - m.ResetTlsCertCACert() - return nil - } - return fmt.Errorf("unknown Tenant field %s", name) -} - -// AddedEdges returns all edge names that were set/added in this mutation. -func (m *TenantMutation) AddedEdges() []string { - edges := make([]string, 0, 1) - if m.chaincodes != nil { - edges = append(edges, tenant.EdgeChaincodes) - } - return edges -} - -// AddedIDs returns all IDs (to other nodes) that were added for the given edge -// name in this mutation. -func (m *TenantMutation) AddedIDs(name string) []ent.Value { - switch name { - case tenant.EdgeChaincodes: - ids := make([]ent.Value, 0, len(m.chaincodes)) - for id := range m.chaincodes { - ids = append(ids, id) - } - return ids - } - return nil -} - -// RemovedEdges returns all edge names that were removed in this mutation. -func (m *TenantMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) - if m.removedchaincodes != nil { - edges = append(edges, tenant.EdgeChaincodes) - } - return edges -} - -// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with -// the given name in this mutation. -func (m *TenantMutation) RemovedIDs(name string) []ent.Value { - switch name { - case tenant.EdgeChaincodes: - ids := make([]ent.Value, 0, len(m.removedchaincodes)) - for id := range m.removedchaincodes { - ids = append(ids, id) - } - return ids - } - return nil -} - -// ClearedEdges returns all edge names that were cleared in this mutation. -func (m *TenantMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) - if m.clearedchaincodes { - edges = append(edges, tenant.EdgeChaincodes) - } - return edges -} - -// EdgeCleared returns a boolean which indicates if the edge with the given name -// was cleared in this mutation. -func (m *TenantMutation) EdgeCleared(name string) bool { - switch name { - case tenant.EdgeChaincodes: - return m.clearedchaincodes - } - return false -} - -// ClearEdge clears the value of the edge with the given name. It returns an error -// if that edge is not defined in the schema. -func (m *TenantMutation) ClearEdge(name string) error { - switch name { - } - return fmt.Errorf("unknown Tenant unique edge %s", name) -} - -// ResetEdge resets all changes to the edge with the given name in this mutation. -// It returns an error if the edge is not defined in the schema. -func (m *TenantMutation) ResetEdge(name string) error { - switch name { - case tenant.EdgeChaincodes: - m.ResetChaincodes() - return nil - } - return fmt.Errorf("unknown Tenant edge %s", name) -} diff --git a/ent/predicate/predicate.go b/ent/predicate/predicate.go deleted file mode 100644 index 1050623..0000000 --- a/ent/predicate/predicate.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package predicate - -import ( - "entgo.io/ent/dialect/sql" -) - -// Chaincode is the predicate function for chaincode builders. -type Chaincode func(*sql.Selector) - -// Tenant is the predicate function for tenant builders. -type Tenant func(*sql.Selector) diff --git a/ent/runtime.go b/ent/runtime.go deleted file mode 100644 index 9fb7c5f..0000000 --- a/ent/runtime.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/schema" -) - -// The init function reads all schema descriptors with runtime code -// (default values, validators, hooks and policies) and stitches it -// to their package variables. -func init() { - chaincodeFields := schema.Chaincode{}.Fields() - _ = chaincodeFields - // chaincodeDescPackageId is the schema descriptor for packageId field. - chaincodeDescPackageId := chaincodeFields[0].Descriptor() - // chaincode.PackageIdValidator is a validator for the "packageId" field. It is called by the builders before save. - chaincode.PackageIdValidator = chaincodeDescPackageId.Validators[0].(func(string) error) -} diff --git a/ent/runtime/runtime.go b/ent/runtime/runtime.go deleted file mode 100644 index e578a36..0000000 --- a/ent/runtime/runtime.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package runtime - -// The schema-stitching logic is generated in github.com/kfsoftware/hlf-cc-dev/ent/runtime.go - -const ( - Version = "v0.9.1" // Version of ent codegen. - Sum = "h1:IG8andyeD79GG24U8Q+1Y45hQXj6gY5evSBcva5gtBk=" // Sum of ent codegen. -) diff --git a/ent/schema/chaincode.go b/ent/schema/chaincode.go deleted file mode 100644 index 51ec050..0000000 --- a/ent/schema/chaincode.go +++ /dev/null @@ -1,29 +0,0 @@ -package schema - -import ( - "entgo.io/ent" - "entgo.io/ent/schema/edge" - "entgo.io/ent/schema/field" -) - -// Chaincode holds the schema definition for the Chaincode entity. -type Chaincode struct { - ent.Schema -} - -// Fields of the Chaincode. -func (Chaincode) Fields() []ent.Field { - return []ent.Field{ - field.String("packageId").NotEmpty(), - field.String("channelId"), - } -} - -// Edges of the Chaincode. -func (Chaincode) Edges() []ent.Edge { - return []ent.Edge{ - edge.From("tenant", Tenant.Type). - Ref("chaincodes"). - Unique(), - } -} diff --git a/ent/schema/tenant.go b/ent/schema/tenant.go deleted file mode 100644 index 9f64dfc..0000000 --- a/ent/schema/tenant.go +++ /dev/null @@ -1,31 +0,0 @@ -package schema - -import ( - "entgo.io/ent" - "entgo.io/ent/schema/edge" - "entgo.io/ent/schema/field" -) - -// Tenant holds the schema definition for the Tenant entity. -type Tenant struct { - ent.Schema -} - -// Fields of the Tenant. -func (Tenant) Fields() []ent.Field { - return []ent.Field{ - field.String("name").Unique(), - field.String("mspId"), - field.Bytes("signCertCAPrivateKey").Optional(), - field.Bytes("signCertCACert").Optional(), - field.Bytes("tlsCertCAPrivateKey").Optional(), - field.Bytes("tlsCertCACert").Optional(), - } -} - -// Edges of the Tenant. -func (Tenant) Edges() []ent.Edge { - return []ent.Edge{ - edge.To("chaincodes", Chaincode.Type), - } -} diff --git a/ent/tenant.go b/ent/tenant.go deleted file mode 100644 index 1232201..0000000 --- a/ent/tenant.go +++ /dev/null @@ -1,177 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "fmt" - "strings" - - "entgo.io/ent/dialect/sql" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// Tenant is the model entity for the Tenant schema. -type Tenant struct { - config `json:"-"` - // ID of the ent. - ID int `json:"id,omitempty"` - // Name holds the value of the "name" field. - Name string `json:"name,omitempty"` - // MspId holds the value of the "mspId" field. - MspId string `json:"mspId,omitempty"` - // SignCertCAPrivateKey holds the value of the "signCertCAPrivateKey" field. - SignCertCAPrivateKey []byte `json:"signCertCAPrivateKey,omitempty"` - // SignCertCACert holds the value of the "signCertCACert" field. - SignCertCACert []byte `json:"signCertCACert,omitempty"` - // TlsCertCAPrivateKey holds the value of the "tlsCertCAPrivateKey" field. - TlsCertCAPrivateKey []byte `json:"tlsCertCAPrivateKey,omitempty"` - // TlsCertCACert holds the value of the "tlsCertCACert" field. - TlsCertCACert []byte `json:"tlsCertCACert,omitempty"` - // Edges holds the relations/edges for other nodes in the graph. - // The values are being populated by the TenantQuery when eager-loading is set. - Edges TenantEdges `json:"edges"` -} - -// TenantEdges holds the relations/edges for other nodes in the graph. -type TenantEdges struct { - // Chaincodes holds the value of the chaincodes edge. - Chaincodes []*Chaincode `json:"chaincodes,omitempty"` - // loadedTypes holds the information for reporting if a - // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool -} - -// ChaincodesOrErr returns the Chaincodes value or an error if the edge -// was not loaded in eager-loading. -func (e TenantEdges) ChaincodesOrErr() ([]*Chaincode, error) { - if e.loadedTypes[0] { - return e.Chaincodes, nil - } - return nil, &NotLoadedError{edge: "chaincodes"} -} - -// scanValues returns the types for scanning values from sql.Rows. -func (*Tenant) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) - for i := range columns { - switch columns[i] { - case tenant.FieldSignCertCAPrivateKey, tenant.FieldSignCertCACert, tenant.FieldTlsCertCAPrivateKey, tenant.FieldTlsCertCACert: - values[i] = new([]byte) - case tenant.FieldID: - values[i] = new(sql.NullInt64) - case tenant.FieldName, tenant.FieldMspId: - values[i] = new(sql.NullString) - default: - return nil, fmt.Errorf("unexpected column %q for type Tenant", columns[i]) - } - } - return values, nil -} - -// assignValues assigns the values that were returned from sql.Rows (after scanning) -// to the Tenant fields. -func (t *Tenant) assignValues(columns []string, values []interface{}) error { - if m, n := len(values), len(columns); m < n { - return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) - } - for i := range columns { - switch columns[i] { - case tenant.FieldID: - value, ok := values[i].(*sql.NullInt64) - if !ok { - return fmt.Errorf("unexpected type %T for field id", value) - } - t.ID = int(value.Int64) - case tenant.FieldName: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field name", values[i]) - } else if value.Valid { - t.Name = value.String - } - case tenant.FieldMspId: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field mspId", values[i]) - } else if value.Valid { - t.MspId = value.String - } - case tenant.FieldSignCertCAPrivateKey: - if value, ok := values[i].(*[]byte); !ok { - return fmt.Errorf("unexpected type %T for field signCertCAPrivateKey", values[i]) - } else if value != nil { - t.SignCertCAPrivateKey = *value - } - case tenant.FieldSignCertCACert: - if value, ok := values[i].(*[]byte); !ok { - return fmt.Errorf("unexpected type %T for field signCertCACert", values[i]) - } else if value != nil { - t.SignCertCACert = *value - } - case tenant.FieldTlsCertCAPrivateKey: - if value, ok := values[i].(*[]byte); !ok { - return fmt.Errorf("unexpected type %T for field tlsCertCAPrivateKey", values[i]) - } else if value != nil { - t.TlsCertCAPrivateKey = *value - } - case tenant.FieldTlsCertCACert: - if value, ok := values[i].(*[]byte); !ok { - return fmt.Errorf("unexpected type %T for field tlsCertCACert", values[i]) - } else if value != nil { - t.TlsCertCACert = *value - } - } - } - return nil -} - -// QueryChaincodes queries the "chaincodes" edge of the Tenant entity. -func (t *Tenant) QueryChaincodes() *ChaincodeQuery { - return (&TenantClient{config: t.config}).QueryChaincodes(t) -} - -// Update returns a builder for updating this Tenant. -// Note that you need to call Tenant.Unwrap() before calling this method if this Tenant -// was returned from a transaction, and the transaction was committed or rolled back. -func (t *Tenant) Update() *TenantUpdateOne { - return (&TenantClient{config: t.config}).UpdateOne(t) -} - -// Unwrap unwraps the Tenant entity that was returned from a transaction after it was closed, -// so that all future queries will be executed through the driver which created the transaction. -func (t *Tenant) Unwrap() *Tenant { - tx, ok := t.config.driver.(*txDriver) - if !ok { - panic("ent: Tenant is not a transactional entity") - } - t.config.driver = tx.drv - return t -} - -// String implements the fmt.Stringer. -func (t *Tenant) String() string { - var builder strings.Builder - builder.WriteString("Tenant(") - builder.WriteString(fmt.Sprintf("id=%v", t.ID)) - builder.WriteString(", name=") - builder.WriteString(t.Name) - builder.WriteString(", mspId=") - builder.WriteString(t.MspId) - builder.WriteString(", signCertCAPrivateKey=") - builder.WriteString(fmt.Sprintf("%v", t.SignCertCAPrivateKey)) - builder.WriteString(", signCertCACert=") - builder.WriteString(fmt.Sprintf("%v", t.SignCertCACert)) - builder.WriteString(", tlsCertCAPrivateKey=") - builder.WriteString(fmt.Sprintf("%v", t.TlsCertCAPrivateKey)) - builder.WriteString(", tlsCertCACert=") - builder.WriteString(fmt.Sprintf("%v", t.TlsCertCACert)) - builder.WriteByte(')') - return builder.String() -} - -// Tenants is a parsable slice of Tenant. -type Tenants []*Tenant - -func (t Tenants) config(cfg config) { - for _i := range t { - t[_i].config = cfg - } -} diff --git a/ent/tenant/tenant.go b/ent/tenant/tenant.go deleted file mode 100644 index d0a9c38..0000000 --- a/ent/tenant/tenant.go +++ /dev/null @@ -1,54 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package tenant - -const ( - // Label holds the string label denoting the tenant type in the database. - Label = "tenant" - // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name field in the database. - FieldName = "name" - // FieldMspId holds the string denoting the mspid field in the database. - FieldMspId = "msp_id" - // FieldSignCertCAPrivateKey holds the string denoting the signcertcaprivatekey field in the database. - FieldSignCertCAPrivateKey = "sign_cert_ca_private_key" - // FieldSignCertCACert holds the string denoting the signcertcacert field in the database. - FieldSignCertCACert = "sign_cert_ca_cert" - // FieldTlsCertCAPrivateKey holds the string denoting the tlscertcaprivatekey field in the database. - FieldTlsCertCAPrivateKey = "tls_cert_ca_private_key" - // FieldTlsCertCACert holds the string denoting the tlscertcacert field in the database. - FieldTlsCertCACert = "tls_cert_ca_cert" - // EdgeChaincodes holds the string denoting the chaincodes edge name in mutations. - EdgeChaincodes = "chaincodes" - // Table holds the table name of the tenant in the database. - Table = "tenants" - // ChaincodesTable is the table that holds the chaincodes relation/edge. - ChaincodesTable = "chaincodes" - // ChaincodesInverseTable is the table name for the Chaincode entity. - // It exists in this package in order to avoid circular dependency with the "chaincode" package. - ChaincodesInverseTable = "chaincodes" - // ChaincodesColumn is the table column denoting the chaincodes relation/edge. - ChaincodesColumn = "tenant_chaincodes" -) - -// Columns holds all SQL columns for tenant fields. -var Columns = []string{ - FieldID, - FieldName, - FieldMspId, - FieldSignCertCAPrivateKey, - FieldSignCertCACert, - FieldTlsCertCAPrivateKey, - FieldTlsCertCACert, -} - -// ValidColumn reports if the column name is valid (part of the table columns). -func ValidColumn(column string) bool { - for i := range Columns { - if column == Columns[i] { - return true - } - } - return false -} diff --git a/ent/tenant/where.go b/ent/tenant/where.go deleted file mode 100644 index 0641682..0000000 --- a/ent/tenant/where.go +++ /dev/null @@ -1,776 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package tenant - -import ( - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" -) - -// ID filters vertices based on their ID field. -func ID(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) -} - -// IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) -} - -// IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) -} - -// IDIn applies the In predicate on the ID field. -func IDIn(ids ...int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(ids) == 0 { - s.Where(sql.False()) - return - } - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) -} - -// IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(ids) == 0 { - s.Where(sql.False()) - return - } - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) -} - -// IDGT applies the GT predicate on the ID field. -func IDGT(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) -} - -// IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) -} - -// IDLT applies the LT predicate on the ID field. -func IDLT(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) -} - -// IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) -} - -// Name applies equality check predicate on the "name" field. It's identical to NameEQ. -func Name(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) -} - -// MspId applies equality check predicate on the "mspId" field. It's identical to MspIdEQ. -func MspId(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldMspId), v)) - }) -} - -// SignCertCAPrivateKey applies equality check predicate on the "signCertCAPrivateKey" field. It's identical to SignCertCAPrivateKeyEQ. -func SignCertCAPrivateKey(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCACert applies equality check predicate on the "signCertCACert" field. It's identical to SignCertCACertEQ. -func SignCertCACert(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSignCertCACert), v)) - }) -} - -// TlsCertCAPrivateKey applies equality check predicate on the "tlsCertCAPrivateKey" field. It's identical to TlsCertCAPrivateKeyEQ. -func TlsCertCAPrivateKey(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCACert applies equality check predicate on the "tlsCertCACert" field. It's identical to TlsCertCACertEQ. -func TlsCertCACert(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldTlsCertCACert), v)) - }) -} - -// NameEQ applies the EQ predicate on the "name" field. -func NameEQ(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) -} - -// NameNEQ applies the NEQ predicate on the "name" field. -func NameNEQ(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldName), v)) - }) -} - -// NameIn applies the In predicate on the "name" field. -func NameIn(vs ...string) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldName), v...)) - }) -} - -// NameNotIn applies the NotIn predicate on the "name" field. -func NameNotIn(vs ...string) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldName), v...)) - }) -} - -// NameGT applies the GT predicate on the "name" field. -func NameGT(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldName), v)) - }) -} - -// NameGTE applies the GTE predicate on the "name" field. -func NameGTE(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldName), v)) - }) -} - -// NameLT applies the LT predicate on the "name" field. -func NameLT(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldName), v)) - }) -} - -// NameLTE applies the LTE predicate on the "name" field. -func NameLTE(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldName), v)) - }) -} - -// NameContains applies the Contains predicate on the "name" field. -func NameContains(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldName), v)) - }) -} - -// NameHasPrefix applies the HasPrefix predicate on the "name" field. -func NameHasPrefix(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldName), v)) - }) -} - -// NameHasSuffix applies the HasSuffix predicate on the "name" field. -func NameHasSuffix(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldName), v)) - }) -} - -// NameEqualFold applies the EqualFold predicate on the "name" field. -func NameEqualFold(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldName), v)) - }) -} - -// NameContainsFold applies the ContainsFold predicate on the "name" field. -func NameContainsFold(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldName), v)) - }) -} - -// MspIdEQ applies the EQ predicate on the "mspId" field. -func MspIdEQ(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldMspId), v)) - }) -} - -// MspIdNEQ applies the NEQ predicate on the "mspId" field. -func MspIdNEQ(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldMspId), v)) - }) -} - -// MspIdIn applies the In predicate on the "mspId" field. -func MspIdIn(vs ...string) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldMspId), v...)) - }) -} - -// MspIdNotIn applies the NotIn predicate on the "mspId" field. -func MspIdNotIn(vs ...string) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldMspId), v...)) - }) -} - -// MspIdGT applies the GT predicate on the "mspId" field. -func MspIdGT(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldMspId), v)) - }) -} - -// MspIdGTE applies the GTE predicate on the "mspId" field. -func MspIdGTE(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldMspId), v)) - }) -} - -// MspIdLT applies the LT predicate on the "mspId" field. -func MspIdLT(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldMspId), v)) - }) -} - -// MspIdLTE applies the LTE predicate on the "mspId" field. -func MspIdLTE(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldMspId), v)) - }) -} - -// MspIdContains applies the Contains predicate on the "mspId" field. -func MspIdContains(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldMspId), v)) - }) -} - -// MspIdHasPrefix applies the HasPrefix predicate on the "mspId" field. -func MspIdHasPrefix(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldMspId), v)) - }) -} - -// MspIdHasSuffix applies the HasSuffix predicate on the "mspId" field. -func MspIdHasSuffix(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldMspId), v)) - }) -} - -// MspIdEqualFold applies the EqualFold predicate on the "mspId" field. -func MspIdEqualFold(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldMspId), v)) - }) -} - -// MspIdContainsFold applies the ContainsFold predicate on the "mspId" field. -func MspIdContainsFold(v string) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldMspId), v)) - }) -} - -// SignCertCAPrivateKeyEQ applies the EQ predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyNEQ applies the NEQ predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyNEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyIn applies the In predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldSignCertCAPrivateKey), v...)) - }) -} - -// SignCertCAPrivateKeyNotIn applies the NotIn predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyNotIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldSignCertCAPrivateKey), v...)) - }) -} - -// SignCertCAPrivateKeyGT applies the GT predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyGT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyGTE applies the GTE predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyGTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyLT applies the LT predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyLT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyLTE applies the LTE predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyLTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldSignCertCAPrivateKey), v)) - }) -} - -// SignCertCAPrivateKeyIsNil applies the IsNil predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyIsNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldSignCertCAPrivateKey))) - }) -} - -// SignCertCAPrivateKeyNotNil applies the NotNil predicate on the "signCertCAPrivateKey" field. -func SignCertCAPrivateKeyNotNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldSignCertCAPrivateKey))) - }) -} - -// SignCertCACertEQ applies the EQ predicate on the "signCertCACert" field. -func SignCertCACertEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertNEQ applies the NEQ predicate on the "signCertCACert" field. -func SignCertCACertNEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertIn applies the In predicate on the "signCertCACert" field. -func SignCertCACertIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldSignCertCACert), v...)) - }) -} - -// SignCertCACertNotIn applies the NotIn predicate on the "signCertCACert" field. -func SignCertCACertNotIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldSignCertCACert), v...)) - }) -} - -// SignCertCACertGT applies the GT predicate on the "signCertCACert" field. -func SignCertCACertGT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertGTE applies the GTE predicate on the "signCertCACert" field. -func SignCertCACertGTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertLT applies the LT predicate on the "signCertCACert" field. -func SignCertCACertLT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertLTE applies the LTE predicate on the "signCertCACert" field. -func SignCertCACertLTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldSignCertCACert), v)) - }) -} - -// SignCertCACertIsNil applies the IsNil predicate on the "signCertCACert" field. -func SignCertCACertIsNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldSignCertCACert))) - }) -} - -// SignCertCACertNotNil applies the NotNil predicate on the "signCertCACert" field. -func SignCertCACertNotNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldSignCertCACert))) - }) -} - -// TlsCertCAPrivateKeyEQ applies the EQ predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyNEQ applies the NEQ predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyNEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyIn applies the In predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldTlsCertCAPrivateKey), v...)) - }) -} - -// TlsCertCAPrivateKeyNotIn applies the NotIn predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyNotIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldTlsCertCAPrivateKey), v...)) - }) -} - -// TlsCertCAPrivateKeyGT applies the GT predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyGT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyGTE applies the GTE predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyGTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyLT applies the LT predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyLT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyLTE applies the LTE predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyLTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldTlsCertCAPrivateKey), v)) - }) -} - -// TlsCertCAPrivateKeyIsNil applies the IsNil predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyIsNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldTlsCertCAPrivateKey))) - }) -} - -// TlsCertCAPrivateKeyNotNil applies the NotNil predicate on the "tlsCertCAPrivateKey" field. -func TlsCertCAPrivateKeyNotNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldTlsCertCAPrivateKey))) - }) -} - -// TlsCertCACertEQ applies the EQ predicate on the "tlsCertCACert" field. -func TlsCertCACertEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertNEQ applies the NEQ predicate on the "tlsCertCACert" field. -func TlsCertCACertNEQ(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertIn applies the In predicate on the "tlsCertCACert" field. -func TlsCertCACertIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldTlsCertCACert), v...)) - }) -} - -// TlsCertCACertNotIn applies the NotIn predicate on the "tlsCertCACert" field. -func TlsCertCACertNotIn(vs ...[]byte) predicate.Tenant { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Tenant(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldTlsCertCACert), v...)) - }) -} - -// TlsCertCACertGT applies the GT predicate on the "tlsCertCACert" field. -func TlsCertCACertGT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertGTE applies the GTE predicate on the "tlsCertCACert" field. -func TlsCertCACertGTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertLT applies the LT predicate on the "tlsCertCACert" field. -func TlsCertCACertLT(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertLTE applies the LTE predicate on the "tlsCertCACert" field. -func TlsCertCACertLTE(v []byte) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldTlsCertCACert), v)) - }) -} - -// TlsCertCACertIsNil applies the IsNil predicate on the "tlsCertCACert" field. -func TlsCertCACertIsNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldTlsCertCACert))) - }) -} - -// TlsCertCACertNotNil applies the NotNil predicate on the "tlsCertCACert" field. -func TlsCertCACertNotNil() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldTlsCertCACert))) - }) -} - -// HasChaincodes applies the HasEdge predicate on the "chaincodes" edge. -func HasChaincodes() predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(ChaincodesTable, FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, ChaincodesTable, ChaincodesColumn), - ) - sqlgraph.HasNeighbors(s, step) - }) -} - -// HasChaincodesWith applies the HasEdge predicate on the "chaincodes" edge with a given conditions (other predicates). -func HasChaincodesWith(preds ...predicate.Chaincode) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(ChaincodesInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, ChaincodesTable, ChaincodesColumn), - ) - sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { - for _, p := range preds { - p(s) - } - }) - }) -} - -// And groups predicates with the AND operator between them. -func And(predicates ...predicate.Tenant) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) -} - -// Or groups predicates with the OR operator between them. -func Or(predicates ...predicate.Tenant) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) -} - -// Not applies the not operator on the given predicate. -func Not(p predicate.Tenant) predicate.Tenant { - return predicate.Tenant(func(s *sql.Selector) { - p(s.Not()) - }) -} diff --git a/ent/tenant_create.go b/ent/tenant_create.go deleted file mode 100644 index d12f672..0000000 --- a/ent/tenant_create.go +++ /dev/null @@ -1,328 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// TenantCreate is the builder for creating a Tenant entity. -type TenantCreate struct { - config - mutation *TenantMutation - hooks []Hook -} - -// SetName sets the "name" field. -func (tc *TenantCreate) SetName(s string) *TenantCreate { - tc.mutation.SetName(s) - return tc -} - -// SetMspId sets the "mspId" field. -func (tc *TenantCreate) SetMspId(s string) *TenantCreate { - tc.mutation.SetMspId(s) - return tc -} - -// SetSignCertCAPrivateKey sets the "signCertCAPrivateKey" field. -func (tc *TenantCreate) SetSignCertCAPrivateKey(b []byte) *TenantCreate { - tc.mutation.SetSignCertCAPrivateKey(b) - return tc -} - -// SetSignCertCACert sets the "signCertCACert" field. -func (tc *TenantCreate) SetSignCertCACert(b []byte) *TenantCreate { - tc.mutation.SetSignCertCACert(b) - return tc -} - -// SetTlsCertCAPrivateKey sets the "tlsCertCAPrivateKey" field. -func (tc *TenantCreate) SetTlsCertCAPrivateKey(b []byte) *TenantCreate { - tc.mutation.SetTlsCertCAPrivateKey(b) - return tc -} - -// SetTlsCertCACert sets the "tlsCertCACert" field. -func (tc *TenantCreate) SetTlsCertCACert(b []byte) *TenantCreate { - tc.mutation.SetTlsCertCACert(b) - return tc -} - -// AddChaincodeIDs adds the "chaincodes" edge to the Chaincode entity by IDs. -func (tc *TenantCreate) AddChaincodeIDs(ids ...int) *TenantCreate { - tc.mutation.AddChaincodeIDs(ids...) - return tc -} - -// AddChaincodes adds the "chaincodes" edges to the Chaincode entity. -func (tc *TenantCreate) AddChaincodes(c ...*Chaincode) *TenantCreate { - ids := make([]int, len(c)) - for i := range c { - ids[i] = c[i].ID - } - return tc.AddChaincodeIDs(ids...) -} - -// Mutation returns the TenantMutation object of the builder. -func (tc *TenantCreate) Mutation() *TenantMutation { - return tc.mutation -} - -// Save creates the Tenant in the database. -func (tc *TenantCreate) Save(ctx context.Context) (*Tenant, error) { - var ( - err error - node *Tenant - ) - if len(tc.hooks) == 0 { - if err = tc.check(); err != nil { - return nil, err - } - node, err = tc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = tc.check(); err != nil { - return nil, err - } - tc.mutation = mutation - if node, err = tc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(tc.hooks) - 1; i >= 0; i-- { - if tc.hooks[i] == nil { - return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = tc.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, tc.mutation); err != nil { - return nil, err - } - } - return node, err -} - -// SaveX calls Save and panics if Save returns an error. -func (tc *TenantCreate) SaveX(ctx context.Context) *Tenant { - v, err := tc.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (tc *TenantCreate) Exec(ctx context.Context) error { - _, err := tc.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (tc *TenantCreate) ExecX(ctx context.Context) { - if err := tc.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (tc *TenantCreate) check() error { - if _, ok := tc.mutation.Name(); !ok { - return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "name"`)} - } - if _, ok := tc.mutation.MspId(); !ok { - return &ValidationError{Name: "mspId", err: errors.New(`ent: missing required field "mspId"`)} - } - return nil -} - -func (tc *TenantCreate) sqlSave(ctx context.Context) (*Tenant, error) { - _node, _spec := tc.createSpec() - if err := sqlgraph.CreateNode(ctx, tc.driver, _spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return nil, err - } - id := _spec.ID.Value.(int64) - _node.ID = int(id) - return _node, nil -} - -func (tc *TenantCreate) createSpec() (*Tenant, *sqlgraph.CreateSpec) { - var ( - _node = &Tenant{config: tc.config} - _spec = &sqlgraph.CreateSpec{ - Table: tenant.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - } - ) - if value, ok := tc.mutation.Name(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldName, - }) - _node.Name = value - } - if value, ok := tc.mutation.MspId(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldMspId, - }) - _node.MspId = value - } - if value, ok := tc.mutation.SignCertCAPrivateKey(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCAPrivateKey, - }) - _node.SignCertCAPrivateKey = value - } - if value, ok := tc.mutation.SignCertCACert(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCACert, - }) - _node.SignCertCACert = value - } - if value, ok := tc.mutation.TlsCertCAPrivateKey(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCAPrivateKey, - }) - _node.TlsCertCAPrivateKey = value - } - if value, ok := tc.mutation.TlsCertCACert(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCACert, - }) - _node.TlsCertCACert = value - } - if nodes := tc.mutation.ChaincodesIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges = append(_spec.Edges, edge) - } - return _node, _spec -} - -// TenantCreateBulk is the builder for creating many Tenant entities in bulk. -type TenantCreateBulk struct { - config - builders []*TenantCreate -} - -// Save creates the Tenant entities in the database. -func (tcb *TenantCreateBulk) Save(ctx context.Context) ([]*Tenant, error) { - specs := make([]*sqlgraph.CreateSpec, len(tcb.builders)) - nodes := make([]*Tenant, len(tcb.builders)) - mutators := make([]Mutator, len(tcb.builders)) - for i := range tcb.builders { - func(i int, root context.Context) { - builder := tcb.builders[i] - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err := builder.check(); err != nil { - return nil, err - } - builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() - var err error - if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, tcb.builders[i+1].mutation) - } else { - spec := &sqlgraph.BatchCreateSpec{Nodes: specs} - // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, tcb.driver, spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - } - } - if err != nil { - return nil, err - } - mutation.id = &nodes[i].ID - mutation.done = true - if specs[i].ID.Value != nil { - id := specs[i].ID.Value.(int64) - nodes[i].ID = int(id) - } - return nodes[i], nil - }) - for i := len(builder.hooks) - 1; i >= 0; i-- { - mut = builder.hooks[i](mut) - } - mutators[i] = mut - }(i, ctx) - } - if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, tcb.builders[0].mutation); err != nil { - return nil, err - } - } - return nodes, nil -} - -// SaveX is like Save, but panics if an error occurs. -func (tcb *TenantCreateBulk) SaveX(ctx context.Context) []*Tenant { - v, err := tcb.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (tcb *TenantCreateBulk) Exec(ctx context.Context) error { - _, err := tcb.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (tcb *TenantCreateBulk) ExecX(ctx context.Context) { - if err := tcb.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/tenant_delete.go b/ent/tenant_delete.go deleted file mode 100644 index ad7fe98..0000000 --- a/ent/tenant_delete.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// TenantDelete is the builder for deleting a Tenant entity. -type TenantDelete struct { - config - hooks []Hook - mutation *TenantMutation -} - -// Where appends a list predicates to the TenantDelete builder. -func (td *TenantDelete) Where(ps ...predicate.Tenant) *TenantDelete { - td.mutation.Where(ps...) - return td -} - -// Exec executes the deletion query and returns how many vertices were deleted. -func (td *TenantDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(td.hooks) == 0 { - affected, err = td.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - td.mutation = mutation - affected, err = td.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(td.hooks) - 1; i >= 0; i-- { - if td.hooks[i] == nil { - return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = td.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, td.mutation); err != nil { - return 0, err - } - } - return affected, err -} - -// ExecX is like Exec, but panics if an error occurs. -func (td *TenantDelete) ExecX(ctx context.Context) int { - n, err := td.Exec(ctx) - if err != nil { - panic(err) - } - return n -} - -func (td *TenantDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: tenant.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - if ps := td.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return sqlgraph.DeleteNodes(ctx, td.driver, _spec) -} - -// TenantDeleteOne is the builder for deleting a single Tenant entity. -type TenantDeleteOne struct { - td *TenantDelete -} - -// Exec executes the deletion query. -func (tdo *TenantDeleteOne) Exec(ctx context.Context) error { - n, err := tdo.td.Exec(ctx) - switch { - case err != nil: - return err - case n == 0: - return &NotFoundError{tenant.Label} - default: - return nil - } -} - -// ExecX is like Exec, but panics if an error occurs. -func (tdo *TenantDeleteOne) ExecX(ctx context.Context) { - tdo.td.ExecX(ctx) -} diff --git a/ent/tenant_query.go b/ent/tenant_query.go deleted file mode 100644 index f4e31ca..0000000 --- a/ent/tenant_query.go +++ /dev/null @@ -1,987 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "database/sql/driver" - "errors" - "fmt" - "math" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// TenantQuery is the builder for querying Tenant entities. -type TenantQuery struct { - config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string - predicates []predicate.Tenant - // eager-loading edges. - withChaincodes *ChaincodeQuery - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Where adds a new predicate for the TenantQuery builder. -func (tq *TenantQuery) Where(ps ...predicate.Tenant) *TenantQuery { - tq.predicates = append(tq.predicates, ps...) - return tq -} - -// Limit adds a limit step to the query. -func (tq *TenantQuery) Limit(limit int) *TenantQuery { - tq.limit = &limit - return tq -} - -// Offset adds an offset step to the query. -func (tq *TenantQuery) Offset(offset int) *TenantQuery { - tq.offset = &offset - return tq -} - -// Unique configures the query builder to filter duplicate records on query. -// By default, unique is set to true, and can be disabled using this method. -func (tq *TenantQuery) Unique(unique bool) *TenantQuery { - tq.unique = &unique - return tq -} - -// Order adds an order step to the query. -func (tq *TenantQuery) Order(o ...OrderFunc) *TenantQuery { - tq.order = append(tq.order, o...) - return tq -} - -// QueryChaincodes chains the current query on the "chaincodes" edge. -func (tq *TenantQuery) QueryChaincodes() *ChaincodeQuery { - query := &ChaincodeQuery{config: tq.config} - query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { - if err := tq.prepareQuery(ctx); err != nil { - return nil, err - } - selector := tq.sqlQuery(ctx) - if err := selector.Err(); err != nil { - return nil, err - } - step := sqlgraph.NewStep( - sqlgraph.From(tenant.Table, tenant.FieldID, selector), - sqlgraph.To(chaincode.Table, chaincode.FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, tenant.ChaincodesTable, tenant.ChaincodesColumn), - ) - fromU = sqlgraph.SetNeighbors(tq.driver.Dialect(), step) - return fromU, nil - } - return query -} - -// First returns the first Tenant entity from the query. -// Returns a *NotFoundError when no Tenant was found. -func (tq *TenantQuery) First(ctx context.Context) (*Tenant, error) { - nodes, err := tq.Limit(1).All(ctx) - if err != nil { - return nil, err - } - if len(nodes) == 0 { - return nil, &NotFoundError{tenant.Label} - } - return nodes[0], nil -} - -// FirstX is like First, but panics if an error occurs. -func (tq *TenantQuery) FirstX(ctx context.Context) *Tenant { - node, err := tq.First(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return node -} - -// FirstID returns the first Tenant ID from the query. -// Returns a *NotFoundError when no Tenant ID was found. -func (tq *TenantQuery) FirstID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = tq.Limit(1).IDs(ctx); err != nil { - return - } - if len(ids) == 0 { - err = &NotFoundError{tenant.Label} - return - } - return ids[0], nil -} - -// FirstIDX is like FirstID, but panics if an error occurs. -func (tq *TenantQuery) FirstIDX(ctx context.Context) int { - id, err := tq.FirstID(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return id -} - -// Only returns a single Tenant entity found by the query, ensuring it only returns one. -// Returns a *NotSingularError when exactly one Tenant entity is not found. -// Returns a *NotFoundError when no Tenant entities are found. -func (tq *TenantQuery) Only(ctx context.Context) (*Tenant, error) { - nodes, err := tq.Limit(2).All(ctx) - if err != nil { - return nil, err - } - switch len(nodes) { - case 1: - return nodes[0], nil - case 0: - return nil, &NotFoundError{tenant.Label} - default: - return nil, &NotSingularError{tenant.Label} - } -} - -// OnlyX is like Only, but panics if an error occurs. -func (tq *TenantQuery) OnlyX(ctx context.Context) *Tenant { - node, err := tq.Only(ctx) - if err != nil { - panic(err) - } - return node -} - -// OnlyID is like Only, but returns the only Tenant ID in the query. -// Returns a *NotSingularError when exactly one Tenant ID is not found. -// Returns a *NotFoundError when no entities are found. -func (tq *TenantQuery) OnlyID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = tq.Limit(2).IDs(ctx); err != nil { - return - } - switch len(ids) { - case 1: - id = ids[0] - case 0: - err = &NotFoundError{tenant.Label} - default: - err = &NotSingularError{tenant.Label} - } - return -} - -// OnlyIDX is like OnlyID, but panics if an error occurs. -func (tq *TenantQuery) OnlyIDX(ctx context.Context) int { - id, err := tq.OnlyID(ctx) - if err != nil { - panic(err) - } - return id -} - -// All executes the query and returns a list of Tenants. -func (tq *TenantQuery) All(ctx context.Context) ([]*Tenant, error) { - if err := tq.prepareQuery(ctx); err != nil { - return nil, err - } - return tq.sqlAll(ctx) -} - -// AllX is like All, but panics if an error occurs. -func (tq *TenantQuery) AllX(ctx context.Context) []*Tenant { - nodes, err := tq.All(ctx) - if err != nil { - panic(err) - } - return nodes -} - -// IDs executes the query and returns a list of Tenant IDs. -func (tq *TenantQuery) IDs(ctx context.Context) ([]int, error) { - var ids []int - if err := tq.Select(tenant.FieldID).Scan(ctx, &ids); err != nil { - return nil, err - } - return ids, nil -} - -// IDsX is like IDs, but panics if an error occurs. -func (tq *TenantQuery) IDsX(ctx context.Context) []int { - ids, err := tq.IDs(ctx) - if err != nil { - panic(err) - } - return ids -} - -// Count returns the count of the given query. -func (tq *TenantQuery) Count(ctx context.Context) (int, error) { - if err := tq.prepareQuery(ctx); err != nil { - return 0, err - } - return tq.sqlCount(ctx) -} - -// CountX is like Count, but panics if an error occurs. -func (tq *TenantQuery) CountX(ctx context.Context) int { - count, err := tq.Count(ctx) - if err != nil { - panic(err) - } - return count -} - -// Exist returns true if the query has elements in the graph. -func (tq *TenantQuery) Exist(ctx context.Context) (bool, error) { - if err := tq.prepareQuery(ctx); err != nil { - return false, err - } - return tq.sqlExist(ctx) -} - -// ExistX is like Exist, but panics if an error occurs. -func (tq *TenantQuery) ExistX(ctx context.Context) bool { - exist, err := tq.Exist(ctx) - if err != nil { - panic(err) - } - return exist -} - -// Clone returns a duplicate of the TenantQuery builder, including all associated steps. It can be -// used to prepare common query builders and use them differently after the clone is made. -func (tq *TenantQuery) Clone() *TenantQuery { - if tq == nil { - return nil - } - return &TenantQuery{ - config: tq.config, - limit: tq.limit, - offset: tq.offset, - order: append([]OrderFunc{}, tq.order...), - predicates: append([]predicate.Tenant{}, tq.predicates...), - withChaincodes: tq.withChaincodes.Clone(), - // clone intermediate query. - sql: tq.sql.Clone(), - path: tq.path, - } -} - -// WithChaincodes tells the query-builder to eager-load the nodes that are connected to -// the "chaincodes" edge. The optional arguments are used to configure the query builder of the edge. -func (tq *TenantQuery) WithChaincodes(opts ...func(*ChaincodeQuery)) *TenantQuery { - query := &ChaincodeQuery{config: tq.config} - for _, opt := range opts { - opt(query) - } - tq.withChaincodes = query - return tq -} - -// GroupBy is used to group vertices by one or more fields/columns. -// It is often used with aggregate functions, like: count, max, mean, min, sum. -// -// Example: -// -// var v []struct { -// Name string `json:"name,omitempty"` -// Count int `json:"count,omitempty"` -// } -// -// client.Tenant.Query(). -// GroupBy(tenant.FieldName). -// Aggregate(ent.Count()). -// Scan(ctx, &v) -// -func (tq *TenantQuery) GroupBy(field string, fields ...string) *TenantGroupBy { - group := &TenantGroupBy{config: tq.config} - group.fields = append([]string{field}, fields...) - group.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := tq.prepareQuery(ctx); err != nil { - return nil, err - } - return tq.sqlQuery(ctx), nil - } - return group -} - -// Select allows the selection one or more fields/columns for the given query, -// instead of selecting all fields in the entity. -// -// Example: -// -// var v []struct { -// Name string `json:"name,omitempty"` -// } -// -// client.Tenant.Query(). -// Select(tenant.FieldName). -// Scan(ctx, &v) -// -func (tq *TenantQuery) Select(fields ...string) *TenantSelect { - tq.fields = append(tq.fields, fields...) - return &TenantSelect{TenantQuery: tq} -} - -func (tq *TenantQuery) prepareQuery(ctx context.Context) error { - for _, f := range tq.fields { - if !tenant.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - } - if tq.path != nil { - prev, err := tq.path(ctx) - if err != nil { - return err - } - tq.sql = prev - } - return nil -} - -func (tq *TenantQuery) sqlAll(ctx context.Context) ([]*Tenant, error) { - var ( - nodes = []*Tenant{} - _spec = tq.querySpec() - loadedTypes = [1]bool{ - tq.withChaincodes != nil, - } - ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { - node := &Tenant{config: tq.config} - nodes = append(nodes, node) - return node.scanValues(columns) - } - _spec.Assign = func(columns []string, values []interface{}) error { - if len(nodes) == 0 { - return fmt.Errorf("ent: Assign called without calling ScanValues") - } - node := nodes[len(nodes)-1] - node.Edges.loadedTypes = loadedTypes - return node.assignValues(columns, values) - } - if err := sqlgraph.QueryNodes(ctx, tq.driver, _spec); err != nil { - return nil, err - } - if len(nodes) == 0 { - return nodes, nil - } - - if query := tq.withChaincodes; query != nil { - fks := make([]driver.Value, 0, len(nodes)) - nodeids := make(map[int]*Tenant) - for i := range nodes { - fks = append(fks, nodes[i].ID) - nodeids[nodes[i].ID] = nodes[i] - nodes[i].Edges.Chaincodes = []*Chaincode{} - } - query.withFKs = true - query.Where(predicate.Chaincode(func(s *sql.Selector) { - s.Where(sql.InValues(tenant.ChaincodesColumn, fks...)) - })) - neighbors, err := query.All(ctx) - if err != nil { - return nil, err - } - for _, n := range neighbors { - fk := n.tenant_chaincodes - if fk == nil { - return nil, fmt.Errorf(`foreign-key "tenant_chaincodes" is nil for node %v`, n.ID) - } - node, ok := nodeids[*fk] - if !ok { - return nil, fmt.Errorf(`unexpected foreign-key "tenant_chaincodes" returned %v for node %v`, *fk, n.ID) - } - node.Edges.Chaincodes = append(node.Edges.Chaincodes, n) - } - } - - return nodes, nil -} - -func (tq *TenantQuery) sqlCount(ctx context.Context) (int, error) { - _spec := tq.querySpec() - return sqlgraph.CountNodes(ctx, tq.driver, _spec) -} - -func (tq *TenantQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := tq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("ent: check existence: %w", err) - } - return n > 0, nil -} - -func (tq *TenantQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: tenant.Table, - Columns: tenant.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - From: tq.sql, - Unique: true, - } - if unique := tq.unique; unique != nil { - _spec.Unique = *unique - } - if fields := tq.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, tenant.FieldID) - for i := range fields { - if fields[i] != tenant.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) - } - } - } - if ps := tq.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if limit := tq.limit; limit != nil { - _spec.Limit = *limit - } - if offset := tq.offset; offset != nil { - _spec.Offset = *offset - } - if ps := tq.order; len(ps) > 0 { - _spec.Order = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return _spec -} - -func (tq *TenantQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(tq.driver.Dialect()) - t1 := builder.Table(tenant.Table) - columns := tq.fields - if len(columns) == 0 { - columns = tenant.Columns - } - selector := builder.Select(t1.Columns(columns...)...).From(t1) - if tq.sql != nil { - selector = tq.sql - selector.Select(selector.Columns(columns...)...) - } - for _, p := range tq.predicates { - p(selector) - } - for _, p := range tq.order { - p(selector) - } - if offset := tq.offset; offset != nil { - // limit is mandatory for offset clause. We start - // with default value, and override it below if needed. - selector.Offset(*offset).Limit(math.MaxInt32) - } - if limit := tq.limit; limit != nil { - selector.Limit(*limit) - } - return selector -} - -// TenantGroupBy is the group-by builder for Tenant entities. -type TenantGroupBy struct { - config - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Aggregate adds the given aggregation functions to the group-by query. -func (tgb *TenantGroupBy) Aggregate(fns ...AggregateFunc) *TenantGroupBy { - tgb.fns = append(tgb.fns, fns...) - return tgb -} - -// Scan applies the group-by query and scans the result into the given value. -func (tgb *TenantGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := tgb.path(ctx) - if err != nil { - return err - } - tgb.sql = query - return tgb.sqlScan(ctx, v) -} - -// ScanX is like Scan, but panics if an error occurs. -func (tgb *TenantGroupBy) ScanX(ctx context.Context, v interface{}) { - if err := tgb.Scan(ctx, v); err != nil { - panic(err) - } -} - -// Strings returns list of strings from group-by. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Strings(ctx context.Context) ([]string, error) { - if len(tgb.fields) > 1 { - return nil, errors.New("ent: TenantGroupBy.Strings is not achievable when grouping more than 1 field") - } - var v []string - if err := tgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// StringsX is like Strings, but panics if an error occurs. -func (tgb *TenantGroupBy) StringsX(ctx context.Context) []string { - v, err := tgb.Strings(ctx) - if err != nil { - panic(err) - } - return v -} - -// String returns a single string from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) String(ctx context.Context) (_ string, err error) { - var v []string - if v, err = tgb.Strings(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantGroupBy.Strings returned %d results when one was expected", len(v)) - } - return -} - -// StringX is like String, but panics if an error occurs. -func (tgb *TenantGroupBy) StringX(ctx context.Context) string { - v, err := tgb.String(ctx) - if err != nil { - panic(err) - } - return v -} - -// Ints returns list of ints from group-by. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Ints(ctx context.Context) ([]int, error) { - if len(tgb.fields) > 1 { - return nil, errors.New("ent: TenantGroupBy.Ints is not achievable when grouping more than 1 field") - } - var v []int - if err := tgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// IntsX is like Ints, but panics if an error occurs. -func (tgb *TenantGroupBy) IntsX(ctx context.Context) []int { - v, err := tgb.Ints(ctx) - if err != nil { - panic(err) - } - return v -} - -// Int returns a single int from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Int(ctx context.Context) (_ int, err error) { - var v []int - if v, err = tgb.Ints(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantGroupBy.Ints returned %d results when one was expected", len(v)) - } - return -} - -// IntX is like Int, but panics if an error occurs. -func (tgb *TenantGroupBy) IntX(ctx context.Context) int { - v, err := tgb.Int(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64s returns list of float64s from group-by. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Float64s(ctx context.Context) ([]float64, error) { - if len(tgb.fields) > 1 { - return nil, errors.New("ent: TenantGroupBy.Float64s is not achievable when grouping more than 1 field") - } - var v []float64 - if err := tgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// Float64sX is like Float64s, but panics if an error occurs. -func (tgb *TenantGroupBy) Float64sX(ctx context.Context) []float64 { - v, err := tgb.Float64s(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64 returns a single float64 from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Float64(ctx context.Context) (_ float64, err error) { - var v []float64 - if v, err = tgb.Float64s(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantGroupBy.Float64s returned %d results when one was expected", len(v)) - } - return -} - -// Float64X is like Float64, but panics if an error occurs. -func (tgb *TenantGroupBy) Float64X(ctx context.Context) float64 { - v, err := tgb.Float64(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bools returns list of bools from group-by. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Bools(ctx context.Context) ([]bool, error) { - if len(tgb.fields) > 1 { - return nil, errors.New("ent: TenantGroupBy.Bools is not achievable when grouping more than 1 field") - } - var v []bool - if err := tgb.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// BoolsX is like Bools, but panics if an error occurs. -func (tgb *TenantGroupBy) BoolsX(ctx context.Context) []bool { - v, err := tgb.Bools(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bool returns a single bool from a group-by query. -// It is only allowed when executing a group-by query with one field. -func (tgb *TenantGroupBy) Bool(ctx context.Context) (_ bool, err error) { - var v []bool - if v, err = tgb.Bools(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantGroupBy.Bools returned %d results when one was expected", len(v)) - } - return -} - -// BoolX is like Bool, but panics if an error occurs. -func (tgb *TenantGroupBy) BoolX(ctx context.Context) bool { - v, err := tgb.Bool(ctx) - if err != nil { - panic(err) - } - return v -} - -func (tgb *TenantGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range tgb.fields { - if !tenant.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} - } - } - selector := tgb.sqlQuery() - if err := selector.Err(); err != nil { - return err - } - rows := &sql.Rows{} - query, args := selector.Query() - if err := tgb.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} - -func (tgb *TenantGroupBy) sqlQuery() *sql.Selector { - selector := tgb.sql.Select() - aggregation := make([]string, 0, len(tgb.fns)) - for _, fn := range tgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(tgb.fields)+len(tgb.fns)) - for _, f := range tgb.fields { - columns = append(columns, selector.C(f)) - } - for _, c := range aggregation { - columns = append(columns, c) - } - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(tgb.fields...)...) -} - -// TenantSelect is the builder for selecting fields of Tenant entities. -type TenantSelect struct { - *TenantQuery - // intermediate query (i.e. traversal path). - sql *sql.Selector -} - -// Scan applies the selector query and scans the result into the given value. -func (ts *TenantSelect) Scan(ctx context.Context, v interface{}) error { - if err := ts.prepareQuery(ctx); err != nil { - return err - } - ts.sql = ts.TenantQuery.sqlQuery(ctx) - return ts.sqlScan(ctx, v) -} - -// ScanX is like Scan, but panics if an error occurs. -func (ts *TenantSelect) ScanX(ctx context.Context, v interface{}) { - if err := ts.Scan(ctx, v); err != nil { - panic(err) - } -} - -// Strings returns list of strings from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Strings(ctx context.Context) ([]string, error) { - if len(ts.fields) > 1 { - return nil, errors.New("ent: TenantSelect.Strings is not achievable when selecting more than 1 field") - } - var v []string - if err := ts.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// StringsX is like Strings, but panics if an error occurs. -func (ts *TenantSelect) StringsX(ctx context.Context) []string { - v, err := ts.Strings(ctx) - if err != nil { - panic(err) - } - return v -} - -// String returns a single string from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) String(ctx context.Context) (_ string, err error) { - var v []string - if v, err = ts.Strings(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantSelect.Strings returned %d results when one was expected", len(v)) - } - return -} - -// StringX is like String, but panics if an error occurs. -func (ts *TenantSelect) StringX(ctx context.Context) string { - v, err := ts.String(ctx) - if err != nil { - panic(err) - } - return v -} - -// Ints returns list of ints from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Ints(ctx context.Context) ([]int, error) { - if len(ts.fields) > 1 { - return nil, errors.New("ent: TenantSelect.Ints is not achievable when selecting more than 1 field") - } - var v []int - if err := ts.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// IntsX is like Ints, but panics if an error occurs. -func (ts *TenantSelect) IntsX(ctx context.Context) []int { - v, err := ts.Ints(ctx) - if err != nil { - panic(err) - } - return v -} - -// Int returns a single int from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Int(ctx context.Context) (_ int, err error) { - var v []int - if v, err = ts.Ints(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantSelect.Ints returned %d results when one was expected", len(v)) - } - return -} - -// IntX is like Int, but panics if an error occurs. -func (ts *TenantSelect) IntX(ctx context.Context) int { - v, err := ts.Int(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64s returns list of float64s from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Float64s(ctx context.Context) ([]float64, error) { - if len(ts.fields) > 1 { - return nil, errors.New("ent: TenantSelect.Float64s is not achievable when selecting more than 1 field") - } - var v []float64 - if err := ts.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// Float64sX is like Float64s, but panics if an error occurs. -func (ts *TenantSelect) Float64sX(ctx context.Context) []float64 { - v, err := ts.Float64s(ctx) - if err != nil { - panic(err) - } - return v -} - -// Float64 returns a single float64 from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Float64(ctx context.Context) (_ float64, err error) { - var v []float64 - if v, err = ts.Float64s(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantSelect.Float64s returned %d results when one was expected", len(v)) - } - return -} - -// Float64X is like Float64, but panics if an error occurs. -func (ts *TenantSelect) Float64X(ctx context.Context) float64 { - v, err := ts.Float64(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bools returns list of bools from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Bools(ctx context.Context) ([]bool, error) { - if len(ts.fields) > 1 { - return nil, errors.New("ent: TenantSelect.Bools is not achievable when selecting more than 1 field") - } - var v []bool - if err := ts.Scan(ctx, &v); err != nil { - return nil, err - } - return v, nil -} - -// BoolsX is like Bools, but panics if an error occurs. -func (ts *TenantSelect) BoolsX(ctx context.Context) []bool { - v, err := ts.Bools(ctx) - if err != nil { - panic(err) - } - return v -} - -// Bool returns a single bool from a selector. It is only allowed when selecting one field. -func (ts *TenantSelect) Bool(ctx context.Context) (_ bool, err error) { - var v []bool - if v, err = ts.Bools(ctx); err != nil { - return - } - switch len(v) { - case 1: - return v[0], nil - case 0: - err = &NotFoundError{tenant.Label} - default: - err = fmt.Errorf("ent: TenantSelect.Bools returned %d results when one was expected", len(v)) - } - return -} - -// BoolX is like Bool, but panics if an error occurs. -func (ts *TenantSelect) BoolX(ctx context.Context) bool { - v, err := ts.Bool(ctx) - if err != nil { - panic(err) - } - return v -} - -func (ts *TenantSelect) sqlScan(ctx context.Context, v interface{}) error { - rows := &sql.Rows{} - query, args := ts.sql.Query() - if err := ts.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} diff --git a/ent/tenant_update.go b/ent/tenant_update.go deleted file mode 100644 index 6c411d6..0000000 --- a/ent/tenant_update.go +++ /dev/null @@ -1,671 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - "github.com/kfsoftware/hlf-cc-dev/ent/chaincode" - "github.com/kfsoftware/hlf-cc-dev/ent/predicate" - "github.com/kfsoftware/hlf-cc-dev/ent/tenant" -) - -// TenantUpdate is the builder for updating Tenant entities. -type TenantUpdate struct { - config - hooks []Hook - mutation *TenantMutation -} - -// Where appends a list predicates to the TenantUpdate builder. -func (tu *TenantUpdate) Where(ps ...predicate.Tenant) *TenantUpdate { - tu.mutation.Where(ps...) - return tu -} - -// SetName sets the "name" field. -func (tu *TenantUpdate) SetName(s string) *TenantUpdate { - tu.mutation.SetName(s) - return tu -} - -// SetMspId sets the "mspId" field. -func (tu *TenantUpdate) SetMspId(s string) *TenantUpdate { - tu.mutation.SetMspId(s) - return tu -} - -// SetSignCertCAPrivateKey sets the "signCertCAPrivateKey" field. -func (tu *TenantUpdate) SetSignCertCAPrivateKey(b []byte) *TenantUpdate { - tu.mutation.SetSignCertCAPrivateKey(b) - return tu -} - -// ClearSignCertCAPrivateKey clears the value of the "signCertCAPrivateKey" field. -func (tu *TenantUpdate) ClearSignCertCAPrivateKey() *TenantUpdate { - tu.mutation.ClearSignCertCAPrivateKey() - return tu -} - -// SetSignCertCACert sets the "signCertCACert" field. -func (tu *TenantUpdate) SetSignCertCACert(b []byte) *TenantUpdate { - tu.mutation.SetSignCertCACert(b) - return tu -} - -// ClearSignCertCACert clears the value of the "signCertCACert" field. -func (tu *TenantUpdate) ClearSignCertCACert() *TenantUpdate { - tu.mutation.ClearSignCertCACert() - return tu -} - -// SetTlsCertCAPrivateKey sets the "tlsCertCAPrivateKey" field. -func (tu *TenantUpdate) SetTlsCertCAPrivateKey(b []byte) *TenantUpdate { - tu.mutation.SetTlsCertCAPrivateKey(b) - return tu -} - -// ClearTlsCertCAPrivateKey clears the value of the "tlsCertCAPrivateKey" field. -func (tu *TenantUpdate) ClearTlsCertCAPrivateKey() *TenantUpdate { - tu.mutation.ClearTlsCertCAPrivateKey() - return tu -} - -// SetTlsCertCACert sets the "tlsCertCACert" field. -func (tu *TenantUpdate) SetTlsCertCACert(b []byte) *TenantUpdate { - tu.mutation.SetTlsCertCACert(b) - return tu -} - -// ClearTlsCertCACert clears the value of the "tlsCertCACert" field. -func (tu *TenantUpdate) ClearTlsCertCACert() *TenantUpdate { - tu.mutation.ClearTlsCertCACert() - return tu -} - -// AddChaincodeIDs adds the "chaincodes" edge to the Chaincode entity by IDs. -func (tu *TenantUpdate) AddChaincodeIDs(ids ...int) *TenantUpdate { - tu.mutation.AddChaincodeIDs(ids...) - return tu -} - -// AddChaincodes adds the "chaincodes" edges to the Chaincode entity. -func (tu *TenantUpdate) AddChaincodes(c ...*Chaincode) *TenantUpdate { - ids := make([]int, len(c)) - for i := range c { - ids[i] = c[i].ID - } - return tu.AddChaincodeIDs(ids...) -} - -// Mutation returns the TenantMutation object of the builder. -func (tu *TenantUpdate) Mutation() *TenantMutation { - return tu.mutation -} - -// ClearChaincodes clears all "chaincodes" edges to the Chaincode entity. -func (tu *TenantUpdate) ClearChaincodes() *TenantUpdate { - tu.mutation.ClearChaincodes() - return tu -} - -// RemoveChaincodeIDs removes the "chaincodes" edge to Chaincode entities by IDs. -func (tu *TenantUpdate) RemoveChaincodeIDs(ids ...int) *TenantUpdate { - tu.mutation.RemoveChaincodeIDs(ids...) - return tu -} - -// RemoveChaincodes removes "chaincodes" edges to Chaincode entities. -func (tu *TenantUpdate) RemoveChaincodes(c ...*Chaincode) *TenantUpdate { - ids := make([]int, len(c)) - for i := range c { - ids[i] = c[i].ID - } - return tu.RemoveChaincodeIDs(ids...) -} - -// Save executes the query and returns the number of nodes affected by the update operation. -func (tu *TenantUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(tu.hooks) == 0 { - affected, err = tu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - tu.mutation = mutation - affected, err = tu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(tu.hooks) - 1; i >= 0; i-- { - if tu.hooks[i] == nil { - return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = tu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, tu.mutation); err != nil { - return 0, err - } - } - return affected, err -} - -// SaveX is like Save, but panics if an error occurs. -func (tu *TenantUpdate) SaveX(ctx context.Context) int { - affected, err := tu.Save(ctx) - if err != nil { - panic(err) - } - return affected -} - -// Exec executes the query. -func (tu *TenantUpdate) Exec(ctx context.Context) error { - _, err := tu.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (tu *TenantUpdate) ExecX(ctx context.Context) { - if err := tu.Exec(ctx); err != nil { - panic(err) - } -} - -func (tu *TenantUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: tenant.Table, - Columns: tenant.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - if ps := tu.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := tu.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldName, - }) - } - if value, ok := tu.mutation.MspId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldMspId, - }) - } - if value, ok := tu.mutation.SignCertCAPrivateKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCAPrivateKey, - }) - } - if tu.mutation.SignCertCAPrivateKeyCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldSignCertCAPrivateKey, - }) - } - if value, ok := tu.mutation.SignCertCACert(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCACert, - }) - } - if tu.mutation.SignCertCACertCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldSignCertCACert, - }) - } - if value, ok := tu.mutation.TlsCertCAPrivateKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCAPrivateKey, - }) - } - if tu.mutation.TlsCertCAPrivateKeyCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldTlsCertCAPrivateKey, - }) - } - if value, ok := tu.mutation.TlsCertCACert(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCACert, - }) - } - if tu.mutation.TlsCertCACertCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldTlsCertCACert, - }) - } - if tu.mutation.ChaincodesCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := tu.mutation.RemovedChaincodesIDs(); len(nodes) > 0 && !tu.mutation.ChaincodesCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := tu.mutation.ChaincodesIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - if n, err = sqlgraph.UpdateNodes(ctx, tu.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{tenant.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return 0, err - } - return n, nil -} - -// TenantUpdateOne is the builder for updating a single Tenant entity. -type TenantUpdateOne struct { - config - fields []string - hooks []Hook - mutation *TenantMutation -} - -// SetName sets the "name" field. -func (tuo *TenantUpdateOne) SetName(s string) *TenantUpdateOne { - tuo.mutation.SetName(s) - return tuo -} - -// SetMspId sets the "mspId" field. -func (tuo *TenantUpdateOne) SetMspId(s string) *TenantUpdateOne { - tuo.mutation.SetMspId(s) - return tuo -} - -// SetSignCertCAPrivateKey sets the "signCertCAPrivateKey" field. -func (tuo *TenantUpdateOne) SetSignCertCAPrivateKey(b []byte) *TenantUpdateOne { - tuo.mutation.SetSignCertCAPrivateKey(b) - return tuo -} - -// ClearSignCertCAPrivateKey clears the value of the "signCertCAPrivateKey" field. -func (tuo *TenantUpdateOne) ClearSignCertCAPrivateKey() *TenantUpdateOne { - tuo.mutation.ClearSignCertCAPrivateKey() - return tuo -} - -// SetSignCertCACert sets the "signCertCACert" field. -func (tuo *TenantUpdateOne) SetSignCertCACert(b []byte) *TenantUpdateOne { - tuo.mutation.SetSignCertCACert(b) - return tuo -} - -// ClearSignCertCACert clears the value of the "signCertCACert" field. -func (tuo *TenantUpdateOne) ClearSignCertCACert() *TenantUpdateOne { - tuo.mutation.ClearSignCertCACert() - return tuo -} - -// SetTlsCertCAPrivateKey sets the "tlsCertCAPrivateKey" field. -func (tuo *TenantUpdateOne) SetTlsCertCAPrivateKey(b []byte) *TenantUpdateOne { - tuo.mutation.SetTlsCertCAPrivateKey(b) - return tuo -} - -// ClearTlsCertCAPrivateKey clears the value of the "tlsCertCAPrivateKey" field. -func (tuo *TenantUpdateOne) ClearTlsCertCAPrivateKey() *TenantUpdateOne { - tuo.mutation.ClearTlsCertCAPrivateKey() - return tuo -} - -// SetTlsCertCACert sets the "tlsCertCACert" field. -func (tuo *TenantUpdateOne) SetTlsCertCACert(b []byte) *TenantUpdateOne { - tuo.mutation.SetTlsCertCACert(b) - return tuo -} - -// ClearTlsCertCACert clears the value of the "tlsCertCACert" field. -func (tuo *TenantUpdateOne) ClearTlsCertCACert() *TenantUpdateOne { - tuo.mutation.ClearTlsCertCACert() - return tuo -} - -// AddChaincodeIDs adds the "chaincodes" edge to the Chaincode entity by IDs. -func (tuo *TenantUpdateOne) AddChaincodeIDs(ids ...int) *TenantUpdateOne { - tuo.mutation.AddChaincodeIDs(ids...) - return tuo -} - -// AddChaincodes adds the "chaincodes" edges to the Chaincode entity. -func (tuo *TenantUpdateOne) AddChaincodes(c ...*Chaincode) *TenantUpdateOne { - ids := make([]int, len(c)) - for i := range c { - ids[i] = c[i].ID - } - return tuo.AddChaincodeIDs(ids...) -} - -// Mutation returns the TenantMutation object of the builder. -func (tuo *TenantUpdateOne) Mutation() *TenantMutation { - return tuo.mutation -} - -// ClearChaincodes clears all "chaincodes" edges to the Chaincode entity. -func (tuo *TenantUpdateOne) ClearChaincodes() *TenantUpdateOne { - tuo.mutation.ClearChaincodes() - return tuo -} - -// RemoveChaincodeIDs removes the "chaincodes" edge to Chaincode entities by IDs. -func (tuo *TenantUpdateOne) RemoveChaincodeIDs(ids ...int) *TenantUpdateOne { - tuo.mutation.RemoveChaincodeIDs(ids...) - return tuo -} - -// RemoveChaincodes removes "chaincodes" edges to Chaincode entities. -func (tuo *TenantUpdateOne) RemoveChaincodes(c ...*Chaincode) *TenantUpdateOne { - ids := make([]int, len(c)) - for i := range c { - ids[i] = c[i].ID - } - return tuo.RemoveChaincodeIDs(ids...) -} - -// Select allows selecting one or more fields (columns) of the returned entity. -// The default is selecting all fields defined in the entity schema. -func (tuo *TenantUpdateOne) Select(field string, fields ...string) *TenantUpdateOne { - tuo.fields = append([]string{field}, fields...) - return tuo -} - -// Save executes the query and returns the updated Tenant entity. -func (tuo *TenantUpdateOne) Save(ctx context.Context) (*Tenant, error) { - var ( - err error - node *Tenant - ) - if len(tuo.hooks) == 0 { - node, err = tuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*TenantMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - tuo.mutation = mutation - node, err = tuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(tuo.hooks) - 1; i >= 0; i-- { - if tuo.hooks[i] == nil { - return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") - } - mut = tuo.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, tuo.mutation); err != nil { - return nil, err - } - } - return node, err -} - -// SaveX is like Save, but panics if an error occurs. -func (tuo *TenantUpdateOne) SaveX(ctx context.Context) *Tenant { - node, err := tuo.Save(ctx) - if err != nil { - panic(err) - } - return node -} - -// Exec executes the query on the entity. -func (tuo *TenantUpdateOne) Exec(ctx context.Context) error { - _, err := tuo.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (tuo *TenantUpdateOne) ExecX(ctx context.Context) { - if err := tuo.Exec(ctx); err != nil { - panic(err) - } -} - -func (tuo *TenantUpdateOne) sqlSave(ctx context.Context) (_node *Tenant, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: tenant.Table, - Columns: tenant.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: tenant.FieldID, - }, - }, - } - id, ok := tuo.mutation.ID() - if !ok { - return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Tenant.ID for update")} - } - _spec.Node.ID.Value = id - if fields := tuo.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, tenant.FieldID) - for _, f := range fields { - if !tenant.ValidColumn(f) { - return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - if f != tenant.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, f) - } - } - } - if ps := tuo.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := tuo.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldName, - }) - } - if value, ok := tuo.mutation.MspId(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: tenant.FieldMspId, - }) - } - if value, ok := tuo.mutation.SignCertCAPrivateKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCAPrivateKey, - }) - } - if tuo.mutation.SignCertCAPrivateKeyCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldSignCertCAPrivateKey, - }) - } - if value, ok := tuo.mutation.SignCertCACert(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldSignCertCACert, - }) - } - if tuo.mutation.SignCertCACertCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldSignCertCACert, - }) - } - if value, ok := tuo.mutation.TlsCertCAPrivateKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCAPrivateKey, - }) - } - if tuo.mutation.TlsCertCAPrivateKeyCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldTlsCertCAPrivateKey, - }) - } - if value, ok := tuo.mutation.TlsCertCACert(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: tenant.FieldTlsCertCACert, - }) - } - if tuo.mutation.TlsCertCACertCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: tenant.FieldTlsCertCACert, - }) - } - if tuo.mutation.ChaincodesCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := tuo.mutation.RemovedChaincodesIDs(); len(nodes) > 0 && !tuo.mutation.ChaincodesCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := tuo.mutation.ChaincodesIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: false, - Table: tenant.ChaincodesTable, - Columns: []string{tenant.ChaincodesColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: chaincode.FieldID, - }, - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - _node = &Tenant{config: tuo.config} - _spec.Assign = _node.assignValues - _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, tuo.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{tenant.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{err.Error(), err} - } - return nil, err - } - return _node, nil -} diff --git a/ent/tx.go b/ent/tx.go deleted file mode 100644 index 8b65f89..0000000 --- a/ent/tx.go +++ /dev/null @@ -1,213 +0,0 @@ -// Code generated by entc, DO NOT EDIT. - -package ent - -import ( - "context" - "sync" - - "entgo.io/ent/dialect" -) - -// Tx is a transactional client that is created by calling Client.Tx(). -type Tx struct { - config - // Chaincode is the client for interacting with the Chaincode builders. - Chaincode *ChaincodeClient - // Tenant is the client for interacting with the Tenant builders. - Tenant *TenantClient - - // lazily loaded. - client *Client - clientOnce sync.Once - - // completion callbacks. - mu sync.Mutex - onCommit []CommitHook - onRollback []RollbackHook - - // ctx lives for the life of the transaction. It is - // the same context used by the underlying connection. - ctx context.Context -} - -type ( - // Committer is the interface that wraps the Committer method. - Committer interface { - Commit(context.Context, *Tx) error - } - - // The CommitFunc type is an adapter to allow the use of ordinary - // function as a Committer. If f is a function with the appropriate - // signature, CommitFunc(f) is a Committer that calls f. - CommitFunc func(context.Context, *Tx) error - - // CommitHook defines the "commit middleware". A function that gets a Committer - // and returns a Committer. For example: - // - // hook := func(next ent.Committer) ent.Committer { - // return ent.CommitFunc(func(context.Context, tx *ent.Tx) error { - // // Do some stuff before. - // if err := next.Commit(ctx, tx); err != nil { - // return err - // } - // // Do some stuff after. - // return nil - // }) - // } - // - CommitHook func(Committer) Committer -) - -// Commit calls f(ctx, m). -func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error { - return f(ctx, tx) -} - -// Commit commits the transaction. -func (tx *Tx) Commit() error { - txDriver := tx.config.driver.(*txDriver) - var fn Committer = CommitFunc(func(context.Context, *Tx) error { - return txDriver.tx.Commit() - }) - tx.mu.Lock() - hooks := append([]CommitHook(nil), tx.onCommit...) - tx.mu.Unlock() - for i := len(hooks) - 1; i >= 0; i-- { - fn = hooks[i](fn) - } - return fn.Commit(tx.ctx, tx) -} - -// OnCommit adds a hook to call on commit. -func (tx *Tx) OnCommit(f CommitHook) { - tx.mu.Lock() - defer tx.mu.Unlock() - tx.onCommit = append(tx.onCommit, f) -} - -type ( - // Rollbacker is the interface that wraps the Rollbacker method. - Rollbacker interface { - Rollback(context.Context, *Tx) error - } - - // The RollbackFunc type is an adapter to allow the use of ordinary - // function as a Rollbacker. If f is a function with the appropriate - // signature, RollbackFunc(f) is a Rollbacker that calls f. - RollbackFunc func(context.Context, *Tx) error - - // RollbackHook defines the "rollback middleware". A function that gets a Rollbacker - // and returns a Rollbacker. For example: - // - // hook := func(next ent.Rollbacker) ent.Rollbacker { - // return ent.RollbackFunc(func(context.Context, tx *ent.Tx) error { - // // Do some stuff before. - // if err := next.Rollback(ctx, tx); err != nil { - // return err - // } - // // Do some stuff after. - // return nil - // }) - // } - // - RollbackHook func(Rollbacker) Rollbacker -) - -// Rollback calls f(ctx, m). -func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error { - return f(ctx, tx) -} - -// Rollback rollbacks the transaction. -func (tx *Tx) Rollback() error { - txDriver := tx.config.driver.(*txDriver) - var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { - return txDriver.tx.Rollback() - }) - tx.mu.Lock() - hooks := append([]RollbackHook(nil), tx.onRollback...) - tx.mu.Unlock() - for i := len(hooks) - 1; i >= 0; i-- { - fn = hooks[i](fn) - } - return fn.Rollback(tx.ctx, tx) -} - -// OnRollback adds a hook to call on rollback. -func (tx *Tx) OnRollback(f RollbackHook) { - tx.mu.Lock() - defer tx.mu.Unlock() - tx.onRollback = append(tx.onRollback, f) -} - -// Client returns a Client that binds to current transaction. -func (tx *Tx) Client() *Client { - tx.clientOnce.Do(func() { - tx.client = &Client{config: tx.config} - tx.client.init() - }) - return tx.client -} - -func (tx *Tx) init() { - tx.Chaincode = NewChaincodeClient(tx.config) - tx.Tenant = NewTenantClient(tx.config) -} - -// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. -// The idea is to support transactions without adding any extra code to the builders. -// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. -// Commit and Rollback are nop for the internal builders and the user must call one -// of them in order to commit or rollback the transaction. -// -// If a closed transaction is embedded in one of the generated entities, and the entity -// applies a query, for example: Chaincode.QueryXXX(), the query will be executed -// through the driver which created this transaction. -// -// Note that txDriver is not goroutine safe. -type txDriver struct { - // the driver we started the transaction from. - drv dialect.Driver - // tx is the underlying transaction. - tx dialect.Tx -} - -// newTx creates a new transactional driver. -func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { - tx, err := drv.Tx(ctx) - if err != nil { - return nil, err - } - return &txDriver{tx: tx, drv: drv}, nil -} - -// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls -// from the internal builders. Should be called only by the internal builders. -func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } - -// Dialect returns the dialect of the driver we started the transaction from. -func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } - -// Close is a nop close. -func (*txDriver) Close() error { return nil } - -// Commit is a nop commit for the internal builders. -// User must call `Tx.Commit` in order to commit the transaction. -func (*txDriver) Commit() error { return nil } - -// Rollback is a nop rollback for the internal builders. -// User must call `Tx.Rollback` in order to rollback the transaction. -func (*txDriver) Rollback() error { return nil } - -// Exec calls tx.Exec. -func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { - return tx.tx.Exec(ctx, query, args, v) -} - -// Query calls tx.Query. -func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { - return tx.tx.Query(ctx, query, args, v) -} - -var _ dialect.Driver = (*txDriver)(nil) diff --git a/gql/generated.go b/gql/generated.go index 67e87ae..328f0d1 100644 --- a/gql/generated.go +++ b/gql/generated.go @@ -417,6 +417,7 @@ input DeployChaincodeInput { tenantId: Int! pdc: String! chaincodeAddress: String! + signaturePolicy: String! } `, BuiltIn: false}, {Name: "schema/query.graphql", Input: `type Query { @@ -2643,6 +2644,14 @@ func (ec *executionContext) unmarshalInputDeployChaincodeInput(ctx context.Conte if err != nil { return it, err } + case "signaturePolicy": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("signaturePolicy")) + it.SignaturePolicy, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } } } diff --git a/gql/models/models.go b/gql/models/models.go index 715a504..afdcafb 100644 --- a/gql/models/models.go +++ b/gql/models/models.go @@ -18,6 +18,7 @@ type DeployChaincodeInput struct { TenantID int `json:"tenantId"` Pdc string `json:"pdc"` ChaincodeAddress string `json:"chaincodeAddress"` + SignaturePolicy string `json:"signaturePolicy"` } type DeployChaincodeResponse struct { diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index b5b72db..3d487ed 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -10,7 +10,6 @@ import ( "encoding/pem" "fmt" "github.com/gosimple/slug" - "github.com/hyperledger/fabric-config/configtx/membership" pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" @@ -19,7 +18,6 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" - "github.com/kfsoftware/hlf-cc-dev/ent" "github.com/kfsoftware/hlf-cc-dev/gql/models" "github.com/kfsoftware/hlf-cc-dev/log" "github.com/lithammer/shortuuid/v3" @@ -28,6 +26,7 @@ import ( "net" "os" "path/filepath" + "strings" "time" ) @@ -170,7 +169,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl if err != nil { return nil, err } - userName := fmt.Sprintf("%s-%s", "chaincode", shortuuid.New()[:5]) + userName := fmt.Sprintf("%s-%s", "chaincode", chaincodeName) secret := shortuuid.New() _, err = m.MSPClient.Register(&clientmsp.RegistrationRequest{ Name: userName, @@ -179,7 +178,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl CAName: m.CAConfig.CAName, Secret: secret, }) - if err != nil { + if !strings.Contains(err.Error(), "is already registered"){ return nil, err } err = m.MSPClient.Enroll( @@ -226,6 +225,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl } version := "1" sequence := 1 + pkg, err := getChaincodePackage(chaincodeName, codeTarBytes) if err != nil { return nil, err @@ -242,7 +242,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl return nil, err } packageID := lifecycle.ComputePackageID(chaincodeName, pkg) - signaturePolicy := fmt.Sprintf("OR('%s.member')", m.Organization) + signaturePolicy := input.SignaturePolicy sp, err := policydsl.FromString(signaturePolicy) if err != nil { return nil, err @@ -263,27 +263,33 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl } } log.Debugf("collections=%v", collections) - txID, err := resClient.LifecycleApproveCC( - m.Channel, - resmgmt.LifecycleApproveCCRequest{ - Name: chaincodeName, - Version: version, - PackageID: packageID, - Sequence: int64(sequence), - EndorsementPlugin: "escc", - ValidationPlugin: "vscc", - SignaturePolicy: sp, - CollectionConfig: collections, - InitRequired: false, - }, - resmgmt.WithTimeout(fab.ResMgmt, 2*time.Minute), - resmgmt.WithTimeout(fab.PeerResponse, 2*time.Minute), - ) - if err != nil { - return nil, err + for mspID, sdkContext := range m.SDKContextMap { + resClient, err := resmgmt.New(sdkContext) + if err != nil { + return nil, err + } + txID, err := resClient.LifecycleApproveCC( + m.Channel, + resmgmt.LifecycleApproveCCRequest{ + Name: chaincodeName, + Version: version, + PackageID: packageID, + Sequence: int64(sequence), + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: sp, + CollectionConfig: collections, + InitRequired: false, + }, + resmgmt.WithTimeout(fab.ResMgmt, 2*time.Minute), + resmgmt.WithTimeout(fab.PeerResponse, 2*time.Minute), + ) + if err != nil { + return nil, err + } + log.Infof("%s Chaincode %s approved= %s", mspID, chaincodeName, txID) } - log.Infof("Chaincode %s approved= %s", chaincodeName, txID) - commitReadiness , err := resClient.LifecycleCheckCCCommitReadiness(m.Channel, + commitReadiness, err := resClient.LifecycleCheckCCCommitReadiness(m.Channel, resmgmt.LifecycleCheckCCCommitReadinessRequest{ Name: chaincodeName, Version: version, @@ -298,7 +304,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl return nil, err } log.Infof("Chaincode %s readiness= %v", chaincodeName, commitReadiness) - txID, err = resClient.LifecycleCommitCC( + txID, err := resClient.LifecycleCommitCC( m.Channel, resmgmt.LifecycleCommitCCRequest{ Name: chaincodeName, @@ -350,44 +356,6 @@ func ParseX509Certificate(contents []byte) (*x509.Certificate, error) { return crt, nil } -func mapNodeOUs(tenant *ent.Tenant) (membership.NodeOUs, error) { - clientCert, err := ParseX509Certificate(tenant.SignCertCACert) - if err != nil { - return membership.NodeOUs{}, nil - } - peerCert, err := ParseX509Certificate(tenant.SignCertCACert) - if err != nil { - return membership.NodeOUs{}, nil - } - adminCert, err := ParseX509Certificate(tenant.SignCertCACert) - if err != nil { - return membership.NodeOUs{}, nil - } - ordererCert, err := ParseX509Certificate(tenant.SignCertCACert) - if err != nil { - return membership.NodeOUs{}, nil - } - nodeOUs := membership.NodeOUs{ - Enable: true, - ClientOUIdentifier: membership.OUIdentifier{ - Certificate: clientCert, - OrganizationalUnitIdentifier: "client", - }, - PeerOUIdentifier: membership.OUIdentifier{ - Certificate: peerCert, - OrganizationalUnitIdentifier: "peer", - }, - AdminOUIdentifier: membership.OUIdentifier{ - Certificate: adminCert, - OrganizationalUnitIdentifier: "admin", - }, - OrdererOUIdentifier: membership.OUIdentifier{ - Certificate: ordererCert, - OrganizationalUnitIdentifier: "orderer", - }, - } - return nodeOUs, nil -} func (m mutationResolver) InvokeChaincode(ctx context.Context, input models.InvokeChaincodeInput) (*models.InvokeChaincodeResponse, error) { chContext := m.SDK.ChannelContext( diff --git a/gql/resolvers/resolvers.go b/gql/resolvers/resolvers.go index a6a70a0..1606a92 100644 --- a/gql/resolvers/resolvers.go +++ b/gql/resolvers/resolvers.go @@ -11,13 +11,14 @@ import ( ) type Resolver struct { - SDK *fabsdk.FabricSDK - SDKContext context.ClientProvider - Channel string - MSPClient *clientmsp.Client - CAConfig *msp.CAConfig - Organization string - User string + SDK *fabsdk.FabricSDK + SDKContext context.ClientProvider + SDKContextMap map[string]context.ClientProvider + Channel string + MSPClient *clientmsp.Client + CAConfig *msp.CAConfig + Organization string + User string } // Mutation returns gql.MutationResolver implementation. diff --git a/schema/mutation.graphql b/schema/mutation.graphql index f6798c7..888eb9b 100644 --- a/schema/mutation.graphql +++ b/schema/mutation.graphql @@ -64,4 +64,5 @@ input DeployChaincodeInput { tenantId: Int! pdc: String! chaincodeAddress: String! + signaturePolicy: String! } diff --git a/server/server.go b/server/server.go index 860b9f1..7ab5247 100644 --- a/server/server.go +++ b/server/server.go @@ -33,11 +33,13 @@ type BlockchainServerOpts struct { MetricsAddress string SDK *fabsdk.FabricSDK SDKContext context.ClientProvider - Channel string - MSPClient *clientmsp.Client - CAConfig *msp.CAConfig - Organization string - User string + SDKContextMap map[string]context.ClientProvider + + Channel string + MSPClient *clientmsp.Client + CAConfig *msp.CAConfig + Organization string + User string } type BlockchainAPIServer struct { @@ -71,11 +73,12 @@ func (a *BlockchainAPIServer) setupHttpServer() http.Handler { serverMux := http.NewServeMux() config := gql.Config{ Resolvers: &resolvers.Resolver{ - SDK: a.SDK, - SDKContext: a.SDKContext, - Channel: a.Channel, - MSPClient: a.MSPClient, - CAConfig: a.CAConfig, + SDK: a.SDK, + SDKContext: a.SDKContext, + Channel: a.Channel, + MSPClient: a.MSPClient, + CAConfig: a.CAConfig, + SDKContextMap: a.SDKContextMap, Organization: a.Organization, User: a.User, }, From e9cc17b53e8e13950d021471dc54820ef2a37be2 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Mon, 17 Jan 2022 23:58:31 +0100 Subject: [PATCH 07/20] approve in parallel, allow meta-inf indexes --- cmd/serve/serve.go | 8 ++- cmd/start/start.go | 55 +++++++++++++---- go.mod | 5 +- go.sum | 11 ---- gql/generated.go | 82 ++++++++++++++++++++++--- gql/models/models.go | 15 +++-- gql/resolvers/mutation.go | 125 ++++++++++++++++++-------------------- schema/mutation.graphql | 6 +- 8 files changed, 202 insertions(+), 105 deletions(-) diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index ccd8cbe..f30e1a9 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -148,9 +148,13 @@ func (c *serveCmd) run(conf *serveConfig) error { } mapSdkContext := map[string]context.ClientProvider{} for _, organization := range appConf.Organizations { + sdk, err := fabsdk.New(configBackend) + if err != nil { + return err + } mapSdkContext[organization.Name] = sdk.Context( - fabsdk.WithUser(conf.Fabric.Org), - fabsdk.WithOrg(organization.Name), + fabsdk.WithUser(conf.Fabric.User), + fabsdk.WithOrg(organization.MSP.Name), ) } opts := server.BlockchainServerOpts{ diff --git a/cmd/start/start.go b/cmd/start/start.go index 03382c4..c3c6555 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -4,9 +4,9 @@ import ( "context" "fmt" "github.com/hashicorp/yamux" + "github.com/kfsoftware/getout/pkg/tunnel" "github.com/kfsoftware/hlf-cc-dev/gql/models" "github.com/kfsoftware/hlf-cc-dev/log" - "github.com/kfsoftware/getout/pkg/tunnel" "github.com/lithammer/shortuuid/v3" "github.com/pkg/errors" "github.com/shurcooL/graphql" @@ -16,6 +16,7 @@ import ( "k8s.io/client-go/util/homedir" "net" "os" + "path" "path/filepath" "strings" ) @@ -48,7 +49,6 @@ const ( ) type startCmd struct { - tenant int chaincode string localChaincodeAddress string tunnelAddress string @@ -58,15 +58,16 @@ type startCmd struct { metaInf string chaincodeAddress string chaincodeAddressSubdomain string + signaturePolicy string } func (c startCmd) validate() error { - if c.tenant == 0 { - return errors.New("--tenant is required") - } if c.chaincodeAddress == "" && c.chaincodeAddressSubdomain == "" { return errors.New("either --chaincode or --chaincodeAddressSubdomain are required") } + if c.signaturePolicy == "" { + return errors.New("--signaturePolicy is required") + } if c.chaincode == "" { return errors.New("--chaincode is required") } @@ -102,9 +103,9 @@ func (c startCmd) run() error { p.CertsDir(c.chaincode), ) if err != nil { - return err + log.Errorf("failed to ensure directories: %v", err) + return errors.Wrapf(err, "failed to ensure dirs") } - gqlClient := graphql.NewClient(c.apiUrl, nil) ctx := context.Background() chaincodeAddress := c.chaincodeAddress @@ -114,17 +115,49 @@ func (c startCmd) run() error { } pdcContents := "" if c.pdcFile != "" { - pdcContentsBytes,err := ioutil.ReadFile(c.pdcFile) + pdcContentsBytes, err := ioutil.ReadFile(c.pdcFile) if err != nil { - return err + return errors.Wrapf(err, "failed to read pdc file %q", c.pdcFile) } pdcContents = string(pdcContentsBytes) } + var indices []*models.CouchDBIndex + if c.metaInf != "" { + src := c.metaInf + // walk through 3 file in the folder + err = filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + // must provide real name + // (see https://golang.org/src/archive/tar/common.go?#L626) + relname, err := filepath.Rel(src, file) + if err != nil { + return err + } + if relname == "." { + return nil + } + if strings.Contains(relname, "statedb/couchdb/indexes") && !fi.IsDir() { + contentBytes, err := ioutil.ReadFile(file) + if err != nil { + return err + } + index := &models.CouchDBIndex{ + ID: path.Base(relname), + Contents: string(contentBytes), + } + indices = append(indices, index) + } + return nil + }) + if err != nil { + return err + } + } input := models.DeployChaincodeInput{ Name: c.chaincode, - TenantID: c.tenant, ChaincodeAddress: chaincodeAddress, Pdc: pdcContents, + SignaturePolicy: c.signaturePolicy, + Indexes: indices, } var m struct { DeployChaincode struct { @@ -236,7 +269,6 @@ func NewStartCmd() *cobra.Command { f := cmd.Flags() f.StringVar(&c.chaincodeAddress, "chaincodeAddress", "", "chaincode address to be accessed by the peer(needs to be publicly accessible)") f.StringVar(&c.chaincodeAddressSubdomain, "chaincodeAddressSubdomain", "", "subdomain to be used for chaincode address, in this case, the address is generated automatically .") - f.IntVar(&c.tenant, "tenant", 0, "tenant id") f.StringVar(&c.chaincode, "chaincode", "", "chaincode name within the channel") f.StringVar(&c.localChaincodeAddress, "localChaincode", "", "address of the local chaincode server, example: localhost:9999") f.StringVar(&c.apiUrl, "apiUrl", "", "apiUrl to interact with the peers") @@ -244,5 +276,6 @@ func NewStartCmd() *cobra.Command { f.StringVar(&c.tunnelAddress, "tunnelAddress", "", "address of the local chaincode server, example: localhost:9999") f.StringVar(&c.accessToken, "accessToken", "", "access token") f.StringVar(&c.metaInf, "metaInf", "", "metadata") + f.StringVar(&c.signaturePolicy, "signaturePolicy", "", "Signature policy") return cmd } diff --git a/go.mod b/go.mod index aeb8234..b859fd8 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,9 @@ module github.com/kfsoftware/hlf-cc-dev go 1.16 require ( - entgo.io/ent v0.9.1 github.com/99designs/gqlgen v0.14.0 + github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gosimple/slug v1.12.0 github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 github.com/hyperledger/fabric-config v0.1.0 @@ -13,6 +14,8 @@ require ( github.com/kfsoftware/getout v0.0.4-beta4 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 + github.com/mattn/go-sqlite3 v1.14.8 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.7.1 github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a diff --git a/go.sum b/go.sum index 9424fe8..22c07ca 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -entgo.io/ent v0.9.1 h1:IG8andyeD79GG24U8Q+1Y45hQXj6gY5evSBcva5gtBk= -entgo.io/ent v0.9.1/go.mod h1:6NUeTfUN5mp5YN+5tgoH1SlakSvYPTBOYotSOvaI4ak= github.com/99designs/gqlgen v0.14.0 h1:Wg8aNYQUjMR/4v+W3xD+7SizOy6lSvVeQ06AobNQAXI= github.com/99designs/gqlgen v0.14.0/go.mod h1:S7z4boV+Nx4VvzMUpVrY/YuHjFX4n7rDyuTqvAkuoRE= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -53,8 +51,6 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= @@ -152,7 +148,6 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/go-bindata/go-bindata v1.0.1-0.20190711162640-ee3c2418e368/go.mod h1:7xCgX1lzlrXPHkfvn3EhumqHkmSlzt8at9q7v0ax19c= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -165,7 +160,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -381,7 +375,6 @@ github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -406,7 +399,6 @@ github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNE github.com/kfsoftware/getout v0.0.4-beta4 h1:7nk6Gds4WDmNcSrgVnBuPPfKXBpOartCeymPYXe6tLM= github.com/kfsoftware/getout v0.0.4-beta4/go.mod h1:mB5QcbViWO6Pn9hH2WC2ITsXkTlAzuaIdxe21qSAVFM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= @@ -458,7 +450,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= @@ -495,7 +486,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -868,7 +858,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/gql/generated.go b/gql/generated.go index 328f0d1..e88b4c7 100644 --- a/gql/generated.go +++ b/gql/generated.go @@ -414,10 +414,14 @@ type DeployChaincodeResponse { } input DeployChaincodeInput { name: String! - tenantId: Int! pdc: String! chaincodeAddress: String! signaturePolicy: String! + indexes: [CouchDBIndex!] +} +input CouchDBIndex { + id: String! + contents: String! } `, BuiltIn: false}, {Name: "schema/query.graphql", Input: `type Query { @@ -2572,6 +2576,37 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputCouchDBIndex(ctx context.Context, obj interface{}) (models.CouchDBIndex, error) { + var it models.CouchDBIndex + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "contents": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("contents")) + it.Contents, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputCreateTenantInput(ctx context.Context, obj interface{}) (models.CreateTenantInput, error) { var it models.CreateTenantInput asMap := map[string]interface{}{} @@ -2620,14 +2655,6 @@ func (ec *executionContext) unmarshalInputDeployChaincodeInput(ctx context.Conte if err != nil { return it, err } - case "tenantId": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("tenantId")) - it.TenantID, err = ec.unmarshalNInt2int(ctx, v) - if err != nil { - return it, err - } case "pdc": var err error @@ -2652,6 +2679,14 @@ func (ec *executionContext) unmarshalInputDeployChaincodeInput(ctx context.Conte if err != nil { return it, err } + case "indexes": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("indexes")) + it.Indexes, err = ec.unmarshalOCouchDBIndex2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐCouchDBIndexᚄ(ctx, v) + if err != nil { + return it, err + } } } @@ -3384,6 +3419,11 @@ func (ec *executionContext) marshalNChaincode2ᚖgithubᚗcomᚋkfsoftwareᚋhlf return ec._Chaincode(ctx, sel, v) } +func (ec *executionContext) unmarshalNCouchDBIndex2ᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐCouchDBIndex(ctx context.Context, v interface{}) (*models.CouchDBIndex, error) { + res, err := ec.unmarshalInputCouchDBIndex(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNDeployChaincodeInput2githubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐDeployChaincodeInput(ctx context.Context, v interface{}) (models.DeployChaincodeInput, error) { res, err := ec.unmarshalInputDeployChaincodeInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -3824,6 +3864,30 @@ func (ec *executionContext) marshalOChaincode2ᚕᚖgithubᚗcomᚋkfsoftwareᚋ return ret } +func (ec *executionContext) unmarshalOCouchDBIndex2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐCouchDBIndexᚄ(ctx context.Context, v interface{}) ([]*models.CouchDBIndex, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]*models.CouchDBIndex, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNCouchDBIndex2ᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐCouchDBIndex(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + func (ec *executionContext) unmarshalOOrgInput2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐOrgInputᚄ(ctx context.Context, v interface{}) ([]*models.OrgInput, error) { if v == nil { return nil, nil diff --git a/gql/models/models.go b/gql/models/models.go index afdcafb..223bfb0 100644 --- a/gql/models/models.go +++ b/gql/models/models.go @@ -8,17 +8,22 @@ type Chaincode struct { Sequence int `json:"sequence"` } +type CouchDBIndex struct { + ID string `json:"id"` + Contents string `json:"contents"` +} + type CreateTenantInput struct { Name string `json:"name"` Orgs []*OrgInput `json:"orgs"` } type DeployChaincodeInput struct { - Name string `json:"name"` - TenantID int `json:"tenantId"` - Pdc string `json:"pdc"` - ChaincodeAddress string `json:"chaincodeAddress"` - SignaturePolicy string `json:"signaturePolicy"` + Name string `json:"name"` + Pdc string `json:"pdc"` + ChaincodeAddress string `json:"chaincodeAddress"` + SignaturePolicy string `json:"signaturePolicy"` + Indexes []*CouchDBIndex `json:"indexes"` } type DeployChaincodeResponse struct { diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 3d487ed..2888140 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -24,9 +24,8 @@ import ( "github.com/pkg/errors" "io" "net" - "os" - "path/filepath" "strings" + "sync" "time" ) @@ -79,7 +78,7 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { return buf.Bytes(), nil } -func getCodeTarGz(address string, rootCert string, clientKey string, clientCert string, metaInfPath string) ([]byte, error) { +func getCodeTarGz(address string, rootCert string, clientKey string, clientCert string, couchDBIndices []*models.CouchDBIndex) ([]byte, error) { var err error connMap := map[string]interface{}{ "address": address, @@ -115,46 +114,24 @@ func getCodeTarGz(address string, rootCert string, clientKey string, clientCert if err != nil { return nil, err } - if metaInfPath != "" { - src := metaInfPath - // walk through 3 file in the folder - err = filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { - // generate tar header - header, err := tar.FileInfoHeader(fi, file) - if err != nil { - return err - } - - // must provide real name - // (see https://golang.org/src/archive/tar/common.go?#L626) - relname, err := filepath.Rel(src, file) - if err != nil { - return err - } - if relname == "." { - return nil - } - header.Name = "META-INF/" + filepath.ToSlash(relname) - + if len(couchDBIndices) > 0 { + for _, couchDBIndex := range couchDBIndices { + header := new(tar.Header) + contentsBytes := []byte(couchDBIndex.Contents) + header.Mode = 0755 + header.Size = int64(len(contentsBytes)) + header.Name = "META-INF/statedb/couchdb/indexes/" + couchDBIndex.ID // write header if err := tw.WriteHeader(header); err != nil { - return err + return nil, err } // if not a dir, write file content - if !fi.IsDir() { - data, err := os.Open(file) - if err != nil { - return err - } - if _, err := io.Copy(tw, data); err != nil { - return err - } + r := bytes.NewReader(contentsBytes) + if _, err := io.Copy(tw, r); err != nil { + return nil, err } - return nil - }) - if err != nil { - return nil, err } + } tw.Close() @@ -162,6 +139,14 @@ func getCodeTarGz(address string, rootCert string, clientKey string, clientCert return buf.Bytes(), nil } +type mspFilter struct { + mspID string +} + +// Accept returns true if this peer is to be included in the target list +func (f *mspFilter) Accept(peer fab.Peer) bool { + return peer.MSPID() == f.mspID +} func (m mutationResolver) DeployChaincode(ctx context.Context, input models.DeployChaincodeInput) (*models.DeployChaincodeResponse, error) { chaincodeName := slug.Make(input.Name) address := input.ChaincodeAddress @@ -169,7 +154,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl if err != nil { return nil, err } - userName := fmt.Sprintf("%s-%s", "chaincode", chaincodeName) + userName := fmt.Sprintf("%s-%s", "chaincode", shortuuid.New()[:5]) secret := shortuuid.New() _, err = m.MSPClient.Register(&clientmsp.RegistrationRequest{ Name: userName, @@ -178,7 +163,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl CAName: m.CAConfig.CAName, Secret: secret, }) - if !strings.Contains(err.Error(), "is already registered"){ + if err != nil && !strings.Contains(err.Error(), "is already registered") { return nil, err } err = m.MSPClient.Enroll( @@ -212,12 +197,13 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl rootCrt := string(caInfoResponse.CAChain) privateKey := string(pk) certificate := string(si.EnrollmentCertificate()) + codeTarBytes, err := getCodeTarGz( address, rootCrt, privateKey, certificate, - "", + input.Indexes, ) resClient, err := resmgmt.New(m.SDKContext) if err != nil { @@ -263,32 +249,42 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl } } log.Debugf("collections=%v", collections) + approveCCRequest := resmgmt.LifecycleApproveCCRequest{ + Name: chaincodeName, + Version: version, + PackageID: packageID, + Sequence: int64(sequence), + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: sp, + CollectionConfig: collections, + InitRequired: false, + } + var wg sync.WaitGroup + wg.Add(len(m.SDKContextMap)) for mspID, sdkContext := range m.SDKContextMap { - resClient, err := resmgmt.New(sdkContext) - if err != nil { - return nil, err - } - txID, err := resClient.LifecycleApproveCC( - m.Channel, - resmgmt.LifecycleApproveCCRequest{ - Name: chaincodeName, - Version: version, - PackageID: packageID, - Sequence: int64(sequence), - EndorsementPlugin: "escc", - ValidationPlugin: "vscc", - SignaturePolicy: sp, - CollectionConfig: collections, - InitRequired: false, - }, - resmgmt.WithTimeout(fab.ResMgmt, 2*time.Minute), - resmgmt.WithTimeout(fab.PeerResponse, 2*time.Minute), - ) - if err != nil { - return nil, err - } - log.Infof("%s Chaincode %s approved= %s", mspID, chaincodeName, txID) + mspID := mspID + sdkContext := sdkContext + go func() { + defer wg.Done() + resClient, err := resmgmt.New(sdkContext) + if err != nil { + log.Errorf("Error when creating resmgmt client: %v", err) + return + } + txID, err := resClient.LifecycleApproveCC( + m.Channel, + approveCCRequest, + resmgmt.WithTargetFilter(&mspFilter{mspID: mspID}), + ) + if err != nil && !strings.Contains(err.Error(), "redefine uncommitted") { + log.Errorf("Error when approving chaincode: %v", err) + return + } + log.Infof("%s Chaincode %s approved= %s", mspID, chaincodeName, txID) + }() } + wg.Wait() commitReadiness, err := resClient.LifecycleCheckCCCommitReadiness(m.Channel, resmgmt.LifecycleCheckCCCommitReadinessRequest{ Name: chaincodeName, @@ -356,7 +352,6 @@ func ParseX509Certificate(contents []byte) (*x509.Certificate, error) { return crt, nil } - func (m mutationResolver) InvokeChaincode(ctx context.Context, input models.InvokeChaincodeInput) (*models.InvokeChaincodeResponse, error) { chContext := m.SDK.ChannelContext( m.Channel, diff --git a/schema/mutation.graphql b/schema/mutation.graphql index 888eb9b..8640329 100644 --- a/schema/mutation.graphql +++ b/schema/mutation.graphql @@ -61,8 +61,12 @@ type DeployChaincodeResponse { } input DeployChaincodeInput { name: String! - tenantId: Int! pdc: String! chaincodeAddress: String! signaturePolicy: String! + indexes: [CouchDBIndex!] +} +input CouchDBIndex { + id: String! + contents: String! } From a4ab0f64be718364c6677e2fe77fdd0842ffa11d Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Fri, 21 Jan 2022 09:46:38 +0100 Subject: [PATCH 08/20] install in peers per organization --- cmd/start/start.go | 86 +++++++++++++++++++++++++++++++++++---- gql/resolvers/mutation.go | 23 ++++++----- 2 files changed, 91 insertions(+), 18 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index c3c6555..cb171ad 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -2,6 +2,10 @@ package start import ( "context" + "crypto/ecdsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" "fmt" "github.com/hashicorp/yamux" "github.com/kfsoftware/getout/pkg/tunnel" @@ -96,6 +100,29 @@ func ensureDirs(paths ...string) error { } return nil } + +func ParsePKCS8PrivateKey(contents []byte) (*ecdsa.PrivateKey, error) { + block, _ := pem.Decode(contents) + key, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + ecdsaKey, ok := key.(*ecdsa.PrivateKey) + if !ok { + return nil, errors.New("private key is not of ECDSA type") + } + return ecdsaKey, nil +} +func ParseECDSAPrivateKey(contents []byte) (*ecdsa.PrivateKey, error) { + block, _ := pem.Decode(contents) + var ecdsaKey *ecdsa.PrivateKey + var err error + ecdsaKey, err = x509.ParseECPrivateKey(block.Bytes) + if err != nil { + return nil, err + } + return ecdsaKey, nil +} func (c startCmd) run() error { var err error p := mustGetHLFCCPaths() @@ -178,8 +205,17 @@ func (c startCmd) run() error { if err != nil { return err } + pk, err := ParseECDSAPrivateKey([]byte(m.DeployChaincode.PrivateKey)) + if err != nil { + return err + } + pkBytes, err := EncodePrivateKey(pk) + if err != nil { + return err + } + log.Infof("Private key: %s", string(pkBytes)) chaincodeKeyPath := filepath.Join(p.CertsDir(c.chaincode), "chaincode.key") - err = ioutil.WriteFile(chaincodeKeyPath, []byte(m.DeployChaincode.PrivateKey), 0777) + err = ioutil.WriteFile(chaincodeKeyPath, pkBytes, 0777) if err != nil { return err } @@ -193,13 +229,37 @@ func (c startCmd) run() error { if err != nil { return err } + + chaincodeKeyB64Path := filepath.Join(p.CertsDir(c.chaincode), "chaincode_b64.key") + err = ioutil.WriteFile(chaincodeKeyB64Path, []byte(base64.StdEncoding.EncodeToString(pkBytes)), 0777) + if err != nil { + return err + } + chaincodeCertB64Path := filepath.Join(p.CertsDir(c.chaincode), "chaincode_b64.pem") + err = ioutil.WriteFile(chaincodeCertB64Path, []byte(base64.StdEncoding.EncodeToString([]byte(m.DeployChaincode.Certificate))), 0777) + if err != nil { + return err + } dotEnvFile := fmt.Sprintf(` -export CORE_CHAINCODE_ID_NAME=%s -export CORE_CHAINCODE_ADDRESS=%s -export CORE_CHAINCODE_KEY_FILE=%s -export CORE_CHAINCODE_CERT_FILE=%s -export CORE_CHAINCODE_CA_FILE=%s -`, m.DeployChaincode.PackageID, c.localChaincodeAddress, chaincodeKeyPath, chaincodeCertPath, caCertPath) +CORE_CHAINCODE_ID_NAME=%s +CORE_CHAINCODE_ADDRESS=%s +CORE_CHAINCODE_KEY_FILE=%s +CORE_CHAINCODE_CERT_FILE=%s +CORE_CHAINCODE_CA_FILE=%s + +CORE_PEER_TLS_ROOTCERT_FILE=%s +CORE_TLS_CLIENT_KEY_PATH=%s +CORE_TLS_CLIENT_CERT_PATH=%s +`, + m.DeployChaincode.PackageID, + c.localChaincodeAddress, + chaincodeKeyPath, + chaincodeCertPath, + caCertPath, + caCertPath, + chaincodeKeyB64Path, + chaincodeCertB64Path, + ) dotEnvPath := filepath.Join(p.CertsDir(c.chaincode), ".env") err = ioutil.WriteFile(dotEnvPath, []byte(dotEnvFile), 0777) if err != nil { @@ -221,6 +281,18 @@ export CORE_CHAINCODE_CA_FILE=%s } return err } +func EncodePrivateKey(key interface{}) ([]byte, error) { + signEncodedPK, err := x509.MarshalPKCS8PrivateKey(key) + if err != nil { + return nil, err + } + pemPk := pem.EncodeToMemory(&pem.Block{ + Type: "PRIVATE KEY", + Bytes: signEncodedPK, + }) + return pemPk, nil +} + func startTunnel(tunnelAddr string, localAddress string, sni string) error { conn, err := net.Dial("tcp", tunnelAddr) if err != nil { diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 2888140..87cb38c 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -216,17 +216,6 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl if err != nil { return nil, err } - _, err = resClient.LifecycleInstallCC( - resmgmt.LifecycleInstallCCRequest{ - Label: input.Name, - Package: pkg, - }, - resmgmt.WithTimeout(fab.ResMgmt, 2*time.Minute), - resmgmt.WithTimeout(fab.PeerResponse, 2*time.Minute), - ) - if err != nil { - return nil, err - } packageID := lifecycle.ComputePackageID(chaincodeName, pkg) signaturePolicy := input.SignaturePolicy sp, err := policydsl.FromString(signaturePolicy) @@ -272,6 +261,18 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl log.Errorf("Error when creating resmgmt client: %v", err) return } + _, err = resClient.LifecycleInstallCC( + resmgmt.LifecycleInstallCCRequest{ + Label: input.Name, + Package: pkg, + }, + resmgmt.WithTimeout(fab.ResMgmt, 2*time.Minute), + resmgmt.WithTimeout(fab.PeerResponse, 2*time.Minute), + ) + if err != nil { + log.Errorf("Error when installing chaincode: %v", err) + return + } txID, err := resClient.LifecycleApproveCC( m.Channel, approveCCRequest, From 1f2e8ee8af7ecc9a525bfe49a7b9de821e1d3f4f Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Mon, 24 Jan 2022 09:38:41 +0100 Subject: [PATCH 09/20] Modify environment variables to align with Hyperledger Fabric --- cmd/start/start.go | 20 ++++++++++++++------ go.mod | 3 ++- go.sum | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index cb171ad..eaa7de6 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -63,6 +63,7 @@ type startCmd struct { chaincodeAddress string chaincodeAddressSubdomain string signaturePolicy string + envFile string } func (c startCmd) validate() error { @@ -241,15 +242,15 @@ func (c startCmd) run() error { return err } dotEnvFile := fmt.Sprintf(` -CORE_CHAINCODE_ID_NAME=%s +CORE_CHAINCODE_ID=%s CORE_CHAINCODE_ADDRESS=%s -CORE_CHAINCODE_KEY_FILE=%s -CORE_CHAINCODE_CERT_FILE=%s -CORE_CHAINCODE_CA_FILE=%s +CORE_CHAINCODE_TLS_KEY_FILE=%s +CORE_CHAINCODE_TLS_CERT_FILE=%s +CORE_CHAINCODE_TLS_CLIENT_CACERT_FILE=%s CORE_PEER_TLS_ROOTCERT_FILE=%s -CORE_TLS_CLIENT_KEY_PATH=%s -CORE_TLS_CLIENT_CERT_PATH=%s +CORE_TLS_CLIENT_KEY_FILE=%s +CORE_TLS_CLIENT_CERT_FILE=%s `, m.DeployChaincode.PackageID, c.localChaincodeAddress, @@ -265,6 +266,12 @@ CORE_TLS_CLIENT_CERT_PATH=%s if err != nil { return err } + if c.envFile != "" { + err = ioutil.WriteFile(c.envFile, []byte(dotEnvFile), 0777) + if err != nil { + return err + } + } sni, _, err := net.SplitHostPort(chaincodeAddress) if err != nil { return err @@ -349,5 +356,6 @@ func NewStartCmd() *cobra.Command { f.StringVar(&c.accessToken, "accessToken", "", "access token") f.StringVar(&c.metaInf, "metaInf", "", "metadata") f.StringVar(&c.signaturePolicy, "signaturePolicy", "", "Signature policy") + f.StringVar(&c.envFile, "env-file", "", "Env file to write the environments") return cmd } diff --git a/go.mod b/go.mod index b859fd8..3c63298 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/hyperledger/fabric-config v0.1.0 github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354 github.com/hyperledger/fabric-sdk-go v1.0.0 - github.com/kfsoftware/getout v0.0.4-beta4 + github.com/kfsoftware/getout v0.0.4-beta2 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mattn/go-sqlite3 v1.14.8 // indirect @@ -30,3 +30,4 @@ require ( ) replace github.com/go-kit/kit => github.com/go-kit/kit v0.8.0 +replace github.com/kfsoftware/getout => github.com/kfsoftware/getout v0.0.4-beta2 diff --git a/go.sum b/go.sum index 22c07ca..7f3d4c6 100644 --- a/go.sum +++ b/go.sum @@ -396,6 +396,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= +github.com/kfsoftware/getout v0.0.4-beta2 h1:0PZhp24N4KyHEhVjayNcscSxith2PrBMSFE2o69TLmY= +github.com/kfsoftware/getout v0.0.4-beta2/go.mod h1:5V6Cp5Yf/CzycuKXJc5cnL6hmNx+evl1X7yHNL9gB2M= github.com/kfsoftware/getout v0.0.4-beta4 h1:7nk6Gds4WDmNcSrgVnBuPPfKXBpOartCeymPYXe6tLM= github.com/kfsoftware/getout v0.0.4-beta4/go.mod h1:mB5QcbViWO6Pn9hH2WC2ITsXkTlAzuaIdxe21qSAVFM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= From a06a0afd4fed72074346caae2210a4e98b68e2d1 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sat, 29 Jan 2022 08:56:49 +0100 Subject: [PATCH 10/20] handle errors --- gql/resolvers/mutation.go | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 87cb38c..9957990 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -42,9 +42,19 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { // set up the gzip writer gw := gzip.NewWriter(buf) - defer gw.Close() + defer func(gw *gzip.Writer) { + err := gw.Close() + if err != nil { + log.Warnf("gzip.Writer.Close() failed: %s", err) + } + }(gw) tw := tar.NewWriter(gw) - defer tw.Close() + defer func(tw *tar.Writer) { + err := tw.Close() + if err != nil { + log.Warnf("tar.Writer.Close() failed: %s", err) + } + }(tw) header := new(tar.Header) header.Name = "metadata.json" metadataJsonBytes := []byte(metadataJson) @@ -59,7 +69,6 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { if err != nil { return nil, err } - headerCode := new(tar.Header) headerCode.Name = "code.tar.gz" headerCode.Size = int64(len(codeTarGz)) @@ -73,8 +82,7 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { if err != nil { return nil, err } - tw.Close() - gw.Close() + return buf.Bytes(), nil } @@ -93,13 +101,11 @@ func getCodeTarGz(address string, rootCert string, clientKey string, clientCert if err != nil { return nil, err } - log.Infof("Conn=%s", string(connJsonBytes)) + log.Debugf("Conn=%s", string(connJsonBytes)) // set up the output file buf := &bytes.Buffer{} - // set up the gzip writer gw := gzip.NewWriter(buf) - tw := tar.NewWriter(gw) header := new(tar.Header) header.Name = "connection.json" @@ -133,9 +139,14 @@ func getCodeTarGz(address string, rootCert string, clientKey string, clientCert } } - - tw.Close() - gw.Close() + err = tw.Close() + if err != nil { + return nil, err + } + err = gw.Close() + if err != nil { + return nil, err + } return buf.Bytes(), nil } @@ -197,7 +208,6 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl rootCrt := string(caInfoResponse.CAChain) privateKey := string(pk) certificate := string(si.EnrollmentCertificate()) - codeTarBytes, err := getCodeTarGz( address, rootCrt, From 9708cf5b1d6469ed96ef6b97ee60f801ba4f6906 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sat, 29 Jan 2022 20:54:12 +0100 Subject: [PATCH 11/20] Add chaincode query by name --- cmd/start/start.go | 27 ++++++------ go.mod | 1 + go.sum | 23 +++------- gql/generated.go | 87 ++++++++++++++++++++++++++++++++++++++ gql/resolvers/query.go | 24 ++++++++++- gql/resolvers/resolvers.go | 1 + schema/query.graphql | 1 + 7 files changed, 134 insertions(+), 30 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index eaa7de6..0c9a6e2 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -273,18 +273,21 @@ CORE_TLS_CLIENT_CERT_FILE=%s } } sni, _, err := net.SplitHostPort(chaincodeAddress) - if err != nil { - return err - } - log.Infof("Channel: %s Chaincode: %s", m.DeployChaincode.ChaincodeName, m.DeployChaincode.ChannelName) - log.Infof("starting tunnel from %s to %s", c.localChaincodeAddress, chaincodeAddress) - err = startTunnel( - c.tunnelAddress, - c.localChaincodeAddress, - sni, - ) - if err != nil { - return err + if c.tunnelAddress != "" && sni != "" { + if err != nil { + return err + } + log.Infof("Channel: %s Chaincode: %s", m.DeployChaincode.ChaincodeName, m.DeployChaincode.ChannelName) + log.Infof("starting tunnel from %s to %s", c.localChaincodeAddress, chaincodeAddress) + + err = startTunnel( + c.tunnelAddress, + c.localChaincodeAddress, + sni, + ) + if err != nil { + return err + } } return err } diff --git a/go.mod b/go.mod index 3c63298..0fadb6b 100644 --- a/go.mod +++ b/go.mod @@ -30,4 +30,5 @@ require ( ) replace github.com/go-kit/kit => github.com/go-kit/kit v0.8.0 + replace github.com/kfsoftware/getout => github.com/kfsoftware/getout v0.0.4-beta2 diff --git a/go.sum b/go.sum index 7f3d4c6..9b0887f 100644 --- a/go.sum +++ b/go.sum @@ -329,9 +329,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.7.0 h1:pwjzcYyfmz/HQOQlENvG1OcDqauTGaqlVahq934F0/U= github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA= -github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -344,9 +343,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.5 h1:NUbEWPmCQZbMmYlTjVoNPhc0CfnYyz2bfUAh6A5ZVJM= github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -356,24 +354,21 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.5.0 h1:jzBqRk2HFG2CV4AIwgCI2PwTgm6UUoCAK2ofHHRirtc= github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= -github.com/jackc/pgtype v1.6.2 h1:b3pDeuhbbzBYcg5kwNmNDun4pFUD/0AAr1kLXZLeNt8= -github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.9.0 h1:6STjDqppM2ROy5p1wNDcsC7zJTjSHeuCsguZmXyzx7c= github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms= -github.com/jackc/pgx/v4 v4.10.1 h1:/6Q3ye4myIj6AaplUm+eRcz4OhK9HAvFf4ePsG40LJY= -github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= @@ -398,8 +393,6 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= github.com/kfsoftware/getout v0.0.4-beta2 h1:0PZhp24N4KyHEhVjayNcscSxith2PrBMSFE2o69TLmY= github.com/kfsoftware/getout v0.0.4-beta2/go.mod h1:5V6Cp5Yf/CzycuKXJc5cnL6hmNx+evl1X7yHNL9gB2M= -github.com/kfsoftware/getout v0.0.4-beta4 h1:7nk6Gds4WDmNcSrgVnBuPPfKXBpOartCeymPYXe6tLM= -github.com/kfsoftware/getout v0.0.4-beta4/go.mod h1:mB5QcbViWO6Pn9hH2WC2ITsXkTlAzuaIdxe21qSAVFM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -1056,12 +1049,10 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.0.0 h1:5rDW3AnqXaacuQn6nB/ZNAIfTCIvmL5oKGa/TtCoBFA= gorm.io/datatypes v1.0.0/go.mod h1:aKpJ+RNhLXWeF5OAdxfzBwT1UPw1wseSchF0AY3/lSw= +gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg= gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= -gorm.io/driver/mysql v1.0.5 h1:WAAmvLK2rG0tCOqrf5XcLi2QUwugd4rcVJ/W3aoon9o= -gorm.io/driver/mysql v1.0.5/go.mod h1:N1OIhHAIhx5SunkMGqWbGFVeh4yTNWKmMo1GOAsohLI= +gorm.io/driver/postgres v1.0.5 h1:raX6ezL/ciUmaYTvOq48jq1GE95aMC0CmxQYbxQ4Ufw= gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= -gorm.io/driver/postgres v1.0.8 h1:PAgM+PaHOSAeroTjHkCHCBIHHoBIf9RgPWGo8dF2DA8= -gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc= gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= gorm.io/driver/sqlserver v1.0.5 h1:n5knSvyaEwufxl0aROEW90pn+aLoV9h+vahYJk1x5l4= @@ -1070,8 +1061,6 @@ gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.5/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.6 h1:xEFbH7WShsnAM+HeRNv7lOeyqmDAK+dDnf1AMf/cVPQ= gorm.io/gorm v1.21.6/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/gql/generated.go b/gql/generated.go index e88b4c7..3ef84a2 100644 --- a/gql/generated.go +++ b/gql/generated.go @@ -72,6 +72,7 @@ type ComplexityRoot struct { } Query struct { + Chaincode func(childComplexity int, name string) int Chaincodes func(childComplexity int) int } @@ -94,6 +95,7 @@ type MutationResolver interface { } type QueryResolver interface { Chaincodes(ctx context.Context) ([]*models.Chaincode, error) + Chaincode(ctx context.Context, name string) (*models.Chaincode, error) } type executableSchema struct { @@ -245,6 +247,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.QueryChaincode(childComplexity, args["input"].(models.QueryChaincodeInput)), true + case "Query.chaincode": + if e.complexity.Query.Chaincode == nil { + break + } + + args, err := ec.field_Query_chaincode_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Chaincode(childComplexity, args["name"].(string)), true + case "Query.chaincodes": if e.complexity.Query.Chaincodes == nil { break @@ -426,6 +440,7 @@ input CouchDBIndex { `, BuiltIn: false}, {Name: "schema/query.graphql", Input: `type Query { chaincodes: [Chaincode!] + chaincode(name: String!): Chaincode } type Chaincode { @@ -522,6 +537,21 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query_chaincode_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["name"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["name"] = arg0 + return args, nil +} + func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1208,6 +1238,45 @@ func (ec *executionContext) _Query_chaincodes(ctx context.Context, field graphql return ec.marshalOChaincode2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐChaincodeᚄ(ctx, field.Selections, res) } +func (ec *executionContext) _Query_chaincode(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_chaincode_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Chaincode(rctx, args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Chaincode) + fc.Result = res + return ec.marshalOChaincode2ᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐChaincode(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -3060,6 +3129,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_chaincodes(ctx, field) return res }) + case "chaincode": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_chaincode(ctx, field) + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": @@ -3864,6 +3944,13 @@ func (ec *executionContext) marshalOChaincode2ᚕᚖgithubᚗcomᚋkfsoftwareᚋ return ret } +func (ec *executionContext) marshalOChaincode2ᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐChaincode(ctx context.Context, sel ast.SelectionSet, v *models.Chaincode) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Chaincode(ctx, sel, v) +} + func (ec *executionContext) unmarshalOCouchDBIndex2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐCouchDBIndexᚄ(ctx context.Context, v interface{}) ([]*models.CouchDBIndex, error) { if v == nil { return nil, nil diff --git a/gql/resolvers/query.go b/gql/resolvers/query.go index 1ee0abc..51ce1d2 100644 --- a/gql/resolvers/query.go +++ b/gql/resolvers/query.go @@ -15,7 +15,7 @@ func (r *queryResolver) Chaincodes(ctx context.Context) ([]*models.Chaincode, er if err != nil { return nil, err } - chaincodes := []*models.Chaincode{} + var chaincodes []*models.Chaincode for _, cc := range committedCCs { chaincodes = append(chaincodes, &models.Chaincode{ Name: cc.Name, @@ -25,3 +25,25 @@ func (r *queryResolver) Chaincodes(ctx context.Context) ([]*models.Chaincode, er } return chaincodes, nil } + +func (r *queryResolver) Chaincode(ctx context.Context, name string) (*models.Chaincode, error) { + resClient, err := resmgmt.New(r.SDKContext) + if err != nil { + return nil, err + } + committedCCs, err := resClient.LifecycleQueryCommittedCC(r.Channel, resmgmt.LifecycleQueryCommittedCCRequest{ + Name: name, + }) + if err != nil { + return nil, err + } + var chaincode *models.Chaincode + for _, cc := range committedCCs { + chaincode = &models.Chaincode{ + Name: cc.Name, + Sequence: int(cc.Sequence), + Version: cc.Version, + } + } + return chaincode, nil +} diff --git a/gql/resolvers/resolvers.go b/gql/resolvers/resolvers.go index 1606a92..dedd1d1 100644 --- a/gql/resolvers/resolvers.go +++ b/gql/resolvers/resolvers.go @@ -30,3 +30,4 @@ func (r *Resolver) Query() gql.QueryResolver { return &queryResolver{r} } type mutationResolver struct{ *Resolver } type queryResolver struct{ *Resolver } + diff --git a/schema/query.graphql b/schema/query.graphql index b0c88ea..6487dd4 100644 --- a/schema/query.graphql +++ b/schema/query.graphql @@ -1,5 +1,6 @@ type Query { chaincodes: [Chaincode!] + chaincode(name: String!): Chaincode } type Chaincode { From 69bf9b9f5c8b4172fb9ee4f3a978f1d4b1c6d421 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sat, 29 Jan 2022 22:04:39 +0100 Subject: [PATCH 12/20] remove tunnelAddress as mandatory --- cmd/start/start.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index 0c9a6e2..d8f133a 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -76,9 +76,6 @@ func (c startCmd) validate() error { if c.chaincode == "" { return errors.New("--chaincode is required") } - if c.tunnelAddress == "" { - return errors.New("--tunnelAddress is required") - } if c.localChaincodeAddress == "" { return errors.New("--localChaincodeAddress is required") } @@ -243,6 +240,7 @@ func (c startCmd) run() error { } dotEnvFile := fmt.Sprintf(` CORE_CHAINCODE_ID=%s +CORE_CHAINCODE_ID_NAME=%s CORE_CHAINCODE_ADDRESS=%s CORE_CHAINCODE_TLS_KEY_FILE=%s CORE_CHAINCODE_TLS_CERT_FILE=%s @@ -252,6 +250,7 @@ CORE_PEER_TLS_ROOTCERT_FILE=%s CORE_TLS_CLIENT_KEY_FILE=%s CORE_TLS_CLIENT_CERT_FILE=%s `, + m.DeployChaincode.PackageID, m.DeployChaincode.PackageID, c.localChaincodeAddress, chaincodeKeyPath, From 1bdb3e92c92958fcecfadd7dd126052514980f59 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sat, 29 Jan 2022 22:08:06 +0100 Subject: [PATCH 13/20] update README --- README.md | 121 +++++++++++++++++++++++++++++++++++- static/img/diagram.png | Bin 0 -> 34260 bytes static/img/ngrok-tunnel.png | Bin 0 -> 65757 bytes 3 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 static/img/diagram.png create mode 100644 static/img/ngrok-tunnel.png diff --git a/README.md b/README.md index d4a0427..caf3d9a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,120 @@ -## Chaincode as a service +## What's `hlf-cc-dev`? + +`hlf-cc-dev` is a tool to start developing a new chaincode from your development environment. + +### Why does this tool exist? + +When developing chaincodes, we need to have an HLF network deployed, usually in our development environment. It is hard for new developers to get started since they need to know how to deploy an HLF network. + +This tool aims to ease the onboarding of new developers that are not familiar with the internals of the HLF network but are interested in developing chaincodes. + +The only requirement is that the developer has access to a working HLF network. This network can be set up by Administrators that are used to perform these operations, so the developer doesn't need to. + +With this tool, instead of installing the chaincode in the peers, approving the chaincode definition, and finally, committing the chaincode, the developer can have the chaincode started in its machine. With one command, it can install, approve and commit the chaincode in one go. SupposeThen, ifhe developer needs to modify the chaincode logic. In that case, all it needs to do is restart the chaincode program running in its machine, just like any other application the developer is used to developing. + +### What you'll need + +- A TLS/TCP tunnel to your local development environment (ngrok, getout, etc.) +- Hyperledger Fabric peer with external chaincode builder enabled. +- Network config with admin users for all of the organizations peers you will use. + +## General diagram + +The following diagram explains the architecture of the final solution + +![Diagram](./static/img/diagram.png) + +## Steps to get started + +To start the server, you need the network config with the admin users for each organization. + +```bash +hlf-cc-dev serve --address ":8080" --metrics-address ":8081" --config "" +``` + +## Start development in your local environment + +You need to have a chaincode that's able to be deployed as an external service; you can take a look at the following templates: + +- For Go (https://github.com/kfsoftware/hlf-cc-go-template) +- For Node.JS (https://github.com/kfsoftware/hlf-cc-node-template) +- **pending** For Java (https://github.com/kfsoftware/hlf-cc-java-template) + +We recommend using the Go template since it's the easiest one to get started with. + +Once you have the chaincode project set up on your local machine, you need to expose your server to the public; the easiest way to do this is to use a TLS/TCP tunnel, for example, [ngrok](https://ngrok.com/download). + +```bash +ngrok tcp 9999 --region=eu # region can be us, eu, au, ap, sa, jp, in +``` +The previous command will have this output: + +![ngrok](./static/img/ngrok-tunnel.png) + +Copy the Forwarding URL, but remove the `tcp://` part; for example, if you got `tcp://6.tcp.eu.ngrok.io:19922`, then you want to use `6.tcp.eu.ngrok.io:19922` for the following command(hlf-cc-dev). + +After having exposed your chaincode server to the public, you can run the following command to trigger: + +- Installation of the chaincode on the peers. +- Approval of the chaincode definition. +- Committing the chaincode definition. + +```bash +CHAINCODE_NAME=template_go +API_URL="http://localhost:8080/graphql" +SIGNATURE_POLICY="OR('Org1MSP.member', 'Org2MSP.member')" +CHAINCODE_ADDRESS_TUNNEL="4.tcp.eu.ngrok.io:13438" # the forwarding URL you get from opening an ngrok tunnel +hlf-cc-dev start --localChaincode="localhost:9999" \ + --chaincodeAddress="${CHAINCODE_ADDRESS_TUNNEL}" \ + --chaincode="${CHAINCODE_NAME}" \ + --signaturePolicy="${SIGNATURE_POLICY}" \ + --env-file="${PWD}/.env" \ + --apiUrl="${API_URL}" +``` + +After the successful execution of the previous command, you can follow the instructions on the README.md for each template. + +For example, for Go, you would run the following command: + +```bash +source .env && go run ./main.go +``` + +Then you can go to http://localhost:8080/graphql and test the chaincode by running the following mutation: + +```graphql +mutation invoke { + invokeChaincode(input:{ + chaincodeName:"template_go" + function: "InitLedger" + args: [] + transientMap: [] + }){ + response + transactionID + chaincodeStatus + } +} + +mutation query { + queryChaincode(input:{ + chaincodeName:"template_go" + function: "GetAllAssets" + args: [] + transientMap: [] + }){ + response + chaincodeStatus + } +} + +``` + +If there are any issues you run into with the previous mutations, this can be because: +- The network config used to start the server is not correct. +- The users set up in the network config are not admins. +- The chaincode name is not valid. +- The chaincode function is not valid. + +If after checking the previous things you still get an error, please, [you can open an issue](https://github.com/kfsoftware/hlf-cc-dev/issues/new) -Documentation: TODO \ No newline at end of file diff --git a/static/img/diagram.png b/static/img/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..2c933c68d8a9fff3a2c6bfc58337841219bab250 GIT binary patch literal 34260 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 literal 0 HcmV?d00001 diff --git a/static/img/ngrok-tunnel.png b/static/img/ngrok-tunnel.png new file mode 100644 index 0000000000000000000000000000000000000000..6b0aa4638ae40466eefd3267ba680144c341904b GIT binary patch literal 65757 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�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 literal 0 HcmV?d00001 From 0d055c240aa08553a6ef47d2c9432b6e0ec79b8c Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Fri, 25 Mar 2022 20:14:12 +0100 Subject: [PATCH 14/20] update --- cmd/start/start.go | 16 ++-------------- gql/resolvers/mutation.go | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index eaa7de6..931b6f4 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -102,19 +102,7 @@ func ensureDirs(paths ...string) error { return nil } -func ParsePKCS8PrivateKey(contents []byte) (*ecdsa.PrivateKey, error) { - block, _ := pem.Decode(contents) - key, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return nil, err - } - ecdsaKey, ok := key.(*ecdsa.PrivateKey) - if !ok { - return nil, errors.New("private key is not of ECDSA type") - } - return ecdsaKey, nil -} -func ParseECDSAPrivateKey(contents []byte) (*ecdsa.PrivateKey, error) { +func parseECDSAPrivateKey(contents []byte) (*ecdsa.PrivateKey, error) { block, _ := pem.Decode(contents) var ecdsaKey *ecdsa.PrivateKey var err error @@ -206,7 +194,7 @@ func (c startCmd) run() error { if err != nil { return err } - pk, err := ParseECDSAPrivateKey([]byte(m.DeployChaincode.PrivateKey)) + pk, err := parseECDSAPrivateKey([]byte(m.DeployChaincode.PrivateKey)) if err != nil { return err } diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 87cb38c..4db5f52 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -33,7 +33,7 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { var err error metadataJson := fmt.Sprintf(` { - "type": "external", + "type": "ccaas", "label": "%s" } `, label) From 433e25f247d28bc692acdb01724172e38b7fae8b Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Mon, 28 Mar 2022 08:22:57 +0200 Subject: [PATCH 15/20] use gateway to execute transactions --- cmd/serve/serve.go | 152 ++++++++++++++++++++++++++++++++++++- cmd/start/start.go | 2 +- go.mod | 8 +- go.sum | 78 +++++++++++++------ gql/resolvers/mutation.go | 56 +++++++++----- gql/resolvers/resolvers.go | 2 + server/server.go | 7 +- 7 files changed, 255 insertions(+), 50 deletions(-) diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index f30e1a9..6479245 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -1,8 +1,11 @@ package serve import ( + "crypto/x509" "fmt" "github.com/hyperledger/fabric-config/configtx" + "github.com/hyperledger/fabric-gateway/pkg/client" + "github.com/hyperledger/fabric-gateway/pkg/identity" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" @@ -10,11 +13,16 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/pkg/msp" + "github.com/kfsoftware/hlf-cc-dev/log" "github.com/kfsoftware/hlf-cc-dev/server" _ "github.com/lib/pq" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "strings" + "time" ) const ( @@ -87,7 +95,45 @@ func (c *serveCmd) validate() error { } return nil } - +func getGatewayParams(serve *serveConfig, sdk *fabsdk.FabricSDK) (*GatewayParams, error) { + configBackend1, err := sdk.Config() + if err != nil { + return nil, err + } + adminCertPem, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.users.admin.cert.pem", serve.Fabric.Org)) + log.Infof("adminCertPem: %v", adminCertPem) + adminCertKey, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.users.admin.key.pem", serve.Fabric.Org)) + log.Infof("adminCertKey: %v", adminCertKey) + peersInt, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.peers", serve.Fabric.Org)) + peersArrayInterface := peersInt.([]interface{}) + var peers []string + idx := 0 + var peerUrl string + var peerTLSCACert []byte + for _, item := range peersArrayInterface { + peerName := item.(string) + peers = append(peers, peerName) + peerUrlKey := fmt.Sprintf("peers.%s.url", peerName) + peerTLSCACertKey := fmt.Sprintf("peers.%s.tlsCACerts.pem", peerName) + peerUrlInt, _ := configBackend1.Lookup(peerUrlKey) + peerTLSCACertInt, _ := configBackend1.Lookup(peerTLSCACertKey) + peerUrl = strings.Replace(peerUrlInt.(string), "grpcs://", "", -1) + peerTLSCACert = []byte(peerTLSCACertInt.(string)) + //log.Infof("peerUrl: %v", peerUrl) + //log.Infof("peerTLSCACert: %v", peerTLSCACert) + idx++ + if idx >= 1 { + break + } + } + return &GatewayParams{ + adminKey: adminCertKey.(string), + adminCert: adminCertPem.(string), + peerUrl: peerUrl, + peerTLSCACert: peerTLSCACert, + mspID: serve.Fabric.Org, + }, nil +} func (c *serveCmd) run(conf *serveConfig) error { err := conf.validate() if err != nil { @@ -102,6 +148,7 @@ func (c *serveCmd) run(conf *serveConfig) error { fabsdk.WithUser(conf.Fabric.User), fabsdk.WithOrg(conf.Fabric.Org), ) + embeddedBackend, err := configBackend() if err != nil { return err @@ -132,7 +179,6 @@ func (c *serveCmd) run(conf *serveConfig) error { if err != nil { return err } - block, err := resClient.QueryConfigBlockFromOrderer(conf.Fabric.Channel) if err != nil { return err @@ -157,10 +203,32 @@ func (c *serveCmd) run(conf *serveConfig) error { fabsdk.WithOrg(organization.MSP.Name), ) } + gwParams, err := getGatewayParams(conf, sdk) + if err != nil { + return err + } + clientConnection, err := newGrpcConnection( + gwParams.peerUrl, + gwParams.peerTLSCACert, + ) + if err != nil { + return err + } + gwClient, err := getGateway(*gwParams, clientConnection) + if err != nil { + return err + } + //clientConn := getClientCollection() + //defer clientConn.Close() + //gwClient, err := getGateway(conf, clientConn) + //if err != nil { + // return err + //} opts := server.BlockchainServerOpts{ Address: c.address, MetricsAddress: c.metricsAddress, SDK: sdk, + GWClient: gwClient, SDKContext: sdkContext, SDKContextMap: mapSdkContext, Channel: conf.Fabric.Channel, @@ -173,3 +241,83 @@ func (c *serveCmd) run(conf *serveConfig) error { s.Run() return nil } + +type GatewayParams struct { + adminKey string + adminCert string + peerUrl string + peerTLSCACert []byte + mspID string +} + +func newIdentity(certificatePEM []byte) (*identity.X509Identity, error) { + cert, err := identity.CertificateFromPEM(certificatePEM) + if err != nil { + return nil, err + } + id, err := identity.NewX509Identity("MEDIIOCHAINMSP", cert) + if err != nil { + return nil, err + } + return id, nil +} + +// newSign creates a function that generates a digital signature from a message digest using a private key. +func newSign(privateKeyPEM []byte) (identity.Sign, error) { + privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM) + if err != nil { + return nil, err + } + + sign, err := identity.NewPrivateKeySign(privateKey) + if err != nil { + return nil, err + } + + return sign, nil +} + +// newGrpcConnection creates a gRPC connection to the Gateway server. +func newGrpcConnection(peerEndpoint string, tlsCert []byte) (*grpc.ClientConn, error) { + certificate, err := identity.CertificateFromPEM(tlsCert) + if err != nil { + return nil, fmt.Errorf("failed to obtain commit status: %w", err) + } + + certPool := x509.NewCertPool() + certPool.AddCert(certificate) + transportCredentials := credentials.NewClientTLSFromCert(certPool, "") + + connection, err := grpc.Dial(peerEndpoint, grpc.WithTransportCredentials(transportCredentials)) + if err != nil { + return nil, fmt.Errorf("failed to evaluate transaction: %w", err) + } + + return connection, nil +} +func getGateway(params GatewayParams, clientConnection *grpc.ClientConn) (*client.Gateway, error) { + + id, err := newIdentity([]byte(params.adminCert)) + if err != nil { + return nil, err + } + sign, err := newSign([]byte(params.adminKey)) + if err != nil { + return nil, err + } + // Create a Gateway connection for a specific client identity + gw, err := client.Connect( + id, + client.WithSign(sign), + client.WithClientConnection(clientConnection), + // Default timeouts for different gRPC calls + client.WithEvaluateTimeout(5*time.Second), + client.WithEndorseTimeout(15*time.Second), + client.WithSubmitTimeout(5*time.Second), + client.WithCommitStatusTimeout(1*time.Minute), + ) + if err != nil { + return nil, err + } + return gw, nil +} diff --git a/cmd/start/start.go b/cmd/start/start.go index 931b6f4..9457a79 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -235,7 +235,7 @@ CORE_CHAINCODE_ADDRESS=%s CORE_CHAINCODE_TLS_KEY_FILE=%s CORE_CHAINCODE_TLS_CERT_FILE=%s CORE_CHAINCODE_TLS_CLIENT_CACERT_FILE=%s - +CHAINCODE_TLS_DISABLED=false CORE_PEER_TLS_ROOTCERT_FILE=%s CORE_TLS_CLIENT_KEY_FILE=%s CORE_TLS_CLIENT_CERT_FILE=%s diff --git a/go.mod b/go.mod index 3c63298..f42320a 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,9 @@ require ( github.com/gosimple/slug v1.12.0 github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 github.com/hyperledger/fabric-config v0.1.0 - github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354 - github.com/hyperledger/fabric-sdk-go v1.0.0 + github.com/hyperledger/fabric-gateway v1.0.1 + github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 + github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f github.com/kfsoftware/getout v0.0.4-beta2 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 @@ -25,9 +26,10 @@ require ( github.com/spf13/viper v1.7.0 github.com/vektah/gqlparser/v2 v2.2.0 golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + google.golang.org/grpc v1.43.0 k8s.io/client-go v0.23.1 ) replace github.com/go-kit/kit => github.com/go-kit/kit v0.8.0 + replace github.com/kfsoftware/getout => github.com/kfsoftware/getout v0.0.4-beta2 diff --git a/go.sum b/go.sum index 7f3d4c6..c56e245 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,8 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -71,6 +73,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -102,6 +105,10 @@ github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6S github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -113,6 +120,10 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= +github.com/cucumber/godog v0.12.4/go.mod h1:u6SD7IXC49dLpPN35kal0oYEjsXZWee4pW6Tm9t5pIc= +github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= +github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -132,6 +143,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -180,6 +192,7 @@ github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae/go.mod h1:DC github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -199,8 +212,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -276,11 +290,14 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= @@ -288,10 +305,12 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -305,14 +324,19 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/hyperledger/fabric-config v0.0.5/go.mod h1:YpITBI/+ZayA3XWY5lF302K7PAsFYjEEPM/zr3hegA8= github.com/hyperledger/fabric-config v0.1.0 h1:TsR3y5xEoUmXWfp8tcDycjJhVvXEHiV5kfZIxuIte08= github.com/hyperledger/fabric-config v0.1.0/go.mod h1:aeDZ0moG/qKvwLjddcqYr8+58/oNaJy3HE0tI01546c= +github.com/hyperledger/fabric-gateway v1.0.1 h1:7AFBSlUCMrlZCRYP9rKWhcFc4Em6p7qXpX2zUPo2AYY= +github.com/hyperledger/fabric-gateway v1.0.1/go.mod h1:60RqgUVLHH3Jv4zgzgWFfoYLRG7CMO14IP2OlaohJJo= github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354 h1:6vLLEpvDbSlmUJFjg1hB5YMBpI+WgKguztlONcAFBoY= -github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20211118165945-23d738fc3553/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 h1:YV+siZuYQZwENjRH00t7ZS0CTlywt8Qog/SzL/jf6kE= +github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-sdk-go v1.0.0 h1:NRu0iNbHV6u4nd9jgYghAdA1Ll4g0Sri4hwMEGiTbyg= github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= +github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f h1:SYduJmSWX/Q8fw8tiJK/VnRS+zyLCFXMcAIAAVjzSF0= +github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f/go.mod h1:JRplpKBeAvXjsBhOCCM/KvMRUbdDyhsAh80qbXzKc10= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -329,9 +353,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.7.0 h1:pwjzcYyfmz/HQOQlENvG1OcDqauTGaqlVahq934F0/U= github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA= -github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -344,9 +367,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.5 h1:NUbEWPmCQZbMmYlTjVoNPhc0CfnYyz2bfUAh6A5ZVJM= github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -356,24 +378,21 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.5.0 h1:jzBqRk2HFG2CV4AIwgCI2PwTgm6UUoCAK2ofHHRirtc= github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= -github.com/jackc/pgtype v1.6.2 h1:b3pDeuhbbzBYcg5kwNmNDun4pFUD/0AAr1kLXZLeNt8= -github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.9.0 h1:6STjDqppM2ROy5p1wNDcsC7zJTjSHeuCsguZmXyzx7c= github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms= -github.com/jackc/pgx/v4 v4.10.1 h1:/6Q3ye4myIj6AaplUm+eRcz4OhK9HAvFf4ePsG40LJY= -github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= @@ -385,6 +404,7 @@ github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiEr github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -398,8 +418,6 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= github.com/kfsoftware/getout v0.0.4-beta2 h1:0PZhp24N4KyHEhVjayNcscSxith2PrBMSFE2o69TLmY= github.com/kfsoftware/getout v0.0.4-beta2/go.mod h1:5V6Cp5Yf/CzycuKXJc5cnL6hmNx+evl1X7yHNL9gB2M= -github.com/kfsoftware/getout v0.0.4-beta4 h1:7nk6Gds4WDmNcSrgVnBuPPfKXBpOartCeymPYXe6tLM= -github.com/kfsoftware/getout v0.0.4-beta4/go.mod h1:mB5QcbViWO6Pn9hH2WC2ITsXkTlAzuaIdxe21qSAVFM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -436,6 +454,8 @@ github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaK github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= @@ -460,6 +480,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= +github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -504,6 +526,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -518,11 +542,13 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -538,11 +564,13 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -581,9 +609,12 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.1 h1:GPTpEAuNr98px18yNQ66JllNil98wfRZ/5Ukny8FeQA= github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -648,6 +679,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -807,6 +839,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -916,6 +949,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -975,6 +1009,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1006,12 +1041,14 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1 h1:cmUfbeGKnz9+2DD/UYsMQXeqbHZqZDs4eQwW0sFOpBY= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1044,6 +1081,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1056,12 +1094,10 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.0.0 h1:5rDW3AnqXaacuQn6nB/ZNAIfTCIvmL5oKGa/TtCoBFA= gorm.io/datatypes v1.0.0/go.mod h1:aKpJ+RNhLXWeF5OAdxfzBwT1UPw1wseSchF0AY3/lSw= +gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg= gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= -gorm.io/driver/mysql v1.0.5 h1:WAAmvLK2rG0tCOqrf5XcLi2QUwugd4rcVJ/W3aoon9o= -gorm.io/driver/mysql v1.0.5/go.mod h1:N1OIhHAIhx5SunkMGqWbGFVeh4yTNWKmMo1GOAsohLI= +gorm.io/driver/postgres v1.0.5 h1:raX6ezL/ciUmaYTvOq48jq1GE95aMC0CmxQYbxQ4Ufw= gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= -gorm.io/driver/postgres v1.0.8 h1:PAgM+PaHOSAeroTjHkCHCBIHHoBIf9RgPWGo8dF2DA8= -gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc= gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= gorm.io/driver/sqlserver v1.0.5 h1:n5knSvyaEwufxl0aROEW90pn+aLoV9h+vahYJk1x5l4= @@ -1070,8 +1106,6 @@ gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.5/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.6 h1:xEFbH7WShsnAM+HeRNv7lOeyqmDAK+dDnf1AMf/cVPQ= gorm.io/gorm v1.21.6/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 4db5f52..d2853a8 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -10,6 +10,7 @@ import ( "encoding/pem" "fmt" "github.com/gosimple/slug" + "github.com/hyperledger/fabric-gateway/pkg/client" pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" @@ -508,15 +509,21 @@ type collectionConfigJson struct { } func (m mutationResolver) QueryChaincode(ctx context.Context, input models.QueryChaincodeInput) (*models.QueryChaincodeResponse, error) { - chContext := m.SDK.ChannelContext( - m.Channel, - fabsdk.WithOrg(m.Organization), - fabsdk.WithUser(m.User), - ) - chClient, err := channel.New(chContext) - if err != nil { - return nil, err - } + network := m.GWClient.GetNetwork(m.Channel) + contract := network.GetContract(input.ChaincodeName) + if contract == nil { + return nil, errors.Errorf("chaincode %s not found", input.ChaincodeName) + } + // + //chContext := m.SDK.ChannelContext( + // m.Channel, + // fabsdk.WithOrg(m.Organization), + // fabsdk.WithUser(m.User), + //) + //chClient, err := channel.New(chContext) + //if err != nil { + // return nil, err + //} var byteArgs [][]byte for _, arg := range input.Args { byteArgs = append(byteArgs, []byte(arg)) @@ -525,21 +532,30 @@ func (m mutationResolver) QueryChaincode(ctx context.Context, input models.Query for _, transient := range input.TransientMap { transientMap[transient.Key] = []byte(transient.Value) } - execReponse, err := chClient.Query( - channel.Request{ - ChaincodeID: input.ChaincodeName, - Fcn: input.Function, - Args: byteArgs, - TransientMap: transientMap, - InvocationChain: []*fab.ChaincodeCall{}, - IsInit: false, - }, + response, err := contract.Evaluate( + input.Function, + client.WithBytesArguments(byteArgs...), + client.WithTransient(transientMap), + client.WithEndorsingOrganizations("MEDIIOCHAINMSP"), ) if err != nil { return nil, err } + //execReponse, err := chClient.Query( + // channel.Request{ + // ChaincodeID: input.ChaincodeName, + // Fcn: input.Function, + // Args: byteArgs, + // TransientMap: transientMap, + // InvocationChain: []*fab.ChaincodeCall{}, + // IsInit: false, + // }, + //) + //if err != nil { + // return nil, err + //} return &models.QueryChaincodeResponse{ - Response: string(execReponse.Payload), - ChaincodeStatus: int(execReponse.ChaincodeStatus), + Response: string(response), + ChaincodeStatus: int(10), }, nil } diff --git a/gql/resolvers/resolvers.go b/gql/resolvers/resolvers.go index 1606a92..ac77ab7 100644 --- a/gql/resolvers/resolvers.go +++ b/gql/resolvers/resolvers.go @@ -3,6 +3,7 @@ package resolvers // THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. import ( + "github.com/hyperledger/fabric-gateway/pkg/client" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" @@ -12,6 +13,7 @@ import ( type Resolver struct { SDK *fabsdk.FabricSDK + GWClient *client.Gateway SDKContext context.ClientProvider SDKContextMap map[string]context.ClientProvider Channel string diff --git a/server/server.go b/server/server.go index 7ab5247..4007f63 100644 --- a/server/server.go +++ b/server/server.go @@ -7,6 +7,7 @@ import ( "github.com/99designs/gqlgen/graphql/handler/lru" "github.com/99designs/gqlgen/graphql/handler/transport" "github.com/99designs/gqlgen/graphql/playground" + "github.com/hyperledger/fabric-gateway/pkg/client" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" @@ -34,6 +35,7 @@ type BlockchainServerOpts struct { SDK *fabsdk.FabricSDK SDKContext context.ClientProvider SDKContextMap map[string]context.ClientProvider + GWClient *client.Gateway Channel string MSPClient *clientmsp.Client @@ -79,8 +81,9 @@ func (a *BlockchainAPIServer) setupHttpServer() http.Handler { MSPClient: a.MSPClient, CAConfig: a.CAConfig, SDKContextMap: a.SDKContextMap, - Organization: a.Organization, - User: a.User, + Organization: a.Organization, + User: a.User, + GWClient: a.GWClient, }, } es := gql.NewExecutableSchema(config) From 2abadaec28aee19d4fcd7a761af9b3a3c21598d4 Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Sun, 3 Apr 2022 21:42:18 +0200 Subject: [PATCH 16/20] use new getout version + listen cmd --- cmd/listen/listen.go | 115 ++++++++++++++++++++++++++++ cmd/root.go | 8 ++ cmd/serve/serve.go | 11 --- cmd/start/start.go | 95 ++++++++--------------- config/tunnel.go | 61 +++++++++++++++ go.mod | 10 +-- go.sum | 177 +++++-------------------------------------- 7 files changed, 236 insertions(+), 241 deletions(-) create mode 100644 cmd/listen/listen.go create mode 100644 config/tunnel.go diff --git a/cmd/listen/listen.go b/cmd/listen/listen.go new file mode 100644 index 0000000..f9940f0 --- /dev/null +++ b/cmd/listen/listen.go @@ -0,0 +1,115 @@ +package listen + +import ( + "fmt" + "github.com/kfsoftware/getout/pkg/tunnel" + "github.com/kfsoftware/hlf-cc-dev/config" + "github.com/kfsoftware/hlf-cc-dev/log" + "github.com/lithammer/shortuuid/v3" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "net" + "strings" + "time" +) + +type listenCmd struct { + forwardTo string + tunnelAddress string + tunnelSubdomain string +} + +const ( + listenDesc = "" + listenExample = "" +) + +func (c listenCmd) validate() error { + return nil +} + +func (c listenCmd) run() error { + hostname := strings.ToLower(shortuuid.New()[:10]) + var sni string + tunnelAddress := c.tunnelAddress + tunnelConfig, err := config.NewTunnelConfig() + if err != nil { + return err + } + //tunnelRequestsHost, tunnelRequestsPort, err := net.SplitHostPort(c.tunnelSubdomain) + //if err != nil { + // return err + //} + tunnelKey := fmt.Sprintf("%s_%s", c.forwardTo, c.tunnelAddress) + log.Debugf("tunnelKey: %s", tunnelKey) + cfgItem, err := tunnelConfig.Get(tunnelKey) + if err != nil { + sni = fmt.Sprintf("%s.%s", hostname, c.tunnelSubdomain) + _, err = tunnelConfig.Add(tunnelKey, config.TunnelConfigItem{ + ForwardTo: c.forwardTo, + SNI: sni, + }) + if err != nil { + return err + } + } else { + sni = cfgItem.SNI + } + sniReal, _, err := net.SplitHostPort(sni) + if err != nil { + return err + } + log.Infof("Forwarding %s to %s", sni, tunnelAddress) + for { + err := startTunnel( + tunnelAddress, + c.forwardTo, + sniReal, + ) + if err != nil { + log.Errorf("Error starting the tunnel: %s", err) + log.Infof("Retrying in 5 seconds...") + time.Sleep(5 * time.Second) + } + } + return nil +} + +func startTunnel(tunnelAddr string, localAddress string, sni string) error { + tunnelCli := tunnel.NewTunnelClient( + tunnelAddr, + ) + err := tunnelCli.StartTlsTunnel(sni, localAddress) + if err != nil { + return err + } + return nil +} + +func NewListenCmd() *cobra.Command { + c := &listenCmd{} + cmd := &cobra.Command{ + Use: "listen", + Short: "Listen for incoming connections", + Long: listenDesc, + Example: listenExample, + RunE: func(cmd *cobra.Command, args []string) error { + var err error + viper.AutomaticEnv() + err = viper.BindEnv("") + if err != nil { + return nil + } + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + if err := c.validate(); err != nil { + return err + } + return c.run() + }, + } + f := cmd.Flags() + f.StringVar(&c.tunnelAddress, "tunnel-addr", "", "Tunnel address to connect to") + f.StringVar(&c.forwardTo, "forward-to", "", "address of the local chaincode server, example: localhost:9999") + f.StringVar(&c.tunnelSubdomain, "tunnel-subdomain", "", "subdomain of the tunnel, example: cc.kfs.es") + return cmd +} diff --git a/cmd/root.go b/cmd/root.go index 777f2cb..2d588b9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -3,9 +3,13 @@ package cmd import ( "fmt" "github.com/kfsoftware/hlf-cc-dev/cmd/bootstrap" + "github.com/kfsoftware/hlf-cc-dev/cmd/listen" "github.com/kfsoftware/hlf-cc-dev/cmd/serve" "github.com/kfsoftware/hlf-cc-dev/cmd/start" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "os" + "time" "github.com/spf13/cobra" ) @@ -36,11 +40,15 @@ func Execute() { } func init() { + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339} + log.Logger = zerolog.New(output).With().Timestamp().Logger().Level(zerolog.InfoLevel) cobra.OnInitialize() rootCmd.AddCommand( start.NewStartCmd(), serve.NewServeCmd(), bootstrap.NewInitCmd(), + listen.NewListenCmd(), //server.NewServeCmd(), //dev.NewDevCmd(), //ci.NewCICmd(), diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index 6479245..457f043 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/pkg/msp" - "github.com/kfsoftware/hlf-cc-dev/log" "github.com/kfsoftware/hlf-cc-dev/server" _ "github.com/lib/pq" "github.com/pkg/errors" @@ -101,9 +100,7 @@ func getGatewayParams(serve *serveConfig, sdk *fabsdk.FabricSDK) (*GatewayParams return nil, err } adminCertPem, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.users.admin.cert.pem", serve.Fabric.Org)) - log.Infof("adminCertPem: %v", adminCertPem) adminCertKey, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.users.admin.key.pem", serve.Fabric.Org)) - log.Infof("adminCertKey: %v", adminCertKey) peersInt, _ := configBackend1.Lookup(fmt.Sprintf("organizations.%s.peers", serve.Fabric.Org)) peersArrayInterface := peersInt.([]interface{}) var peers []string @@ -119,8 +116,6 @@ func getGatewayParams(serve *serveConfig, sdk *fabsdk.FabricSDK) (*GatewayParams peerTLSCACertInt, _ := configBackend1.Lookup(peerTLSCACertKey) peerUrl = strings.Replace(peerUrlInt.(string), "grpcs://", "", -1) peerTLSCACert = []byte(peerTLSCACertInt.(string)) - //log.Infof("peerUrl: %v", peerUrl) - //log.Infof("peerTLSCACert: %v", peerTLSCACert) idx++ if idx >= 1 { break @@ -218,12 +213,6 @@ func (c *serveCmd) run(conf *serveConfig) error { if err != nil { return err } - //clientConn := getClientCollection() - //defer clientConn.Close() - //gwClient, err := getGateway(conf, clientConn) - //if err != nil { - // return err - //} opts := server.BlockchainServerOpts{ Address: c.address, MetricsAddress: c.metricsAddress, diff --git a/cmd/start/start.go b/cmd/start/start.go index 9457a79..b02ff36 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -7,18 +7,15 @@ import ( "encoding/base64" "encoding/pem" "fmt" - "github.com/hashicorp/yamux" - "github.com/kfsoftware/getout/pkg/tunnel" + "github.com/kfsoftware/hlf-cc-dev/config" "github.com/kfsoftware/hlf-cc-dev/gql/models" "github.com/kfsoftware/hlf-cc-dev/log" - "github.com/lithammer/shortuuid/v3" "github.com/pkg/errors" "github.com/shurcooL/graphql" "github.com/spf13/cobra" "github.com/spf13/viper" "io/ioutil" "k8s.io/client-go/util/homedir" - "net" "os" "path" "path/filepath" @@ -53,22 +50,20 @@ const ( ) type startCmd struct { - chaincode string - localChaincodeAddress string - tunnelAddress string - apiUrl string - pdcFile string - accessToken string - metaInf string - chaincodeAddress string - chaincodeAddressSubdomain string - signaturePolicy string - envFile string + chaincode string + localChaincodeAddress string + apiUrl string + pdcFile string + accessToken string + metaInf string + signaturePolicy string + envFile string + tunnelAddress string } func (c startCmd) validate() error { - if c.chaincodeAddress == "" && c.chaincodeAddressSubdomain == "" { - return errors.New("either --chaincode or --chaincodeAddressSubdomain are required") + if c.tunnelAddress == "" { + return errors.New("--tunnel-addr is required") } if c.signaturePolicy == "" { return errors.New("--signaturePolicy is required") @@ -76,9 +71,6 @@ func (c startCmd) validate() error { if c.chaincode == "" { return errors.New("--chaincode is required") } - if c.tunnelAddress == "" { - return errors.New("--tunnelAddress is required") - } if c.localChaincodeAddress == "" { return errors.New("--localChaincodeAddress is required") } @@ -124,11 +116,24 @@ func (c startCmd) run() error { } gqlClient := graphql.NewClient(c.apiUrl, nil) ctx := context.Background() - chaincodeAddress := c.chaincodeAddress - if c.chaincodeAddressSubdomain != "" { - chaincodeAddressPrefix := strings.ToLower(shortuuid.New()) - chaincodeAddress = fmt.Sprintf("%s.%s", chaincodeAddressPrefix, c.chaincodeAddressSubdomain) + tunnelConfig, err := config.NewTunnelConfig() + if err != nil { + return errors.Wrap(err, "failed to create tunnel config") } + tunnelKey := fmt.Sprintf("%s_%s", c.localChaincodeAddress, c.tunnelAddress) + log.Debugf("tunnelKey: %s", tunnelKey) + tunnelCFGItem, err := tunnelConfig.Get(tunnelKey) + if err != nil { + return errors.Wrapf(err, `failed to get tunnel config, run the following command +hlf-cc-dev listen --forward-to=%s --tunnel-addr="xxx:8082" +`, c.localChaincodeAddress) + } + + chaincodeAddress := tunnelCFGItem.SNI + //chaincodeAddress, _, err := net.SplitHostPort(fullChaincodeAddress) + //if err != nil { + // return errors.Wrapf(err, "failed to parse chaincode address %s", fullChaincodeAddress) + //} pdcContents := "" if c.pdcFile != "" { pdcContentsBytes, err := ioutil.ReadFile(c.pdcFile) @@ -202,7 +207,6 @@ func (c startCmd) run() error { if err != nil { return err } - log.Infof("Private key: %s", string(pkBytes)) chaincodeKeyPath := filepath.Join(p.CertsDir(c.chaincode), "chaincode.key") err = ioutil.WriteFile(chaincodeKeyPath, pkBytes, 0777) if err != nil { @@ -260,20 +264,7 @@ CORE_TLS_CLIENT_CERT_FILE=%s return err } } - sni, _, err := net.SplitHostPort(chaincodeAddress) - if err != nil { - return err - } log.Infof("Channel: %s Chaincode: %s", m.DeployChaincode.ChaincodeName, m.DeployChaincode.ChannelName) - log.Infof("starting tunnel from %s to %s", c.localChaincodeAddress, chaincodeAddress) - err = startTunnel( - c.tunnelAddress, - c.localChaincodeAddress, - sni, - ) - if err != nil { - return err - } return err } func EncodePrivateKey(key interface{}) ([]byte, error) { @@ -288,30 +279,6 @@ func EncodePrivateKey(key interface{}) ([]byte, error) { return pemPk, nil } -func startTunnel(tunnelAddr string, localAddress string, sni string) error { - conn, err := net.Dial("tcp", tunnelAddr) - if err != nil { - panic(err) - } - session, err := yamux.Client(conn, nil) - if err != nil { - panic(err) - } - tunnelCli := tunnel.NewTunnelClient( - session, - localAddress, - ) - err = tunnelCli.StartTlsTunnel(sni) - if err != nil { - return err - } - err = tunnelCli.Start() - if err != nil { - return err - } - return nil -} - func NewStartCmd() *cobra.Command { c := &startCmd{} cmd := &cobra.Command{ @@ -334,13 +301,11 @@ func NewStartCmd() *cobra.Command { }, } f := cmd.Flags() - f.StringVar(&c.chaincodeAddress, "chaincodeAddress", "", "chaincode address to be accessed by the peer(needs to be publicly accessible)") - f.StringVar(&c.chaincodeAddressSubdomain, "chaincodeAddressSubdomain", "", "subdomain to be used for chaincode address, in this case, the address is generated automatically .") f.StringVar(&c.chaincode, "chaincode", "", "chaincode name within the channel") f.StringVar(&c.localChaincodeAddress, "localChaincode", "", "address of the local chaincode server, example: localhost:9999") + f.StringVar(&c.tunnelAddress, "tunnel-addr", "", "remote tunnel address, example: localhost:9999") f.StringVar(&c.apiUrl, "apiUrl", "", "apiUrl to interact with the peers") f.StringVar(&c.pdcFile, "pdc", "", "pdc file json, see examples/pdc.json") - f.StringVar(&c.tunnelAddress, "tunnelAddress", "", "address of the local chaincode server, example: localhost:9999") f.StringVar(&c.accessToken, "accessToken", "", "access token") f.StringVar(&c.metaInf, "metaInf", "", "metadata") f.StringVar(&c.signaturePolicy, "signaturePolicy", "", "Signature policy") diff --git a/config/tunnel.go b/config/tunnel.go new file mode 100644 index 0000000..4ec019c --- /dev/null +++ b/config/tunnel.go @@ -0,0 +1,61 @@ +package config + +import ( + "crypto/sha256" + "encoding/json" + "fmt" + "github.com/shibukawa/configdir" +) + +type TunnelConfigItem struct { + SNI string + ForwardTo string + ExternalAddress string +} +type TunnelConfig struct { +} + +var ( + configDirs = configdir.New("kfs", "hlf-cc-dev") +) + +func NewTunnelConfig() (*TunnelConfig, error) { + return &TunnelConfig{}, nil +} +func (c *TunnelConfig) Get(host string) (*TunnelConfigItem, error) { + s256 := sha256.New() + s256.Write([]byte(host)) + hash := s256.Sum(nil) + hashHex := fmt.Sprintf("%x", hash) + filePath := fmt.Sprintf("tunnels/%s", hashHex) + folders := configDirs.QueryFolders(configdir.Global) + contentBytes, err := folders[0].ReadFile(filePath) + if err != nil { + return nil, err + } + item := &TunnelConfigItem{} + err = json.Unmarshal(contentBytes, &item) + if err != nil { + return nil, err + } + return item, nil +} + +func (c *TunnelConfig) Add(tunnelKey string, cfg TunnelConfigItem) (*TunnelConfig, error) { + s256 := sha256.New() + s256.Write([]byte(tunnelKey)) + hash := s256.Sum(nil) + hashHex := fmt.Sprintf("%x", hash) + filePath := fmt.Sprintf("tunnels/%s", hashHex) + folders := configDirs.QueryFolders(configdir.Global) + jsonBytes, err := json.Marshal(cfg) + if err != nil { + return nil, err + } + err = folders[0].WriteFile(filePath, jsonBytes) + if err != nil { + return nil, err + } + + return c, nil +} diff --git a/go.mod b/go.mod index f42320a..9c229c7 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/99designs/gqlgen v0.14.0 - github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae // indirect + github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gosimple/slug v1.12.0 github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 @@ -12,24 +12,22 @@ require ( github.com/hyperledger/fabric-gateway v1.0.1 github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f - github.com/kfsoftware/getout v0.0.4-beta2 + github.com/kfsoftware/getout v0.0.5-beta7 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 - github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.7.1 + github.com/rs/zerolog v1.26.1 + github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a github.com/sirupsen/logrus v1.8.1 github.com/slok/go-http-metrics v0.9.0 github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.7.0 github.com/vektah/gqlparser/v2 v2.2.0 - golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 // indirect google.golang.org/grpc v1.43.0 k8s.io/client-go v0.23.1 ) replace github.com/go-kit/kit => github.com/go-kit/kit v0.8.0 - -replace github.com/kfsoftware/getout => github.com/kfsoftware/getout v0.0.4-beta2 diff --git a/go.sum b/go.sum index c56e245..b3d64da 100644 --- a/go.sum +++ b/go.sum @@ -48,12 +48,10 @@ github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSY github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -109,16 +107,14 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= github.com/cucumber/godog v0.12.4/go.mod h1:u6SD7IXC49dLpPN35kal0oYEjsXZWee4pW6Tm9t5pIc= @@ -128,8 +124,6 @@ github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= -github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= @@ -155,11 +149,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= -github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -176,28 +167,18 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae h1:L6V0ANsMIMdLgXly241UXhXNFWYgXbgjHupTAAURrV0= -github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -329,76 +310,19 @@ github.com/hyperledger/fabric-gateway v1.0.1/go.mod h1:60RqgUVLHH3Jv4zgzgWFfoYLR github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324= github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200707132912-fee30f3ccd23/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20211118165945-23d738fc3553/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 h1:YV+siZuYQZwENjRH00t7ZS0CTlywt8Qog/SzL/jf6kE= github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-sdk-go v1.0.0 h1:NRu0iNbHV6u4nd9jgYghAdA1Ll4g0Sri4hwMEGiTbyg= -github.com/hyperledger/fabric-sdk-go v1.0.0/go.mod h1:qWE9Syfg1KbwNjtILk70bJLilnmCvllIYFCSY/pa1RU= github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f h1:SYduJmSWX/Q8fw8tiJK/VnRS+zyLCFXMcAIAAVjzSF0= github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f/go.mod h1:JRplpKBeAvXjsBhOCCM/KvMRUbdDyhsAh80qbXzKc10= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b h1:IpLPmn6Re21F0MaV6Zsc5RdSE6KuoFpWmHiUSEs3PrE= +github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b/go.mod h1:aA6DnFhALT3zH0y+A39we+zbrdMC2N0X/q21e6FI0LU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= -github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= -github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.7.0 h1:pwjzcYyfmz/HQOQlENvG1OcDqauTGaqlVahq934F0/U= -github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.5 h1:NUbEWPmCQZbMmYlTjVoNPhc0CfnYyz2bfUAh6A5ZVJM= -github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= -github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= -github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= -github.com/jackc/pgtype v1.5.0 h1:jzBqRk2HFG2CV4AIwgCI2PwTgm6UUoCAK2ofHHRirtc= -github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= -github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= -github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v4 v4.9.0 h1:6STjDqppM2ROy5p1wNDcsC7zJTjSHeuCsguZmXyzx7c= -github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= -github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -407,7 +331,6 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -416,15 +339,14 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= -github.com/kfsoftware/getout v0.0.4-beta2 h1:0PZhp24N4KyHEhVjayNcscSxith2PrBMSFE2o69TLmY= -github.com/kfsoftware/getout v0.0.4-beta2/go.mod h1:5V6Cp5Yf/CzycuKXJc5cnL6hmNx+evl1X7yHNL9gB2M= +github.com/kfsoftware/getout v0.0.5-beta7 h1:CIExhemI7MaqbbUscmtmjFOOMLo9f+GaLVmis82FX18= +github.com/kfsoftware/getout v0.0.5-beta7/go.mod h1:RErQGJm6Vp3n5zY3rH6Dw0hpmK+rZhicglID9khDtpE= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -433,26 +355,19 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -460,22 +375,14 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= -github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -496,11 +403,9 @@ github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxd github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -524,8 +429,6 @@ github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKw github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -540,7 +443,6 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= @@ -554,14 +456,12 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -573,19 +473,16 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/logger v1.2.0 h1:5WXfINRs3lEUTCZ7YXhj0uN+qukjizvITLm3Ca2m0Ho= -github.com/schollz/logger v1.2.0/go.mod h1:P6F4/dGMGcx8wh+kG1zrNEd4vnNpEBY/mwEMd/vn6AM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= @@ -593,7 +490,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -607,8 +503,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.1 h1:GPTpEAuNr98px18yNQ66JllNil98wfRZ/5Ukny8FeQA= -github.com/spf13/afero v1.3.1/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -628,9 +522,8 @@ github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -642,9 +535,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= @@ -663,7 +554,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= @@ -680,34 +571,25 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= goji.io v2.0.2+incompatible/go.mod h1:sbqFwrtqZACxLBTQcdgVjFh54yGVCvwq8+w49MVMMIk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8= -golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -785,6 +667,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -820,7 +703,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -828,9 +710,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -873,6 +753,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e h1:XMgFehsDnnLGtjvjOfqWSUzt0alpTR1RSEuznObga2c= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -901,7 +782,6 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -909,11 +789,8 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -951,8 +828,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1072,7 +948,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1092,22 +967,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.0.0 h1:5rDW3AnqXaacuQn6nB/ZNAIfTCIvmL5oKGa/TtCoBFA= -gorm.io/datatypes v1.0.0/go.mod h1:aKpJ+RNhLXWeF5OAdxfzBwT1UPw1wseSchF0AY3/lSw= -gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg= -gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= -gorm.io/driver/postgres v1.0.5 h1:raX6ezL/ciUmaYTvOq48jq1GE95aMC0CmxQYbxQ4Ufw= -gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= -gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc= -gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= -gorm.io/driver/sqlserver v1.0.5 h1:n5knSvyaEwufxl0aROEW90pn+aLoV9h+vahYJk1x5l4= -gorm.io/driver/sqlserver v1.0.5/go.mod h1:WI/bfZ+s9TigYXe3hb3XjNaUP0TqmTdXl11pECyLATs= -gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.5/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.6 h1:xEFbH7WShsnAM+HeRNv7lOeyqmDAK+dDnf1AMf/cVPQ= -gorm.io/gorm v1.21.6/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From f63520b7e382835db14a0a388ba89478218f1ab4 Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Mon, 4 Apr 2022 13:56:16 +0200 Subject: [PATCH 17/20] update --- cmd/generate-certs/generate-certs.go | 21 +++------------------ cmd/start/start.go | 6 +++--- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/cmd/generate-certs/generate-certs.go b/cmd/generate-certs/generate-certs.go index a6db4ed..e976893 100644 --- a/cmd/generate-certs/generate-certs.go +++ b/cmd/generate-certs/generate-certs.go @@ -2,10 +2,9 @@ package generate_certs import ( "context" - "github.com/hashicorp/yamux" + "github.com/kfsoftware/getout/pkg/tunnel" "github.com/kfsoftware/hlf-cc-dev/gql/models" "github.com/kfsoftware/hlf-cc-dev/log" - "github.com/kfsoftware/getout/pkg/tunnel" "github.com/pkg/errors" "github.com/shurcooL/graphql" "github.com/spf13/cobra" @@ -107,7 +106,6 @@ func (c startCmd) run() error { ctx := context.Background() input := models.DeployChaincodeInput{ Name: c.chaincode, - TenantID: c.tenant, ChaincodeAddress: c.chaincodeAddress, } var m struct { @@ -158,23 +156,10 @@ func (c startCmd) run() error { return err } func startTunnel(tunnelAddr string, localAddress string, sni string) error { - conn, err := net.Dial("tcp", tunnelAddr) - if err != nil { - panic(err) - } - session, err := yamux.Client(conn, nil) - if err != nil { - panic(err) - } tunnelCli := tunnel.NewTunnelClient( - session, - localAddress, + tunnelAddr, ) - err = tunnelCli.StartTlsTunnel(sni) - if err != nil { - return err - } - err = tunnelCli.Start() + err := tunnelCli.StartTlsTunnel(sni, localAddress) if err != nil { return err } diff --git a/cmd/start/start.go b/cmd/start/start.go index fbd3bfd..8636020 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -64,7 +64,7 @@ type startCmd struct { func (c startCmd) validate() error { if c.tunnelAddress == "" { - return errors.New("--tunnel-addr is required") + return errors.New("--tunnelAddress is required") } if c.signaturePolicy == "" { return errors.New("--signaturePolicy is required") @@ -126,7 +126,7 @@ func (c startCmd) run() error { tunnelCFGItem, err := tunnelConfig.Get(tunnelKey) if err != nil { return errors.Wrapf(err, `failed to get tunnel config, run the following command -hlf-cc-dev listen --forward-to=%s --tunnel-addr="xxx:8082" +hlf-cc-dev listen --forward-to=%s --tunnelAddress="xxx:8082" `, c.localChaincodeAddress) } @@ -306,7 +306,7 @@ func NewStartCmd() *cobra.Command { f := cmd.Flags() f.StringVar(&c.chaincode, "chaincode", "", "chaincode name within the channel") f.StringVar(&c.localChaincodeAddress, "localChaincode", "", "address of the local chaincode server, example: localhost:9999") - f.StringVar(&c.tunnelAddress, "tunnel-addr", "", "remote tunnel address, example: localhost:9999") + f.StringVar(&c.tunnelAddress, "tunnelAddress", "", "remote tunnel address, example: localhost:9999") f.StringVar(&c.apiUrl, "apiUrl", "", "apiUrl to interact with the peers") f.StringVar(&c.pdcFile, "pdc", "", "pdc file json, see examples/pdc.json") f.StringVar(&c.accessToken, "accessToken", "", "access token") From ef6a0feb1b7c49e8ca7d217bcb12fea633eb3f04 Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Tue, 5 Apr 2022 08:23:28 +0200 Subject: [PATCH 18/20] Update --- cmd/listen/listen.go | 9 ++++----- go.mod | 2 +- go.sum | 4 ++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cmd/listen/listen.go b/cmd/listen/listen.go index f9940f0..d15cbc6 100644 --- a/cmd/listen/listen.go +++ b/cmd/listen/listen.go @@ -29,21 +29,17 @@ func (c listenCmd) validate() error { } func (c listenCmd) run() error { - hostname := strings.ToLower(shortuuid.New()[:10]) var sni string tunnelAddress := c.tunnelAddress tunnelConfig, err := config.NewTunnelConfig() if err != nil { return err } - //tunnelRequestsHost, tunnelRequestsPort, err := net.SplitHostPort(c.tunnelSubdomain) - //if err != nil { - // return err - //} tunnelKey := fmt.Sprintf("%s_%s", c.forwardTo, c.tunnelAddress) log.Debugf("tunnelKey: %s", tunnelKey) cfgItem, err := tunnelConfig.Get(tunnelKey) if err != nil { + hostname := strings.ToLower(shortuuid.New()[:10]) sni = fmt.Sprintf("%s.%s", hostname, c.tunnelSubdomain) _, err = tunnelConfig.Add(tunnelKey, config.TunnelConfigItem{ ForwardTo: c.forwardTo, @@ -70,6 +66,9 @@ func (c listenCmd) run() error { log.Errorf("Error starting the tunnel: %s", err) log.Infof("Retrying in 5 seconds...") time.Sleep(5 * time.Second) + } else { + log.Infof("Tunnel closed") + break } } return nil diff --git a/go.mod b/go.mod index 9c229c7..29c650b 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hyperledger/fabric-gateway v1.0.1 github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f - github.com/kfsoftware/getout v0.0.5-beta7 + github.com/kfsoftware/getout v0.0.5-beta13 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mitchellh/mapstructure v1.4.1 // indirect diff --git a/go.sum b/go.sum index b3d64da..15e8f58 100644 --- a/go.sum +++ b/go.sum @@ -151,6 +151,7 @@ github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungG github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -171,6 +172,7 @@ github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvSc github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -339,6 +341,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= +github.com/kfsoftware/getout v0.0.5-beta13 h1:zWnQvGAUMhYmmfjKHleQLbTxa8wL07cGpZCbQ57/2zE= +github.com/kfsoftware/getout v0.0.5-beta13/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= github.com/kfsoftware/getout v0.0.5-beta7 h1:CIExhemI7MaqbbUscmtmjFOOMLo9f+GaLVmis82FX18= github.com/kfsoftware/getout v0.0.5-beta7/go.mod h1:RErQGJm6Vp3n5zY3rH6Dw0hpmK+rZhicglID9khDtpE= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= From fa254afc6e99beb461243af4fcdaea2c4745c43b Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Tue, 5 Apr 2022 13:13:35 +0200 Subject: [PATCH 19/20] Update tunnel dependency --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 29c650b..f54f86d 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hyperledger/fabric-gateway v1.0.1 github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f - github.com/kfsoftware/getout v0.0.5-beta13 + github.com/kfsoftware/getout v0.0.5-beta14 github.com/lib/pq v1.10.2 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mitchellh/mapstructure v1.4.1 // indirect diff --git a/go.sum b/go.sum index 15e8f58..58cbf52 100644 --- a/go.sum +++ b/go.sum @@ -341,8 +341,10 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= +github.com/kfsoftware/getout v0.0.1-beta14/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= github.com/kfsoftware/getout v0.0.5-beta13 h1:zWnQvGAUMhYmmfjKHleQLbTxa8wL07cGpZCbQ57/2zE= github.com/kfsoftware/getout v0.0.5-beta13/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= +github.com/kfsoftware/getout v0.0.5-beta14/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= github.com/kfsoftware/getout v0.0.5-beta7 h1:CIExhemI7MaqbbUscmtmjFOOMLo9f+GaLVmis82FX18= github.com/kfsoftware/getout v0.0.5-beta7/go.mod h1:RErQGJm6Vp3n5zY3rH6Dw0hpmK+rZhicglID9khDtpE= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= From daad6656d5af88633dcad369cb57aa0464f03e13 Mon Sep 17 00:00:00 2001 From: dviejokfs Date: Thu, 14 Apr 2022 08:50:44 +0200 Subject: [PATCH 20/20] Allow different channels for deploying the chaincode & use gateway --- cmd/generate-certs/generate-certs.go | 201 ------- cmd/serve/serve.go | 7 +- go.mod | 6 +- go.sum | 47 +- gql/federation.go | 5 + gql/generated.go | 787 ++++++++++++++++++++++----- gql/models/models.go | 3 + gql/resolvers/mutation.go | 95 ++-- schema/mutation.graphql | 3 + 9 files changed, 742 insertions(+), 412 deletions(-) delete mode 100644 cmd/generate-certs/generate-certs.go diff --git a/cmd/generate-certs/generate-certs.go b/cmd/generate-certs/generate-certs.go deleted file mode 100644 index e976893..0000000 --- a/cmd/generate-certs/generate-certs.go +++ /dev/null @@ -1,201 +0,0 @@ -package generate_certs - -import ( - "context" - "github.com/kfsoftware/getout/pkg/tunnel" - "github.com/kfsoftware/hlf-cc-dev/gql/models" - "github.com/kfsoftware/hlf-cc-dev/log" - "github.com/pkg/errors" - "github.com/shurcooL/graphql" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "io/ioutil" - "k8s.io/client-go/util/homedir" - "net" - "os" - "path/filepath" - "strings" -) - -type Paths struct { - base string - tmp string -} - -func mustGetHLFCCPaths() Paths { - base := filepath.Join(homedir.HomeDir(), ".hlf-cc") - if fromEnv := os.Getenv("HLF_CC_ROOT"); fromEnv != "" { - base = fromEnv - log.Infof("using environment override HLF_CC_ROOT=%s", fromEnv) - } - base, err := filepath.Abs(base) - if err != nil { - panic(errors.Wrap(err, "cannot get absolute path")) - } - return Paths{base: base, tmp: os.TempDir()} -} - -func (p Paths) CertsDir(chaincode string) string { - return filepath.Join(p.base, "certs", chaincode) -} - -const ( - startDesc = `` - startExample = `` -) - -type startCmd struct { - tenant int - chaincode string - localChaincodeAddress string - tunnelAddress string - apiUrl string - pdcFile string - accessToken string - metaInf string - chaincodeAddress string -} - -func (c startCmd) validate() error { - if c.tenant == 0 { - return errors.New("--tenant is required") - } - if c.chaincodeAddress == "" { - return errors.New("--chaincode is required") - } - if c.chaincode == "" { - return errors.New("--chaincode is required") - } - if c.tunnelAddress == "" { - return errors.New("--tunnelAddress is required") - } - if c.localChaincodeAddress == "" { - return errors.New("--localChaincodeAddress is required") - } - if c.apiUrl == "" { - return errors.New("--apiUrl is required") - } - if c.metaInf != "" { - if _, err := os.Stat(c.metaInf); os.IsNotExist(err) { - return err - } - } - - return nil -} -func ensureDirs(paths ...string) error { - for _, p := range paths { - log.Infof("Ensure creating dir: %q", p) - if err := os.MkdirAll(p, 0755); err != nil { - return errors.Wrapf(err, "failed to ensure create directory %q", p) - } - } - return nil -} -func (c startCmd) run() error { - var err error - p := mustGetHLFCCPaths() - err = ensureDirs( - p.CertsDir(c.chaincode), - ) - if err != nil { - return err - } - - gqlClient := graphql.NewClient(c.apiUrl, nil) - ctx := context.Background() - input := models.DeployChaincodeInput{ - Name: c.chaincode, - ChaincodeAddress: c.chaincodeAddress, - } - var m struct { - DeployChaincode struct { - ChaincodeName string `graphql:"chaincodeName"` - PackageID string `graphql:"packageID"` - Version string `graphql:"version"` - Sequence int `graphql:"sequence"` - PrivateKey string `graphql:"privateKey"` - Certificate string `graphql:"certificate"` - RootCertificate string `graphql:"rootCertificate"` - } `graphql:"deployChaincode(input: $input)"` - } - vars := map[string]interface{}{ - "input": input, - } - err = gqlClient.Mutate(ctx, &m, vars) - if err != nil { - return err - } - chaincodeKeyPath := filepath.Join(p.CertsDir(c.chaincode), "chaincode.key") - err = ioutil.WriteFile(chaincodeKeyPath, []byte(m.DeployChaincode.PrivateKey), 0777) - if err != nil { - return err - } - chaincodeCertPath := filepath.Join(p.CertsDir(c.chaincode), "chaincode.pem") - err = ioutil.WriteFile(chaincodeCertPath, []byte(m.DeployChaincode.Certificate), 0777) - if err != nil { - return err - } - caCertPath := filepath.Join(p.CertsDir(c.chaincode), "ca.pem") - err = ioutil.WriteFile(caCertPath, []byte(m.DeployChaincode.RootCertificate), 0777) - if err != nil { - return err - } - sni, _, err := net.SplitHostPort(c.chaincodeAddress) - if err != nil { - return err - } - err = startTunnel( - c.tunnelAddress, - c.localChaincodeAddress, - sni, - ) - if err != nil { - return err - } - return err -} -func startTunnel(tunnelAddr string, localAddress string, sni string) error { - tunnelCli := tunnel.NewTunnelClient( - tunnelAddr, - ) - err := tunnelCli.StartTlsTunnel(sni, localAddress) - if err != nil { - return err - } - return nil -} - -func NewStartCmd() *cobra.Command { - c := &startCmd{} - cmd := &cobra.Command{ - Use: "start", - Short: "Start development for chaincode", - Long: startDesc, - Example: startExample, - RunE: func(cmd *cobra.Command, args []string) error { - var err error - viper.AutomaticEnv() - err = viper.BindEnv("") - if err != nil { - return nil - } - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - if err := c.validate(); err != nil { - return err - } - return c.run() - }, - } - f := cmd.Flags() - f.StringVar(&c.chaincodeAddress, "chaincodeAddress", "", "chaincode address to be accessed by the peer(needs to be publicly accessible)") - f.IntVar(&c.tenant, "tenant", 0, "tenant id") - f.StringVar(&c.chaincode, "chaincode", "", "chaincode name within the channel") - f.StringVar(&c.localChaincodeAddress, "localChaincode", "", "address of the local chaincode server, example: localhost:9999") - f.StringVar(&c.apiUrl, "apiUrl", "", "apiUrl to interact with the peers") - f.StringVar(&c.pdcFile, "pdc", "", "pdc file json, see examples/pdc.json") - f.StringVar(&c.tunnelAddress, "tunnelAddress", "", "address of the local chaincode server, example: localhost:9999") - f.StringVar(&c.accessToken, "accessToken", "", "access token") - f.StringVar(&c.metaInf, "metaInf", "", "metadata") - return cmd -} diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index 457f043..0fc05e5 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -143,7 +143,6 @@ func (c *serveCmd) run(conf *serveConfig) error { fabsdk.WithUser(conf.Fabric.User), fabsdk.WithOrg(conf.Fabric.Org), ) - embeddedBackend, err := configBackend() if err != nil { return err @@ -239,12 +238,12 @@ type GatewayParams struct { mspID string } -func newIdentity(certificatePEM []byte) (*identity.X509Identity, error) { +func newIdentity(mspId string, certificatePEM []byte) (*identity.X509Identity, error) { cert, err := identity.CertificateFromPEM(certificatePEM) if err != nil { return nil, err } - id, err := identity.NewX509Identity("MEDIIOCHAINMSP", cert) + id, err := identity.NewX509Identity(mspId, cert) if err != nil { return nil, err } @@ -286,7 +285,7 @@ func newGrpcConnection(peerEndpoint string, tlsCert []byte) (*grpc.ClientConn, e } func getGateway(params GatewayParams, clientConnection *grpc.ClientConn) (*client.Gateway, error) { - id, err := newIdentity([]byte(params.adminCert)) + id, err := newIdentity(params.mspID, []byte(params.adminCert)) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index f54f86d..cb7f8b7 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/kfsoftware/hlf-cc-dev go 1.16 require ( - github.com/99designs/gqlgen v0.14.0 + github.com/99designs/gqlgen v0.17.1 github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gosimple/slug v1.12.0 - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/hyperledger/fabric-config v0.1.0 github.com/hyperledger/fabric-gateway v1.0.1 github.com/hyperledger/fabric-protos-go v0.0.0-20220315113721-7dc293e117f7 @@ -25,7 +25,7 @@ require ( github.com/slok/go-http-metrics v0.9.0 github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.7.0 - github.com/vektah/gqlparser/v2 v2.2.0 + github.com/vektah/gqlparser/v2 v2.4.0 google.golang.org/grpc v1.43.0 k8s.io/client-go v0.23.1 ) diff --git a/go.sum b/go.sum index 58cbf52..1137aa9 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/gqlgen v0.14.0 h1:Wg8aNYQUjMR/4v+W3xD+7SizOy6lSvVeQ06AobNQAXI= -github.com/99designs/gqlgen v0.14.0/go.mod h1:S7z4boV+Nx4VvzMUpVrY/YuHjFX4n7rDyuTqvAkuoRE= +github.com/99designs/gqlgen v0.17.1 h1:i2qQMPKHQjHgBWYIpO4TsaQpPqMHCPK1+h95ipvH8VU= +github.com/99designs/gqlgen v0.17.1/go.mod h1:K5fzLKwtph+FFgh9j7nFbRUdBKvTcGnsta51fsMTn3o= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= @@ -115,6 +115,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= github.com/cucumber/godog v0.12.4/go.mod h1:u6SD7IXC49dLpPN35kal0oYEjsXZWee4pW6Tm9t5pIc= @@ -260,8 +261,6 @@ github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2c github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -320,7 +319,6 @@ github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220124135247-4f34271d9b0f/go.mod github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b h1:IpLPmn6Re21F0MaV6Zsc5RdSE6KuoFpWmHiUSEs3PrE= github.com/inconshreveable/go-vhost v0.0.0-20160627193104-06d84117953b/go.mod h1:aA6DnFhALT3zH0y+A39we+zbrdMC2N0X/q21e6FI0LU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -341,12 +339,9 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= -github.com/kfsoftware/getout v0.0.1-beta14/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= -github.com/kfsoftware/getout v0.0.5-beta13 h1:zWnQvGAUMhYmmfjKHleQLbTxa8wL07cGpZCbQ57/2zE= -github.com/kfsoftware/getout v0.0.5-beta13/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= +github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= +github.com/kfsoftware/getout v0.0.5-beta14 h1:VWFYc15UGlyvSr1r/yZUoLomuWcre3yGhmG9pjD1RV8= github.com/kfsoftware/getout v0.0.5-beta14/go.mod h1:/qoSgBQ5RC//wbmf3VsmAScPSHWMVo8SKFV/Mtvd5Qg= -github.com/kfsoftware/getout v0.0.5-beta7 h1:CIExhemI7MaqbbUscmtmjFOOMLo9f+GaLVmis82FX18= -github.com/kfsoftware/getout v0.0.5-beta7/go.mod h1:RErQGJm6Vp3n5zY3rH6Dw0hpmK+rZhicglID9khDtpE= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -373,13 +368,13 @@ github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -402,8 +397,8 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -431,8 +426,6 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= @@ -478,11 +471,11 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= @@ -491,9 +484,7 @@ github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1 github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -530,7 +521,6 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -543,14 +533,13 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= -github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= -github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/vektah/gqlparser/v2 v2.4.0 h1:EmA4dw9mqHm0j6Xzb9T21hOrp3oXmxnS40vwki70DZU= +github.com/vektah/gqlparser/v2 v2.4.0/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= github.com/weppos/publicsuffix-go v0.5.0 h1:rutRtjBJViU/YjcI5d80t4JAVvDltS6bciJg2K1HrLU= github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= @@ -561,6 +550,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= @@ -630,6 +620,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -674,6 +665,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -760,8 +752,9 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e h1:XMgFehsDnnLGtjvjOfqWSUzt0alpTR1RSEuznObga2c= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -781,7 +774,6 @@ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -789,7 +781,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -824,6 +815,7 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -835,6 +827,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -998,5 +991,3 @@ sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNza sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= diff --git a/gql/federation.go b/gql/federation.go index 6264d48..53388d8 100644 --- a/gql/federation.go +++ b/gql/federation.go @@ -10,6 +10,11 @@ import ( "github.com/99designs/gqlgen/plugin/federation/fedruntime" ) +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { if ec.DisableIntrospection { return fedruntime.Service{}, errors.New("federated introspection disabled") diff --git a/gql/generated.go b/gql/generated.go index 3ef84a2..f1cacfb 100644 --- a/gql/generated.go +++ b/gql/generated.go @@ -8,9 +8,11 @@ import ( "errors" "strconv" "sync" + "sync/atomic" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" "github.com/kfsoftware/hlf-cc-dev/gql/models" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" @@ -72,8 +74,9 @@ type ComplexityRoot struct { } Query struct { - Chaincode func(childComplexity int, name string) int - Chaincodes func(childComplexity int) int + Chaincode func(childComplexity int, name string) int + Chaincodes func(childComplexity int) int + __resolve__service func(childComplexity int) int } QueryChaincodeResponse struct { @@ -86,6 +89,10 @@ type ComplexityRoot struct { MspID func(childComplexity int) int Name func(childComplexity int) int } + + _Service struct { + SDL func(childComplexity int) int + } } type MutationResolver interface { @@ -266,6 +273,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Chaincodes(childComplexity), true + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + case "QueryChaincodeResponse.chaincodeStatus": if e.complexity.QueryChaincodeResponse.ChaincodeStatus == nil { break @@ -301,6 +315,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Tenant.Name(childComplexity), true + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + } return 0, false } @@ -374,6 +395,7 @@ var sources = []*ast.Source{ } input QueryChaincodeInput { + channel: String chaincodeName: String! function: String! args: [String!] @@ -386,6 +408,7 @@ type QueryChaincodeResponse { } input InvokeChaincodeInput { + channel: String chaincodeName: String! function: String! args: [String!] @@ -432,6 +455,7 @@ input DeployChaincodeInput { chaincodeAddress: String! signaturePolicy: String! indexes: [CouchDBIndex!] + channel: String! } input CouchDBIndex { id: String! @@ -467,8 +491,17 @@ scalar _FieldSet directive @external on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) on OBJECT | INTERFACE -directive @extends on OBJECT +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE +`, BuiltIn: true}, + {Name: "federation/entity.graphql", Input: ` +type _Service { + sdl: String +} + +extend type Query { + _service: _Service! +} `, BuiltIn: true}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) @@ -1277,6 +1310,41 @@ func (ec *executionContext) _Query_chaincode(ctx context.Context, field graphql. return ec.marshalOChaincode2ᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐChaincode(ctx, field.Selections, res) } +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1523,6 +1591,38 @@ func (ec *executionContext) _Tenant_mspId(ctx context.Context, field graphql.Col return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "_Service", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1569,14 +1669,14 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field Object: "__Directive", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, IsResolver: false, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Description, nil + return obj.Description(), nil }) if err != nil { ec.Error(ctx, err) @@ -1585,9 +1685,9 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field if resTmp == nil { return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalOString2string(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { @@ -1741,14 +1841,14 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field Object: "__EnumValue", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, IsResolver: false, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Description, nil + return obj.Description(), nil }) if err != nil { ec.Error(ctx, err) @@ -1757,9 +1857,9 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field if resTmp == nil { return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalOString2string(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { @@ -1875,14 +1975,14 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap Object: "__Field", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, IsResolver: false, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Description, nil + return obj.Description(), nil }) if err != nil { ec.Error(ctx, err) @@ -1891,9 +1991,9 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap if resTmp == nil { return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalOString2string(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { @@ -2079,14 +2179,14 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field Object: "__InputValue", Field: field, Args: nil, - IsMethod: false, + IsMethod: true, IsResolver: false, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Description, nil + return obj.Description(), nil }) if err != nil { ec.Error(ctx, err) @@ -2095,9 +2195,9 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field if resTmp == nil { return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalOString2string(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { @@ -2167,6 +2267,38 @@ func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, fiel return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2430,9 +2562,9 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph if resTmp == nil { return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalOString2string(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { @@ -2641,6 +2773,38 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + // endregion **************************** field.gotpl ***************************** // region **************************** input.gotpl ***************************** @@ -2756,6 +2920,14 @@ func (ec *executionContext) unmarshalInputDeployChaincodeInput(ctx context.Conte if err != nil { return it, err } + case "channel": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("channel")) + it.Channel, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } } } @@ -2771,6 +2943,14 @@ func (ec *executionContext) unmarshalInputInvokeChaincodeInput(ctx context.Conte for k, v := range asMap { switch k { + case "channel": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("channel")) + it.Channel, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } case "chaincodeName": var err error @@ -2849,6 +3029,14 @@ func (ec *executionContext) unmarshalInputQueryChaincodeInput(ctx context.Contex for k, v := range asMap { switch k { + case "channel": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("channel")) + it.Channel, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } case "chaincodeName": var err error @@ -2930,7 +3118,6 @@ var chaincodeImplementors = []string{"Chaincode"} func (ec *executionContext) _Chaincode(ctx context.Context, sel ast.SelectionSet, obj *models.Chaincode) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, chaincodeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2938,17 +3125,32 @@ func (ec *executionContext) _Chaincode(ctx context.Context, sel ast.SelectionSet case "__typename": out.Values[i] = graphql.MarshalString("Chaincode") case "name": - out.Values[i] = ec._Chaincode_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Chaincode_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "version": - out.Values[i] = ec._Chaincode_version(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Chaincode_version(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "sequence": - out.Values[i] = ec._Chaincode_sequence(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Chaincode_sequence(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2967,7 +3169,6 @@ var deployChaincodeResponseImplementors = []string{"DeployChaincodeResponse"} func (ec *executionContext) _DeployChaincodeResponse(ctx context.Context, sel ast.SelectionSet, obj *models.DeployChaincodeResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, deployChaincodeResponseImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2975,42 +3176,82 @@ func (ec *executionContext) _DeployChaincodeResponse(ctx context.Context, sel as case "__typename": out.Values[i] = graphql.MarshalString("DeployChaincodeResponse") case "packageID": - out.Values[i] = ec._DeployChaincodeResponse_packageID(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_packageID(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "version": - out.Values[i] = ec._DeployChaincodeResponse_version(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_version(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "sequence": - out.Values[i] = ec._DeployChaincodeResponse_sequence(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_sequence(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "chaincodeName": - out.Values[i] = ec._DeployChaincodeResponse_chaincodeName(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_chaincodeName(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "privateKey": - out.Values[i] = ec._DeployChaincodeResponse_privateKey(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_privateKey(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "certificate": - out.Values[i] = ec._DeployChaincodeResponse_certificate(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_certificate(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "rootCertificate": - out.Values[i] = ec._DeployChaincodeResponse_rootCertificate(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_rootCertificate(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "channelName": - out.Values[i] = ec._DeployChaincodeResponse_channelName(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DeployChaincodeResponse_channelName(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3029,7 +3270,6 @@ var invokeChaincodeResponseImplementors = []string{"InvokeChaincodeResponse"} func (ec *executionContext) _InvokeChaincodeResponse(ctx context.Context, sel ast.SelectionSet, obj *models.InvokeChaincodeResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, invokeChaincodeResponseImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3037,17 +3277,32 @@ func (ec *executionContext) _InvokeChaincodeResponse(ctx context.Context, sel as case "__typename": out.Values[i] = graphql.MarshalString("InvokeChaincodeResponse") case "response": - out.Values[i] = ec._InvokeChaincodeResponse_response(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InvokeChaincodeResponse_response(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "transactionID": - out.Values[i] = ec._InvokeChaincodeResponse_transactionID(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InvokeChaincodeResponse_transactionID(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "chaincodeStatus": - out.Values[i] = ec._InvokeChaincodeResponse_chaincodeStatus(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InvokeChaincodeResponse_chaincodeStatus(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3066,7 +3321,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -3074,21 +3328,41 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "deployChaincode": - out.Values[i] = ec._Mutation_deployChaincode(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deployChaincode(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "invokeChaincode": - out.Values[i] = ec._Mutation_invokeChaincode(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_invokeChaincode(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "queryChaincode": - out.Values[i] = ec._Mutation_queryChaincode(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_queryChaincode(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -3107,7 +3381,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -3115,12 +3388,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "chaincodes": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3128,10 +3407,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_chaincodes(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "chaincode": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3139,11 +3427,52 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_chaincode(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "_service": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3159,7 +3488,6 @@ var queryChaincodeResponseImplementors = []string{"QueryChaincodeResponse"} func (ec *executionContext) _QueryChaincodeResponse(ctx context.Context, sel ast.SelectionSet, obj *models.QueryChaincodeResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryChaincodeResponseImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3167,12 +3495,22 @@ func (ec *executionContext) _QueryChaincodeResponse(ctx context.Context, sel ast case "__typename": out.Values[i] = graphql.MarshalString("QueryChaincodeResponse") case "response": - out.Values[i] = ec._QueryChaincodeResponse_response(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._QueryChaincodeResponse_response(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "chaincodeStatus": - out.Values[i] = ec._QueryChaincodeResponse_chaincodeStatus(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._QueryChaincodeResponse_chaincodeStatus(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3191,7 +3529,6 @@ var tenantImplementors = []string{"Tenant"} func (ec *executionContext) _Tenant(ctx context.Context, sel ast.SelectionSet, obj *models.Tenant) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, tenantImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3199,17 +3536,32 @@ func (ec *executionContext) _Tenant(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Tenant") case "id": - out.Values[i] = ec._Tenant_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Tenant_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec._Tenant_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Tenant_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mspId": - out.Values[i] = ec._Tenant_mspId(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Tenant_mspId(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3224,11 +3576,38 @@ func (ec *executionContext) _Tenant(ctx context.Context, sel ast.SelectionSet, o return out } +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.__Service_sdl(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3236,24 +3615,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3272,7 +3676,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3280,19 +3683,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3308,7 +3731,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3316,29 +3738,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3354,7 +3806,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3362,19 +3813,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3390,29 +3861,60 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Schema") + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3431,7 +3933,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3439,26 +3940,78 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "specifiedByURL": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_specifiedByURL(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3616,6 +4169,10 @@ func (ec *executionContext) marshalN_FieldSet2string(ctx context.Context, sel as return res } +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { return ec.___Directive(ctx, sel, &v) } @@ -3682,11 +4239,7 @@ func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Conte func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { var vSlice []interface{} if v != nil { - if tmp1, ok := v.([]interface{}); ok { - vSlice = tmp1 - } else { - vSlice = []interface{}{v} - } + vSlice = graphql.CoerceList(v) } var err error res := make([]string, len(vSlice)) @@ -3879,7 +4432,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3894,7 +4448,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOChaincode2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐChaincodeᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.Chaincode) graphql.Marshaler { @@ -3957,11 +4512,7 @@ func (ec *executionContext) unmarshalOCouchDBIndex2ᚕᚖgithubᚗcomᚋkfsoftwa } var vSlice []interface{} if v != nil { - if tmp1, ok := v.([]interface{}); ok { - vSlice = tmp1 - } else { - vSlice = []interface{}{v} - } + vSlice = graphql.CoerceList(v) } var err error res := make([]*models.CouchDBIndex, len(vSlice)) @@ -3981,11 +4532,7 @@ func (ec *executionContext) unmarshalOOrgInput2ᚕᚖgithubᚗcomᚋkfsoftware } var vSlice []interface{} if v != nil { - if tmp1, ok := v.([]interface{}); ok { - vSlice = tmp1 - } else { - vSlice = []interface{}{v} - } + vSlice = graphql.CoerceList(v) } var err error res := make([]*models.OrgInput, len(vSlice)) @@ -4005,7 +4552,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { @@ -4014,11 +4562,7 @@ func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v } var vSlice []interface{} if v != nil { - if tmp1, ok := v.([]interface{}); ok { - vSlice = tmp1 - } else { - vSlice = []interface{}{v} - } + vSlice = graphql.CoerceList(v) } var err error res := make([]string, len(vSlice)) @@ -4062,7 +4606,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) unmarshalOTransientArgument2ᚕᚖgithubᚗcomᚋkfsoftwareᚋhlfᚑccᚑdevᚋgqlᚋmodelsᚐTransientArgumentᚄ(ctx context.Context, v interface{}) ([]*models.TransientArgument, error) { @@ -4071,11 +4616,7 @@ func (ec *executionContext) unmarshalOTransientArgument2ᚕᚖgithubᚗcomᚋkfs } var vSlice []interface{} if v != nil { - if tmp1, ok := v.([]interface{}); ok { - vSlice = tmp1 - } else { - vSlice = []interface{}{v} - } + vSlice = graphql.CoerceList(v) } var err error res := make([]*models.TransientArgument, len(vSlice)) diff --git a/gql/models/models.go b/gql/models/models.go index 223bfb0..c3cb6aa 100644 --- a/gql/models/models.go +++ b/gql/models/models.go @@ -24,6 +24,7 @@ type DeployChaincodeInput struct { ChaincodeAddress string `json:"chaincodeAddress"` SignaturePolicy string `json:"signaturePolicy"` Indexes []*CouchDBIndex `json:"indexes"` + Channel string `json:"channel"` } type DeployChaincodeResponse struct { @@ -38,6 +39,7 @@ type DeployChaincodeResponse struct { } type InvokeChaincodeInput struct { + Channel *string `json:"channel"` ChaincodeName string `json:"chaincodeName"` Function string `json:"function"` Args []string `json:"args"` @@ -56,6 +58,7 @@ type OrgInput struct { } type QueryChaincodeInput struct { + Channel *string `json:"channel"` ChaincodeName string `json:"chaincodeName"` Function string `json:"function"` Args []string `json:"args"` diff --git a/gql/resolvers/mutation.go b/gql/resolvers/mutation.go index 044b8a1..21f38aa 100644 --- a/gql/resolvers/mutation.go +++ b/gql/resolvers/mutation.go @@ -12,12 +12,10 @@ import ( "github.com/gosimple/slug" "github.com/hyperledger/fabric-gateway/pkg/client" pb "github.com/hyperledger/fabric-protos-go/peer" - "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" clientmsp "github.com/hyperledger/fabric-sdk-go/pkg/client/msp" "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle" - "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" "github.com/kfsoftware/hlf-cc-dev/gql/models" "github.com/kfsoftware/hlf-cc-dev/log" @@ -83,7 +81,15 @@ func getChaincodePackage(label string, codeTarGz []byte) ([]byte, error) { if err != nil { return nil, err } - + err = tw.Close() + if err != nil { + return nil, err + } + err = gw.Close() + if err != nil { + log.Warnf("gzip.Writer.Close() failed: %s", err) + return nil, err + } return buf.Bytes(), nil } @@ -233,7 +239,11 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl if err != nil { return nil, err } - committedCCs, err := resClient.LifecycleQueryCommittedCC(m.Channel, resmgmt.LifecycleQueryCommittedCCRequest{Name: chaincodeName}) + channel := m.Channel + if input.Channel != "" { + channel = input.Channel + } + committedCCs, err := resClient.LifecycleQueryCommittedCC(channel, resmgmt.LifecycleQueryCommittedCCRequest{Name: chaincodeName}) if err != nil { log.Warnf("Error when getting commited chaincodes: %v", err) } @@ -285,7 +295,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl return } txID, err := resClient.LifecycleApproveCC( - m.Channel, + channel, approveCCRequest, resmgmt.WithTargetFilter(&mspFilter{mspID: mspID}), ) @@ -297,7 +307,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl }() } wg.Wait() - commitReadiness, err := resClient.LifecycleCheckCCCommitReadiness(m.Channel, + commitReadiness, err := resClient.LifecycleCheckCCCommitReadiness(channel, resmgmt.LifecycleCheckCCCommitReadinessRequest{ Name: chaincodeName, Version: version, @@ -313,7 +323,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl } log.Infof("Chaincode %s readiness= %v", chaincodeName, commitReadiness) txID, err := resClient.LifecycleCommitCC( - m.Channel, + channel, resmgmt.LifecycleCommitCCRequest{ Name: chaincodeName, Version: version, @@ -332,7 +342,7 @@ func (m mutationResolver) DeployChaincode(ctx context.Context, input models.Depl } log.Infof("Chaincode %s committed= %s", chaincodeName, txID) return &models.DeployChaincodeResponse{ - ChannelName: m.Channel, + ChannelName: channel, PackageID: packageID, Version: version, Sequence: sequence, @@ -365,14 +375,14 @@ func ParseX509Certificate(contents []byte) (*x509.Certificate, error) { } func (m mutationResolver) InvokeChaincode(ctx context.Context, input models.InvokeChaincodeInput) (*models.InvokeChaincodeResponse, error) { - chContext := m.SDK.ChannelContext( - m.Channel, - fabsdk.WithOrg(m.Organization), - fabsdk.WithUser(m.User), - ) - chClient, err := channel.New(chContext) - if err != nil { - return nil, err + ch := m.Channel + if input.Channel != nil && *input.Channel != "" { + ch = *input.Channel + } + network := m.GWClient.GetNetwork(ch) + contract := network.GetContract(input.ChaincodeName) + if contract == nil { + return nil, errors.Errorf("chaincode %s not found", input.ChaincodeName) } var byteArgs [][]byte for _, arg := range input.Args { @@ -383,23 +393,22 @@ func (m mutationResolver) InvokeChaincode(ctx context.Context, input models.Invo for _, transient := range input.TransientMap { transientMap[transient.Key] = []byte(transient.Value) } - execReponse, err := chClient.Execute( - channel.Request{ - ChaincodeID: input.ChaincodeName, - Fcn: input.Function, - Args: byteArgs, - TransientMap: transientMap, - InvocationChain: []*fab.ChaincodeCall{}, - IsInit: false, - }, + result, commit, err := contract.SubmitAsync( + input.Function, + client.WithBytesArguments(byteArgs...), + client.WithTransient(transientMap), ) if err != nil { return nil, err } + status, err := commit.Status() + if err != nil { + return nil, err + } return &models.InvokeChaincodeResponse{ - Response: string(execReponse.Payload), - ChaincodeStatus: int(execReponse.ChaincodeStatus), - TransactionID: string(execReponse.TransactionID), + Response: string(result), + ChaincodeStatus: int(status.Code), + TransactionID: status.TransactionID, }, nil } @@ -519,21 +528,15 @@ type collectionConfigJson struct { } func (m mutationResolver) QueryChaincode(ctx context.Context, input models.QueryChaincodeInput) (*models.QueryChaincodeResponse, error) { - network := m.GWClient.GetNetwork(m.Channel) + ch := m.Channel + if input.Channel != nil && *input.Channel != "" { + ch = *input.Channel + } + network := m.GWClient.GetNetwork(ch) contract := network.GetContract(input.ChaincodeName) if contract == nil { return nil, errors.Errorf("chaincode %s not found", input.ChaincodeName) } - // - //chContext := m.SDK.ChannelContext( - // m.Channel, - // fabsdk.WithOrg(m.Organization), - // fabsdk.WithUser(m.User), - //) - //chClient, err := channel.New(chContext) - //if err != nil { - // return nil, err - //} var byteArgs [][]byte for _, arg := range input.Args { byteArgs = append(byteArgs, []byte(arg)) @@ -546,24 +549,10 @@ func (m mutationResolver) QueryChaincode(ctx context.Context, input models.Query input.Function, client.WithBytesArguments(byteArgs...), client.WithTransient(transientMap), - client.WithEndorsingOrganizations("MEDIIOCHAINMSP"), ) if err != nil { return nil, err } - //execReponse, err := chClient.Query( - // channel.Request{ - // ChaincodeID: input.ChaincodeName, - // Fcn: input.Function, - // Args: byteArgs, - // TransientMap: transientMap, - // InvocationChain: []*fab.ChaincodeCall{}, - // IsInit: false, - // }, - //) - //if err != nil { - // return nil, err - //} return &models.QueryChaincodeResponse{ Response: string(response), ChaincodeStatus: int(10), diff --git a/schema/mutation.graphql b/schema/mutation.graphql index 8640329..a7be027 100644 --- a/schema/mutation.graphql +++ b/schema/mutation.graphql @@ -7,6 +7,7 @@ type Mutation { } input QueryChaincodeInput { + channel: String chaincodeName: String! function: String! args: [String!] @@ -19,6 +20,7 @@ type QueryChaincodeResponse { } input InvokeChaincodeInput { + channel: String chaincodeName: String! function: String! args: [String!] @@ -65,6 +67,7 @@ input DeployChaincodeInput { chaincodeAddress: String! signaturePolicy: String! indexes: [CouchDBIndex!] + channel: String! } input CouchDBIndex { id: String!