Skip to content

Commit

Permalink
generate workflow sdk types. small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jinhoonbang committed Oct 15, 2024
1 parent 12af1de commit 9d2beb5
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 37 deletions.
2 changes: 1 addition & 1 deletion core/capabilities/webapi/target/connector_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ConnectorHandler struct {
rateLimiter *common.RateLimiter
}

func NewConnectorHandler(gc connector.GatewayConnector, config Config, lgger logger.Logger) (*ConnectorHandler, error) {
func NewConnectorHandler(gc connector.GatewayConnector, config ServiceConfig, lgger logger.Logger) (*ConnectorHandler, error) {
rateLimiter, err := common.NewRateLimiter(config.RateLimiter)
if err != nil {
return nil, err
Expand Down
53 changes: 38 additions & 15 deletions core/capabilities/webapi/target/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/chainlink-common/pkg/values"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/validation"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/webapi/webapicap"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/webapicapabilities"
)

Expand All @@ -24,16 +25,22 @@ var capabilityInfo = capabilities.MustNewCapabilityInfo(
"A target that sends HTTP requests to external clients via the Chainlink Gateway.",
)

const (
DefaultDeliveryMode = SingleNode
DefaultHttpMethod = "GET"

Check failure on line 30 in core/capabilities/webapi/target/target.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: const DefaultHttpMethod should be DefaultHTTPMethod (revive)
DefaultTimeoutMs = 30000
)

// Capability is a target capability that sends HTTP requests to external clients via the Chainlink Gateway.
type Capability struct {
capabilityInfo capabilities.CapabilityInfo
connectorHandler *ConnectorHandler
lggr logger.Logger
registry core.CapabilitiesRegistry
config Config
config ServiceConfig
}

func NewCapability(config Config, registry core.CapabilitiesRegistry, connectorHandler *ConnectorHandler, lggr logger.Logger) (*Capability, error) {
func NewCapability(config ServiceConfig, registry core.CapabilitiesRegistry, connectorHandler *ConnectorHandler, lggr logger.Logger) (*Capability, error) {
return &Capability{
capabilityInfo: capabilityInfo,
config: config,
Expand Down Expand Up @@ -70,16 +77,38 @@ func getMessageID(req capabilities.CapabilityRequest) (string, error) {
return strings.Join(messageID, "/"), nil
}

func getPayload(input webapicap.TargetPayload, cfg webapicap.TargetConfig) webapicapabilities.TargetRequestPayload {
method := input.Method
if method == nil {
*method = DefaultHttpMethod
}
body := input.Body
if body == nil {
*body = ""
}
timeoutMs := cfg.TimeoutMs
if timeoutMs == nil {
*timeoutMs = DefaultTimeoutMs
}
return webapicapabilities.TargetRequestPayload{
URL: input.Url,
Method: *method,
Headers: input.Headers,
Body: []byte(*body),
TimeoutMs: uint32(*timeoutMs),

Check failure on line 98 in core/capabilities/webapi/target/target.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int64 -> uint32 (gosec)
}
}

func (c *Capability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) {
c.lggr.Debugw("executing http target", "capabilityRequest", req)

var input Input
var input webapicap.TargetPayload
err := req.Inputs.UnwrapTo(&input)
if err != nil {
return capabilities.CapabilityResponse{}, err
}

var workflowCfg WorkflowConfig
var workflowCfg webapicap.TargetConfig
err = req.Config.UnwrapTo(&workflowCfg)
if err != nil {
return capabilities.CapabilityResponse{}, err
Expand All @@ -90,26 +119,20 @@ func (c *Capability) Execute(ctx context.Context, req capabilities.CapabilityReq
return capabilities.CapabilityResponse{}, err
}

payload := webapicapabilities.TargetRequestPayload{
URL: input.URL,
Method: input.Method,
Headers: input.Headers,
Body: input.Body,
TimeoutMs: workflowCfg.TimeoutMs,
}
payload := getPayload(input, workflowCfg)

payloadBytes, err := json.Marshal(payload)
if err != nil {
return capabilities.CapabilityResponse{}, err
}

// Default to SingleNode delivery mode
deliveryMode := SingleNode
if workflowCfg.DeliveryMode != "" {
deliveryMode = workflowCfg.DeliveryMode
deliveryMode := workflowCfg.DeliveryMode
if workflowCfg.DeliveryMode == nil {
*deliveryMode = DefaultDeliveryMode
}

switch deliveryMode {
switch *deliveryMode {
case SingleNode:
// blocking call to handle single node request. waits for response from gateway
resp, err := c.connectorHandler.HandleSingleNodeRequest(ctx, messageID, payloadBytes)
Expand Down
6 changes: 3 additions & 3 deletions core/capabilities/webapi/target/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
owner1 = "0x00000000000000000000000000000000000000aa"
)

var defaultConfig = Config{
var defaultConfig = ServiceConfig{
RateLimiter: common.RateLimiterConfig{
GlobalRPS: 100.0,
GlobalBurst: 100,
Expand All @@ -42,12 +42,12 @@ type testHarness struct {
registry *registrymock.CapabilitiesRegistry
connector *gcmocks.GatewayConnector
lggr logger.Logger
config Config
config ServiceConfig
connectorHandler *ConnectorHandler
capability *Capability
}

func setup(t *testing.T, config Config) testHarness {
func setup(t *testing.T, config ServiceConfig) testHarness {
registry := registrymock.NewCapabilitiesRegistry(t)
connector := gcmocks.NewGatewayConnector(t)
lggr := logger.Test(t)
Expand Down
20 changes: 3 additions & 17 deletions core/capabilities/webapi/target/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,10 @@ const (
AllAtOnce string = "AllAtOnce"
)

type Input struct {
URL string `json:"url"` // URL to query, only http and https protocols are supported.
Method string `json:"method,omitempty"` // HTTP verb, defaults to GET.
Headers map[string]string `json:"headers,omitempty"` // HTTP headers, defaults to empty.
Body []byte `json:"body,omitempty"` // HTTP body, defaults to empty.
}

// WorkflowConfig is the configuration of the workflow that is passed in the workflow execute request
type WorkflowConfig struct {
TimeoutMs uint32 `json:"timeoutMs,omitempty"` // Timeout in milliseconds
RetryCount uint8 `json:"retryCount,omitempty"` // Number of retries, defaults to 0.
DeliveryMode string `json:"deliveryMode,omitempty"` // DeliveryMode describes how request should be delivered to gateway nodes, defaults to SingleNode.
}

// Config is the configuration for the Target capability and handler
// ServiceConfig is the configuration for the Target capability and handler
// TODO: handle retry configurations here CM-472
// Note that workflow executions have their own internal timeouts and retries set by the user
// that are separate from this configuration
type Config struct {
RateLimiter common.RateLimiterConfig `toml:"rateLimiter"`
type ServiceConfig struct {
RateLimiter common.RateLimiterConfig `toml:"rateLimiter" json:"rateLimiter" yaml:"rateLimiter" mapstructure:"rateLimiter"`
}
43 changes: 43 additions & 0 deletions core/capabilities/webapi/webapicap/target_builders_generated.go

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

62 changes: 62 additions & 0 deletions core/capabilities/webapi/webapicap/webapi_target-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/smartcontractkit/chainlink/v2/core/capabilities/webapi/webapicap/web-api-target@1.0.0",
"description": "A target that sends HTTP requests to a URL",
"$defs": {
"TargetPayload": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The URL to send the request to"
},
"method": {
"type": "string",
"description": "The HTTP method to use for the request"
},
"headers": {
"type": "object",
"description": "The headers to include in the request",
"additionalProperties" : {
"type": "string"
}
},
"body": {
"type": "string",
"description": "The body of the request"
}
},
"required": ["url"],
"additionalProperties": false
},
"TargetConfig": {
"type": "object",
"properties": {
"timeoutMs": {
"type": "integer",
"description": "The timeout in milliseconds for the request"
},
"retryCount": {
"type": "integer",
"description": "The number of times to retry the request"
},
"deliveryMode": {
"type": "string",
"description": "The delivery mode for the request"
}
},
"required": [],
"additionalProperties": false
}
},
"type": "object",
"properties": {
"config": {
"$ref": "#/$defs/TargetConfig"
},
"inputs": {
"$ref": "#/$defs/TargetPayload"
}
},
"required": ["config","inputs"]
}
84 changes: 84 additions & 0 deletions core/capabilities/webapi/webapicap/webapi_target_generated.go

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

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

3 changes: 3 additions & 0 deletions core/services/gateway/handlers/webapicapabilities/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ func (h *handler) handleWebAPITargetMessage(ctx context.Context, msg *api.Messag
DonId: msg.Body.DonId,
Payload: payloadBytes,
},
// this signature is not verified by the node because
// WS connection between gateway and node are already verified
Signature: msg.Signature,
}
}
err = h.don.SendToNode(newCtx, nodeAddr, respMsg)
Expand Down
Loading

0 comments on commit 9d2beb5

Please sign in to comment.