Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add http proxy cababitlity for rest-trigger #150

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 32 additions & 98 deletions trigger/rest/README.md
Original file line number Diff line number Diff line change
@@ -1,115 +1,49 @@
<!--
title: REST
weight: 4706
-->
# REST Trigger
This trigger provides your flogo application the ability to start an action via REST over HTTP

If the option `isPassThroughUri` is set, a pathParam is automatically create with the rest of the path after the give settings path of the handler
## Installation

```bash
flogo install github.com/project-flogo/contrib/trigger/rest
```

## TIBCO sandbox - Manual loading
```bash
zip the 'rest' directory (including the directory 'rest' )
Go to https://eu.integration.cloud.tibco.com/envtools/flogo_extensions and upload the zip
ensure to increase the version nr in the description.json before uploading to distingues between versions
```

## Configuration

### Settings:
| Name | Type | Description
|:--- | :--- | :---
| port | int | The port to listen on - **REQUIRED**
| enableTLS | bool | Enable TLS on the server
| certFile | string | The path to PEM encoded server certificate
| keyFile | string | The path to PEM encoded server key

| Name | Type | Description |
|:----------|:-------|:-------------------------------------------|
| port | int | The port to listen on - **REQUIRED** |
| enableTLS | bool | Enable TLS on the server |
| certFile | string | The path to PEM encoded server certificate |
| keyFile | string | The path to PEM encoded server key |

### Handler Settings:
| Name | Type | Description
|:--- | :--- | :---
| method | string | The HTTP method (ie. GET,POST,PUT,PATCH or DELETE) - **REQUIRED**
| path | string | The resource path - **REQUIRED**
| Name | Type | Description |
|:-----------|:--------|:-------------------------------------------------------------------|
| method | string | The HTTP method (ie. GET,POST,PUT,PATCH or DELETE) - **REQUIRED** |
| path | string | The resource path - **REQUIRED** |


