Skip to content

Commit bf684d7

Browse files
committed
added to OSN new handler for fetch a block of channel
Signed-off-by: Fedor Partanskiy <fredprtnsk@gmail.com>
1 parent 824eb5a commit bf684d7

File tree

15 files changed

+755
-8
lines changed

15 files changed

+755
-8
lines changed

cmd/osnadmin/main.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"io"
1717
"net/http"
1818
"os"
19+
"strconv"
1920

2021
"github.com/hyperledger/fabric-protos-go-apiv2/common"
2122
"github.com/hyperledger/fabric/internal/osnadmin"
@@ -63,6 +64,11 @@ func executeForArgs(args []string) (output string, exit int, err error) {
6364
configUpdateEnvelopePath := update.Flag("config-update-envelope", "Path to the file containing an up-to-date config update envelope for the channel").Short('e').Required().String()
6465
tlsHandshakeTimeShift := update.Flag("tlsHandshakeTimeShift", "The amount of time to shift backwards for certificate expiration checks during TLS handshakes with the orderer endpoint").Short('t').Default("0").Duration()
6566

67+
fetch := channel.Command("fetch", "Fetch a specified block, writing it to a file.")
68+
fetchChannelID := fetch.Flag("channelID", "Channel ID").Short('c').Required().String()
69+
fetchBlockID := fetch.Flag("blockID", "Block ID - <newest|oldest|config|(number)>").Short('b').Required().String()
70+
fetchOutputFile := fetch.Flag("outputfile", "Puth to a file.").Short('f').Required().String()
71+
6672
command, err := app.Parse(args)
6773
if err != nil {
6874
return "", 1, err
@@ -141,6 +147,14 @@ func executeForArgs(args []string) (output string, exit int, err error) {
141147
resp, err = osnadmin.Remove(osnURL, *removeChannelID, caCertPool, tlsClientCert)
142148
case update.FullCommand():
143149
resp, err = osnadmin.Update(osnURL, marshaledConfigEnvelope, caCertPool, tlsClientCert, *tlsHandshakeTimeShift)
150+
case fetch.FullCommand():
151+
if *fetchBlockID != "newest" && *fetchBlockID != "oldest" && *fetchBlockID != "config" {
152+
_, err = strconv.Atoi(*fetchBlockID)
153+
if err != nil {
154+
return "", 1, fmt.Errorf("'%s' not equal <newest|oldest|config|(number)>", *fetchBlockID)
155+
}
156+
}
157+
resp, err = osnadmin.Fetch(osnURL, *fetchChannelID, *fetchBlockID, caCertPool, tlsClientCert)
144158
}
145159
if err != nil {
146160
return errorOutput(err), 1, nil
@@ -151,22 +165,28 @@ func executeForArgs(args []string) (output string, exit int, err error) {
151165
return errorOutput(err), 1, nil
152166
}
153167

154-
output, err = responseOutput(!*noStatus, resp.StatusCode, bodyBytes)
168+
output, err = responseOutput(!*noStatus, resp.StatusCode, bodyBytes, *fetchOutputFile)
155169
if err != nil {
156170
return errorOutput(err), 1, nil
157171
}
158172

159173
return output, 0, nil
160174
}
161175

162-
func responseOutput(showStatus bool, statusCode int, responseBody []byte) (string, error) {
176+
func responseOutput(showStatus bool, statusCode int, responseBody []byte, outputFile string) (string, error) {
163177
var buffer bytes.Buffer
164178
if showStatus {
165179
fmt.Fprintf(&buffer, "Status: %d\n", statusCode)
166180
}
167181
if len(responseBody) != 0 {
168-
if err := json.Indent(&buffer, responseBody, "", "\t"); err != nil {
169-
return "", err
182+
if outputFile != "" {
183+
if err := os.WriteFile(outputFile, responseBody, 0o644); err != nil {
184+
return "", err
185+
}
186+
} else {
187+
if err := json.Indent(&buffer, responseBody, "", "\t"); err != nil {
188+
return "", err
189+
}
170190
}
171191
}
172192
return buffer.String(), nil

cmd/osnadmin/mocks/channel_management.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/osnadmin/osnadmin_suite_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type channelManagement interface {
2323
JoinChannel(channelID string, configBlock *cb.Block) (types.ChannelInfo, error)
2424
UpdateChannel(channelID string, configUpdateEnvelope *cb.Envelope) (types.ChannelInfo, error)
2525
RemoveChannel(channelID string) error
26+
FetchBlock(channelID string, blockID string) (*cb.Block, error)
2627
}
2728

2829
func TestOsnadmin(t *testing.T) {

docs/source/commands/osnadminchannel.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The `osnadmin channel` command has the following subcommands:
1818
* join
1919
* list
2020
* remove
21+
* update
22+
* fetch
2123

2224
## osnadmin channel
2325
```
@@ -56,6 +58,9 @@ Subcommands:
5658
5759
channel update --channelID=CHANNELID --config-update-envelope=CONFIG-UPDATE-ENVELOPE [<flags>]
5860
Update an Ordering Service Node (OSN) to a channel.
61+
62+
channel fetch --channelID=CHANNELID --blockID=BLOCKID --outputfile=OUTPUTFILE
63+
Fetch a specified block, writing it to a file.
5964
```
6065

6166

@@ -169,6 +174,33 @@ Flags:
169174
handshakes with the orderer endpoint
170175
```
171176

177+
178+
## osnadmin channel fetch
179+
```
180+
usage: osnadmin channel fetch --channelID=CHANNELID --blockID=BLOCKID --outputfile=OUTPUTFILE
181+
182+
Fetch a specified block, writing it to a file.
183+
184+
Flags:
185+
--help Show context-sensitive help (also try
186+
--help-long and --help-man).
187+
-o, --orderer-address=ORDERER-ADDRESS
188+
Admin endpoint of the OSN
189+
--ca-file=CA-FILE Path to file containing PEM-encoded TLS CA
190+
certificate(s) for the OSN
191+
--client-cert=CLIENT-CERT Path to file containing PEM-encoded X509 public
192+
key to use for mutual TLS communication with
193+
the OSN
194+
--client-key=CLIENT-KEY Path to file containing PEM-encoded private key
195+
to use for mutual TLS communication with the
196+
OSN
197+
--no-status Remove the HTTP status message from the command
198+
output
199+
-c, --channelID=CHANNELID Channel ID
200+
-b, --blockID=BLOCKID Block ID - <newest|oldest|config|(number)>
201+
-f, --outputfile=OUTPUTFILE Puth to a file.
202+
```
203+
172204
## Example Usage
173205

174206
### osnadmin channel join examples

docs/wrappers/osnadmin_channel_preamble.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ The `osnadmin channel` command has the following subcommands:
1313
* join
1414
* list
1515
* remove
16+
* update
17+
* fetch

integration/nwo/channel_participation.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ func getBody(client *http.Client, url string) func() string {
171171
}
172172
}
173173

174+
func getBodyBinary(client *http.Client, url string) func() []byte {
175+
return func() []byte {
176+
resp, err := client.Get(url)
177+
Expect(err).NotTo(HaveOccurred())
178+
bodyBytes, err := io.ReadAll(resp.Body)
179+
Expect(err).NotTo(HaveOccurred())
180+
resp.Body.Close()
181+
return bodyBytes
182+
}
183+
}
184+
174185
type ChannelInfo struct {
175186
Name string `json:"name"`
176187
URL string `json:"url"`
@@ -195,6 +206,29 @@ func ListOne(n *Network, o *Orderer, channel string) ChannelInfo {
195206
return *c
196207
}
197208

209+
func Fetch(n *Network, o *Orderer, channel string, blockID string, errStr string) *common.Block {
210+
authClient, _ := OrdererOperationalClients(n, o)
211+
212+
protocol := "http"
213+
if n.TLSEnabled {
214+
protocol = "https"
215+
}
216+
fetchURL := fmt.Sprintf("%s://127.0.0.1:%d/participation/v1/channels/%s/blocks/%s", protocol, n.OrdererPort(o, AdminPort), channel, blockID)
217+
218+
body := getBodyBinary(authClient, fetchURL)()
219+
if errStr != "" {
220+
Expect(string(body)).To(ContainSubstring(errStr))
221+
222+
return nil
223+
}
224+
225+
b := &common.Block{}
226+
err := proto.Unmarshal(body, b)
227+
Expect(err).NotTo(HaveOccurred())
228+
229+
return b
230+
}
231+
198232
func Remove(n *Network, o *Orderer, channel string) {
199233
authClient, _ := OrdererOperationalClients(n, o)
200234

internal/osnadmin/fetch.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package osnadmin
8+
9+
import (
10+
"crypto/tls"
11+
"crypto/x509"
12+
"fmt"
13+
"net/http"
14+
)
15+
16+
// Fetch get block from OSN.
17+
func Fetch(osnURL, channelID string, blockID string, caCertPool *x509.CertPool, tlsClientCert tls.Certificate) (*http.Response, error) {
18+
url := fmt.Sprintf("%s/participation/v1/channels/%s/blocks/%s", osnURL, channelID, blockID)
19+
20+
return httpGet(url, caCertPool, tlsClientCert)
21+
}

0 commit comments

Comments
 (0)