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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 83 additions & 3 deletions docs/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10028,6 +10028,69 @@ paths:
description: Success
default:
description: ""
/namespaces/{ns}/transactions/{txnid}/blockchainevents:
get:
description: 'TODO: Description'
operationId: getTxnBlockchainEvents
parameters:
- description: 'TODO: Description'
in: path
name: ns
required: true
schema:
example: default
type: string
- description: 'TODO: Description'
in: path
name: txnid
required: true
schema:
type: string
- description: Server-side request timeout (millseconds, or set a custom suffix
like 10s)
in: header
name: Request-Timeout
schema:
default: 120s
type: string
responses:
"200":
content:
application/json:
schema:
items:
properties:
id: {}
info:
additionalProperties: {}
type: object
name:
type: string
namespace:
type: string
output:
additionalProperties: {}
type: object
protocolId:
type: string
sequence:
format: int64
type: integer
source:
type: string
subscription: {}
timestamp: {}
tx:
properties:
id: {}
type:
type: string
type: object
type: object
type: array
description: Success
default:
description: ""
/namespaces/{ns}/transactions/{txnid}/operations:
get:
description: 'TODO: Description'
Expand Down Expand Up @@ -10060,20 +10123,37 @@ paths:
schema:
items:
properties:
backendId:
type: string
created: {}
error:
type: string
id: {}
input:
additionalProperties: {}
type: object
namespace:
type: string
output:
additionalProperties: {}
type: object
plugin:
type: string
status:
type: string
tx: {}
type:
enum:
- none
- batch_pin
- token_pool
- blockchain_batch_pin
- publicstorage_batch_broadcast
- dataexchange_batch_send
- dataexchange_blob_send
- token_create_pool
- token_announce_pool
- token_transfer
- contract_invoke
type: string
updated: {}
type: object
type: array
description: Success
Expand Down
45 changes: 45 additions & 0 deletions internal/apiserver/route_get_txn_blockchainevents.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package apiserver

import (
"net/http"

"github.com/hyperledger/firefly/internal/config"
"github.com/hyperledger/firefly/internal/i18n"
"github.com/hyperledger/firefly/internal/oapispec"
"github.com/hyperledger/firefly/pkg/fftypes"
)

var getTxnBlockchainEvents = &oapispec.Route{
Name: "getTxnBlockchainEvents",
Path: "namespaces/{ns}/transactions/{txnid}/blockchainevents",
Method: http.MethodGet,
PathParams: []*oapispec.PathParam{
{Name: "ns", ExampleFromConf: config.NamespacesDefault, Description: i18n.MsgTBD},
{Name: "txnid", Description: i18n.MsgTBD},
},
QueryParams: nil,
FilterFactory: nil,
Description: i18n.MsgTBD,
JSONInputValue: nil,
JSONOutputValue: func() interface{} { return &[]*fftypes.BlockchainEvent{} },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't need the & here I think as arrays are a reference type, although it doesn't really matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copy-pasted this, but your comment prompted me to do a quick investigation... it actually looks like the Swagger generation for the output schema is only correct if you do include the &. So for this route it correctly indicates that it will return an array of BlockchainEvent. But for other routes that don't return a pointer, it's a bit broken - such as for /transactions, which returns []*fftypes.Transaction, the Swagger indicates it will return a single Transaction object.

I take this to mean we should add the & everywhere on array returns, or investigate why the Swagger generation behaves this way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for digging! Will merge based on this and raise an issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I see #449

JSONOutputCodes: []int{http.StatusOK},
JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) {
return filterResult(getOr(r.Ctx).GetTransactionBlockchainEvents(r.Ctx, r.PP["ns"], r.PP["txnid"]))
},
}
39 changes: 39 additions & 0 deletions internal/apiserver/route_get_txn_blockchainevents_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright © 2021 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package apiserver