### Output:
| Name | Type | Description
|:--- | :--- | :---
| pathParams | params | The path parameters (e.g., 'id' in http://.../pet/:id/name )
| queryParams | params | The query parameters (e.g., 'id' in http://.../pet?id=someValue )
| headers | params | The HTTP header parameters
| method | string | The HTTP method used for the request
| content | any | The content of the request
| Name | Type | Description |
|-------------|--------|-------------------------------------------------------------------|
| pathParams | params | The path parameters (e.g., 'id' in http://.../pet/:id/name ) |
| queryParams | params | The query parameters (e.g., 'id' in http://.../pet?id=someValue ) |
| headers | params | The HTTP header parameters |
| method | string | The HTTP method used for the request |
| content | any | The content of the request |

### Reply:
| Name | Type | Description
|:--- | :--- | :---
| code | int | The http code to reply with
| data | any | The data to reply with
| headers | params | The HTTP response headers
| cookies | params | The HTTP response cookies to set (uses 'Set-Cookie' headers)

## Example Configurations

Triggers are configured via the triggers.json of your application. The following are some example configuration of the REST Trigger.

### POST
Configure the Trigger to handle a POST on /device

```json
{
"triggers": [
{
"id": "flogo-rest",
"ref": "github.com/project-flogo/contrib/trigger/rest",
"settings": {
"port": 8080
},
"handlers": [
{
"settings": {
"method": "POST",
"path": "/device"
},
"action": {
"ref": "github.com/project-flogo/flow",
"settings": {
"flowURI": "res://flow:new_device_flow"
}
}
}
]
}
]
}
```

### GET
Configure the Trigger to handle a GET on /device/:id

```json
{
"triggers": [
{
"id": "flogo-rest",
"ref": "github.com/project-flogo/contrib/trigger/rest",
"settings": {
"port": 8080
},
"handlers": [
{
"settings": {
"method": "GET",
"path": "/device/:id"
},
"action": {
"ref": "github.com/project-flogo/flow",
"settings": {
"flowURI": "res://flow:get_device_flow"
},
"input":{
"deviceId":"=$.pathParams.id"
}
}
}
]
}
]
}
```
| Name | Type | Description |
|---------|--------|--------------------------------------------------------------|
| code | int | The http code to reply with |
| data | any | The data to reply with |
| headers | params | The HTTP response headers |
| cookies | params | The HTTP response cookies to set (uses 'Set-Cookie' headers) |
19 changes: 13 additions & 6 deletions trigger/rest/descriptor.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "flogo-rest",
"name": "flogo-lp-rest",
"type": "flogo:trigger",
"version": "0.10.0",
"title": "Receive HTTP Message",
"description": "Simple REST Trigger",
"homepage": "https://github.com/project-flogo/contrib/tree/master/trigger/rest",
"version": "1.0.0",
"title": "HTTP uri-path pass through",
"description": "Rest Trigger with uri-path pass through capabilities ",
"homepage": "https://gitlab.core-services.leaseplan.systems/workloads/0026-wkl-ng-integration/integration/shared/flogoresttrigger",
"settings": [
{
"name": "port",
Expand Down Expand Up @@ -58,7 +58,7 @@
"reply": [
{
"name": "code",
"type": "int",
"type": "number",
"description": "The http code to reply with"
},
{
Expand All @@ -79,6 +79,13 @@
],
"handler": {
"settings": [
{
"name": "isPassThroughUri",
"type": "string",
"required" : true,
"allowed" : ["YES", "NO"],
"description": "use as a pass through will automatically add a 'partial' part of the defined 'path' as a pathParam with name 'restOfThePath'"
},
{
"name": "method",
"type": "string",
Expand Down
5 changes: 3 additions & 2 deletions trigger/rest/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ type Settings struct {
}

type HandlerSettings struct {
Method string `md:"method,required,allowed(GET,POST,PUT,PATCH,DELETE)"` // The HTTP method (ie. GET,POST,PUT,PATCH or DELETE)
Path string `md:"path,required"` // The resource path
IsPassThroughUri string `md:"isPassThroughUri,required,allowed(YES,NO)"` // use as a pass through will automatically add a 'partial' part of the defined 'path' as a pathParam with name 'restOfThePath'
Method string `md:"method,required,allowed(GET,POST,PUT,PATCH,DELETE)"` // The HTTP method (ie. GET,POST,PUT,PATCH or DELETE)
Path string `md:"path,required"` // The resource path
}

type Output struct {
Expand Down
23 changes: 11 additions & 12 deletions trigger/rest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ import (
)

const (
httpDefaultAddr = ":http" //todo should this be :8080
httpDefaultAddr = ":http" //todo should this be :8080
httpDefaultTlsAddr = ":https" //todo should this be :8443

httpDefaultReadTimeout = 15 * time.Second
httpDefaultReadTimeout = 15 * time.Second
httpDefaultWriteTimeout = 15 * time.Second
)

type Server struct {
running bool
srv *http.Server
srv *http.Server

tlsEnabled bool
certFile string
keyFile string
certFile string
keyFile string
}

func NewServer(addr string, handler http.Handler, opts ...func(*Server)) (*Server, error) {
Expand All @@ -36,10 +36,10 @@ func NewServer(addr string, handler http.Handler, opts ...func(*Server)) (*Serve

srv := &Server{}
srv.srv = &http.Server{
Addr: addr,
Handler: handler,
ReadTimeout:httpDefaultReadTimeout,
WriteTimeout:httpDefaultWriteTimeout,
Addr: addr,
Handler: handler,
ReadTimeout: httpDefaultReadTimeout,
WriteTimeout: httpDefaultWriteTimeout,
}

for _, opt := range opts {
Expand All @@ -53,7 +53,6 @@ func NewServer(addr string, handler http.Handler, opts ...func(*Server)) (*Serve
return srv, nil
}


///////////////////////
// Options

Expand Down Expand Up @@ -145,7 +144,7 @@ func (s *Server) Stop() error {
///////////////////////
// Validation Helpers

func (s *Server) validateStart() error {
func (s *Server) validateStart() error {

//check if port is available
ln, err := net.Listen("tcp", s.srv.Addr)
Expand All @@ -157,7 +156,7 @@ func (s *Server) validateStart() error {
return nil
}

func (s *Server) validateInit() error {
func (s *Server) validateInit() error {

if s.tlsEnabled {
// using tls, so validate cert & key
Expand Down
26 changes: 19 additions & 7 deletions trigger/rest/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ func (*Factory) New(config *trigger.Config) (trigger.Trigger, error) {

// Trigger REST trigger struct
type Trigger struct {
server *Server
settings *Settings
id string
logger log.Logger
// serverInstanceID string
server *Server
settings *Settings
id string
logger log.Logger
// serverInstanceID string
}

func (t *Trigger) Initialize(ctx trigger.InitContext) error {
Expand All @@ -79,7 +79,12 @@ func (t *Trigger) Initialize(ctx trigger.InitContext) error {

method := s.Method
path := s.Path

if s.IsPassThroughUri == "YES" {
if len(path) == 0 || path[len(path)-1] != '/' {
path = path + "/"
}
path = path + "*restOfThePath"
}
t.logger.Debugf("Registering handler [%s: %s]", method, path)

if _, ok := pathMap[path]; !ok {
Expand Down Expand Up @@ -138,6 +143,13 @@ type IDResponse struct {
ID string `json:"id"`
}

func removeFirstCharIfForwardSlash(input string) string {
if input[0] == '/' {
return input[1:]
}
return input
}

func newActionHandler(rt *Trigger, method string, handler trigger.Handler) httprouter.Handle {

return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
Expand All @@ -157,7 +169,7 @@ func newActionHandler(rt *Trigger, method string, handler trigger.Handler) httpr

out.PathParams = make(map[string]string)
for _, param := range ps {
out.PathParams[param.Key] = param.Value
out.PathParams[param.Key] = removeFirstCharIfForwardSlash(param.Value) // router 'catch all' path part remove '/' to make pathParams look the same
}

queryValues := r.URL.Query()
Expand Down
Loading