github.com/s7techlab/cckit@v0.10.5/gateway/invoker_instance.go (about)

     1  package gateway
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/hyperledger/fabric-protos-go/peer"
     9  
    10  	"github.com/s7techlab/cckit/convert"
    11  )
    12  
    13  // ChaincodeInvoker used in generated service gateway code
    14  type (
    15  	ChaincodeInstanceInvoker interface {
    16  		Query(ctx context.Context, fn string, args []interface{}, target interface{}) (interface{}, error)
    17  		Invoke(ctx context.Context, fn string, args []interface{}, target interface{}) (interface{}, error)
    18  	}
    19  
    20  	ChaincodeInstanceServiceInvoker struct {
    21  		ChaincodeInstance ChaincodeInstanceServiceServer
    22  	}
    23  )
    24  
    25  func NewChaincodeInstanceServiceInvoker(ccInstance ChaincodeInstanceServiceServer) *ChaincodeInstanceServiceInvoker {
    26  	c := &ChaincodeInstanceServiceInvoker{
    27  		ChaincodeInstance: ccInstance,
    28  	}
    29  
    30  	return c
    31  }
    32  
    33  func (c *ChaincodeInstanceServiceInvoker) Query(
    34  	ctx context.Context, fn string, args []interface{}, target interface{}) (interface{}, error) {
    35  
    36  	ccInput, err := ccInput(ctx, fn, args)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	res, err := c.ChaincodeInstance.Query(ctx, &ChaincodeInstanceQueryRequest{
    42  		Input: ccInput,
    43  	})
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	return ccOutput(res, target)
    49  }
    50  
    51  func (c *ChaincodeInstanceServiceInvoker) Invoke(
    52  	ctx context.Context, fn string, args []interface{}, target interface{}) (interface{}, error) {
    53  
    54  	ccInput, err := ccInput(ctx, fn, args)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	res, err := c.ChaincodeInstance.Invoke(ctx, &ChaincodeInstanceInvokeRequest{
    60  		Input: ccInput,
    61  	})
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	return ccOutput(res, target)
    67  }
    68  
    69  func InvokerArgs(fn string, args []interface{}) ([][]byte, error) {
    70  	argsBytes, err := convert.ArgsToBytes(args...)
    71  	if err != nil {
    72  		return nil, fmt.Errorf(`invoker args: %w`, err)
    73  	}
    74  
    75  	return append([][]byte{[]byte(fn)}, argsBytes...), nil
    76  }
    77  
    78  func ccInput(ctx context.Context, fn string, args []interface{}) (*ChaincodeInput, error) {
    79  	argsBytes, err := InvokerArgs(fn, args)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	ccInput := &ChaincodeInput{
    84  		Args: argsBytes,
    85  	}
    86  
    87  	if ccInput.Transient, err = TransientFromContext(ctx); err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	return ccInput, nil
    92  }
    93  
    94  func ccOutput(response *peer.Response, target interface{}) (res interface{}, err error) {
    95  	output, err := convert.FromBytes(response.Payload, target)
    96  	if err != nil {
    97  		return nil, fmt.Errorf(`convert output to=%s: %w`, reflect.TypeOf(target), err)
    98  	}
    99  
   100  	return output, nil
   101  }