import (
"net/http/httptest"
"testing"

"github.com/hyperledger/firefly/pkg/fftypes"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

func TestGetTxnBlockchainEvents(t *testing.T) {
o, r := newTestAPIServer()
req := httptest.NewRequest("GET", "/api/v1/namespaces/mynamespace/transactions/abcd12345/blockchainevents", nil)
req.Header.Set("Content-Type", "application/json; charset=utf-8")
res := httptest.NewRecorder()

o.On("GetTransactionBlockchainEvents", mock.Anything, "mynamespace", "abcd12345").
Return([]*fftypes.BlockchainEvent{}, nil, nil)
r.ServeHTTP(res, req)

assert.Equal(t, 200, res.Result().StatusCode)
}
2 changes: 1 addition & 1 deletion internal/apiserver/route_get_txn_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var getTxnOps = &oapispec.Route{
FilterFactory: nil,
Description: i18n.MsgTBD,
JSONInputValue: nil,
JSONOutputValue: func() interface{} { return &[]*fftypes.Transaction{} },
JSONOutputValue: func() interface{} { return &[]*fftypes.Operation{} },
JSONOutputCodes: []int{http.StatusOK},
JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) {
return filterResult(getOr(r.Ctx).GetTransactionOperations(r.Ctx, r.PP["ns"], r.PP["txnid"]))
Expand Down
1 change: 1 addition & 0 deletions internal/apiserver/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var routes = []*oapispec.Route{
getSubscriptions,
getTxnByID,
getTxnOps,
getTxnBlockchainEvents,
getTxns,

getChartHistogram,
Expand Down
13 changes: 13 additions & 0 deletions internal/orchestrator/data_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,16 @@ func (or *orchestrator) GetBlockchainEventByID(ctx context.Context, id *fftypes.
func (or *orchestrator) GetBlockchainEvents(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.BlockchainEvent, *database.FilterResult, error) {
return or.database.GetBlockchainEvents(ctx, or.scopeNS(ns, filter))
}

func (or *orchestrator) GetTransactionBlockchainEvents(ctx context.Context, ns, id string) ([]*fftypes.BlockchainEvent, *database.FilterResult, error) {
u, err := or.verifyIDAndNamespace(ctx, ns, id)
if err != nil {
return nil, nil, err
}
fb := database.BlockchainEventQueryFactory.NewFilter(ctx)
filter := fb.And(
fb.Eq("tx.id", u),
fb.Eq("namespace", ns),
)
return or.database.GetBlockchainEvents(ctx, filter)
}
14 changes: 13 additions & 1 deletion internal/orchestrator/data_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ func TestGetTransactionOperationsOk(t *testing.T) {

func TestGetTransactionOperationBadID(t *testing.T) {
or := newTestOrchestrator()
or.mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{}, nil, nil)
_, _, err := or.GetTransactionOperations(context.Background(), "ns1", "")
assert.Regexp(t, "FF10142", err)
}
Expand Down Expand Up @@ -591,3 +590,16 @@ func TestGetBlockchainEvents(t *testing.T) {
_, _, err := or.GetBlockchainEvents(context.Background(), "ns", f.And())
assert.NoError(t, err)
}

func TestGetTransactionBlockchainEventsOk(t *testing.T) {
or := newTestOrchestrator()
or.mdi.On("GetBlockchainEvents", mock.Anything, mock.Anything).Return([]*fftypes.BlockchainEvent{}, nil, nil)
_, _, err := or.GetTransactionBlockchainEvents(context.Background(), "ns1", fftypes.NewUUID().String())
assert.NoError(t, err)
}

func TestGetTransactionBlockchainEventsBadID(t *testing.T) {
or := newTestOrchestrator()
_, _, err := or.GetTransactionBlockchainEvents(context.Background(), "ns1", "")
assert.Regexp(t, "FF10142", err)
}
1 change: 1 addition & 0 deletions internal/orchestrator/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ type Orchestrator interface {
GetNamespaces(ctx context.Context, filter database.AndFilter) ([]*fftypes.Namespace, *database.FilterResult, error)
GetTransactionByID(ctx context.Context, ns, id string) (*fftypes.Transaction, error)
GetTransactionOperations(ctx context.Context, ns, id string) ([]*fftypes.Operation, *database.FilterResult, error)
GetTransactionBlockchainEvents(ctx context.Context, ns, id string) ([]*fftypes.BlockchainEvent, *database.FilterResult, error)
GetTransactions(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.Transaction, *database.FilterResult, error)
GetMessageByID(ctx context.Context, ns, id string) (*fftypes.Message, error)
GetMessageByIDWithData(ctx context.Context, ns, id string) (*fftypes.MessageInOut, error)
Expand Down
32 changes: 32 additions & 0 deletions mocks/orchestratormocks/orchestrator.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.