github.com/s7techlab/cckit@v0.10.5/gateway/chaincode_instance_service.go (about) 1 package gateway 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/hyperledger/fabric-protos-go/peer" 8 9 "github.com/s7techlab/cckit/router" 10 "github.com/s7techlab/cckit/sdk" 11 ) 12 13 type ( 14 ChaincodeInstanceService struct { 15 SDK sdk.SDK 16 Locator *ChaincodeLocator 17 Opts *Opts 18 } 19 20 // ChaincodeInstance base implementation ChaincodeInstanceService - via SDK 21 // but also possible another implementation (via REST, another SDK etc) 22 ChaincodeInstance interface { 23 ChaincodeInstanceServiceServer 24 25 EventsChan(ctx context.Context, rr ...*ChaincodeInstanceEventsStreamRequest) ( 26 _ chan *ChaincodeEvent, closer func() error, _ error) 27 } 28 ) 29 30 var _ ChaincodeInstance = &ChaincodeInstanceService{} 31 32 func NewChaincodeInstanceService(sdk sdk.SDK, locator *ChaincodeLocator, opts ...Opt) *ChaincodeInstanceService { 33 ccInstanceService := &ChaincodeInstanceService{ 34 SDK: sdk, 35 Locator: locator, 36 Opts: &Opts{}, 37 } 38 39 for _, o := range opts { 40 o(ccInstanceService.Opts) 41 } 42 43 return ccInstanceService 44 } 45 46 func (cis *ChaincodeInstanceService) EventService() *ChaincodeInstanceEventService { 47 return &ChaincodeInstanceEventService{ 48 EventDelivery: cis.SDK, 49 Locator: &ChaincodeLocator{ 50 Channel: cis.Locator.Channel, 51 Chaincode: cis.Locator.Chaincode, 52 }, 53 Opts: cis.Opts, 54 } 55 } 56 57 func (cis *ChaincodeInstanceService) ServiceDef() ServiceDef { 58 return ServiceDef{ 59 Desc: &_ChaincodeInstanceService_serviceDesc, 60 Service: cis, 61 HandlerFromEndpointRegister: RegisterChaincodeInstanceServiceHandlerFromEndpoint, 62 } 63 } 64 65 func (cis *ChaincodeInstanceService) Exec(ctx context.Context, req *ChaincodeInstanceExecRequest) (*peer.Response, error) { 66 switch req.Type { 67 case InvocationType_INVOCATION_TYPE_QUERY: 68 return cis.Query(ctx, &ChaincodeInstanceQueryRequest{Input: req.Input}) 69 case InvocationType_INVOCATION_TYPE_INVOKE: 70 return cis.Invoke(ctx, &ChaincodeInstanceInvokeRequest{Input: req.Input}) 71 default: 72 return nil, ErrUnknownInvocationType 73 } 74 } 75 76 func (cis *ChaincodeInstanceService) Query(ctx context.Context, req *ChaincodeInstanceQueryRequest) (*peer.Response, error) { 77 if err := router.ValidateRequest(req); err != nil { 78 return nil, err 79 } 80 81 for _, c := range cis.Opts.Context { 82 ctx = c(ctx) 83 } 84 85 signer, _ := SignerFromContext(ctx) 86 87 for _, i := range cis.Opts.Input { 88 if err := i(req.Input); err != nil { 89 return nil, err 90 } 91 } 92 93 response, err := cis.SDK.Query( 94 ctx, 95 cis.Locator.Channel, 96 cis.Locator.Chaincode, 97 req.Input.Args, 98 signer, 99 req.Input.Transient, 100 ) 101 if err != nil { 102 return nil, fmt.Errorf("query chaincode: %w", err) 103 } 104 for _, o := range cis.Opts.Output { 105 if err = o(InvocationType_INVOCATION_TYPE_QUERY, response); err != nil { 106 return nil, fmt.Errorf(`output opt: %w`, err) 107 } 108 } 109 110 return response, nil 111 112 } 113 114 func (cis *ChaincodeInstanceService) Invoke(ctx context.Context, req *ChaincodeInstanceInvokeRequest) (*peer.Response, error) { 115 if err := router.ValidateRequest(req); err != nil { 116 return nil, err 117 } 118 119 for _, c := range cis.Opts.Context { 120 ctx = c(ctx) 121 } 122 123 // underlying hlf-sdk(or your implementation must handle it) should handle 'nil' identity cases 124 // and set default if identity wasn't provided here 125 // if smth goes wrong we'll see it on the step below 126 signer, _ := SignerFromContext(ctx) 127 128 for _, i := range cis.Opts.Input { 129 if err := i(req.Input); err != nil { 130 return nil, err 131 } 132 } 133 134 response, _, err := cis.SDK.Invoke( 135 ctx, 136 cis.Locator.Channel, 137 cis.Locator.Chaincode, 138 req.Input.Args, 139 signer, 140 req.Input.Transient, 141 TxWaiterFromContext(ctx), 142 ) 143 if err != nil { 144 return nil, fmt.Errorf("invoke chaincode: %w", err) 145 } 146 147 for _, o := range cis.Opts.Output { 148 if err = o(InvocationType_INVOCATION_TYPE_INVOKE, response); err != nil { 149 return nil, fmt.Errorf(`output opt: %w`, err) 150 } 151 } 152 153 return response, nil 154 } 155 156 func (cis *ChaincodeInstanceService) EventsStream( 157 req *ChaincodeInstanceEventsStreamRequest, stream ChaincodeInstanceService_EventsStreamServer) error { 158 return cis.EventService().EventsStream(req, stream) 159 } 160 161 func (cis *ChaincodeInstanceService) Events( 162 ctx context.Context, req *ChaincodeInstanceEventsRequest) (*ChaincodeEvents, error) { 163 return cis.EventService().Events(ctx, req) 164 } 165 166 func (cis *ChaincodeInstanceService) EventsChan( 167 ctx context.Context, rr ...*ChaincodeInstanceEventsStreamRequest) (_ chan *ChaincodeEvent, closer func() error, _ error) { 168 return cis.EventService().EventsChan(ctx, rr...) 169 }