code.vegaprotocol.io/vega@v0.79.0/datanode/admin/client.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package admin
    17  
    18  import (
    19  	"bytes"
    20  	"context"
    21  	"fmt"
    22  	"net"
    23  	"net/http"
    24  	"net/url"
    25  
    26  	"code.vegaprotocol.io/vega/datanode/networkhistory/segment"
    27  	"code.vegaprotocol.io/vega/logging"
    28  
    29  	"github.com/gorilla/rpc/json"
    30  )
    31  
    32  type Client struct {
    33  	log  *logging.Logger
    34  	cfg  Config
    35  	http *http.Client
    36  }
    37  
    38  func NewClient(
    39  	log *logging.Logger,
    40  	config Config,
    41  ) *Client {
    42  	log = log.Named(namedLogger)
    43  	log.SetLevel(config.Level.Get())
    44  	return &Client{
    45  		log: log,
    46  		cfg: config,
    47  		http: &http.Client{
    48  			Transport: &http.Transport{
    49  				DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
    50  					return net.Dial("unix", config.Server.SocketPath)
    51  				},
    52  			},
    53  		},
    54  	}
    55  }
    56  
    57  func (s *Client) call(ctx context.Context, method string, args interface{}, reply interface{}) error {
    58  	req, err := json.EncodeClientRequest(method, args)
    59  	if err != nil {
    60  		return fmt.Errorf("failed to encode client JSON request: %w", err)
    61  	}
    62  
    63  	u := url.URL{
    64  		Scheme: "http",
    65  		Host:   "unix",
    66  		Path:   s.cfg.Server.HTTPPath,
    67  	}
    68  
    69  	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), bytes.NewReader(req))
    70  	if err != nil {
    71  		return fmt.Errorf("failed to create HTTP request: %w", err)
    72  	}
    73  
    74  	httpReq.Header.Set("Content-Type", "application/json")
    75  
    76  	resp, err := s.http.Do(httpReq)
    77  	if err != nil {
    78  		return fmt.Errorf("failed to contact vega socket: %w", err)
    79  	}
    80  	defer resp.Body.Close()
    81  
    82  	if err := json.DecodeClientResponse(resp.Body, reply); err != nil {
    83  		return fmt.Errorf("failed to decode client JSON response: %w", err)
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func (s *Client) FetchNetworkHistorySegment(ctx context.Context, historySegmentID string) (segment.Full, error) {
    90  	var reply segment.Full
    91  	err := s.call(ctx, "networkhistory.FetchHistorySegment", historySegmentID, &reply)
    92  	return reply, err
    93  }
    94  
    95  func (s *Client) CopyHistorySegmentToFile(ctx context.Context, historySegmentID string, filePath string) (CopyHistorySegmentToFileReply, error) {
    96  	var reply CopyHistorySegmentToFileReply
    97  	err := s.call(ctx, "networkhistory.CopyHistorySegmentToFile", CopyHistorySegmentToFileArg{
    98  		HistorySegmentID: historySegmentID,
    99  		OutFile:          filePath,
   100  	}, &reply)
   101  	return reply, err
   102  }