Skip to content

Commit

Permalink
change lua script
Browse files Browse the repository at this point in the history
  • Loading branch information
AmaliMatharaarachchi committed Jan 5, 2022
1 parent 1a15ab1 commit de0cd81
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 70 deletions.
136 changes: 71 additions & 65 deletions adapter/internal/interceptor/interceptor.go
Expand Up @@ -75,88 +75,94 @@ var (
// commonTemplate contains common lua code for request and response intercept
// Note: this template only applies if request or response interceptor is enabled
commonTemplate = `
local interceptor = require 'home.wso2.interceptor.lib.interceptor'
{{if .ResponseFlowEnable}} {{/* resp_flow details are required in req flow if request info needed in resp flow */}}
local resp_flow_list = {
{{ range $key, $value := .ResponseFlow }}
{{ $key }} = {invocationContext={{$value.Include.InvocationContext}}, requestHeaders={{$value.Include.RequestHeaders}}, requestBody={{$value.Include.RequestBody}}, requestTrailer={{$value.Include.RequestTrailer}},
responseHeaders={{$value.Include.ResponseHeaders}}, responseBody={{$value.Include.ResponseBody}}, responseTrailers={{$value.Include.ResponseTrailers}}}
{{ end }}
}
{{else}}local resp_flow_list = {}{{end}} {{/* if resp_flow disabled no need req info in resp path */}}
local inv_context = {
organizationId = "{{.Context.OrganizationID}}",
basePath = "{{.Context.BasePath}}",
supportedMethods = "{{.Context.SupportedMethods}}",
apiName = "{{.Context.APIName}}",
apiVersion = "{{.Context.APIVersion}}",
pathTemplate = "{{.Context.PathTemplate}}",
vhost = "{{.Context.Vhost}}",
prodClusterName = "{{.Context.ProdClusterName}}",
sandClusterName = "{{.Context.SandClusterName}}"
}
`
local interceptor = require 'home.wso2.interceptor.lib.interceptor'
{{if .ResponseFlowEnable}} {{/* resp_flow details are required in req flow if request info needed in resp flow */}}
local resp_flow_list = { {{ range $key, $value := .ResponseFlow }} {{ $key }}={invocationContext={{$value.Include.InvocationContext}}, requestHeaders={{$value.Include.RequestHeaders}}, requestBody={{$value.Include.RequestBody}}, requestTrailer={{$value.Include.RequestTrailer}},
responseHeaders={{$value.Include.ResponseHeaders}}, responseBody={{$value.Include.ResponseBody}}, responseTrailers={{$value.Include.ResponseTrailers}}},
{{ end }}}
{{else}}local resp_flow_list = {}{{end}} {{/* if resp_flow disabled no need req info in resp path */}}
local inv_context = {
organizationId = "{{.Context.OrganizationID}}",
basePath = "{{.Context.BasePath}}",
supportedMethods = "{{.Context.SupportedMethods}}",
apiName = "{{.Context.APIName}}",
apiVersion = "{{.Context.APIVersion}}",
pathTemplate = "{{.Context.PathTemplate}}",
vhost = "{{.Context.Vhost}}",
prodClusterName = "{{.Context.ProdClusterName}}",
sandClusterName = "{{.Context.SandClusterName}}"
}
`
requestInterceptorTemplate = `
local req_flow_list = {
{{ range $key, $value := .RequestFlow }}
{{ $key }}= {invocationContext={{$value.Include.InvocationContext}}, requestHeaders={{$value.Include.RequestHeaders}}, requestBody={{$value.Include.RequestBody}}, requestTrailer={{$value.Include.RequestTrailer}}}
{{ end }}
}
local req_call_config = {
{{ range $key, $value := .RequestFlow }}
{{ $key }}={ClusterName={{$value.ExternalCall.ClusterName}}, Timeout={{$value.ExternalCall.Timeout}}
{{ end }}
}
function envoy_on_request(request_handle)
method=request_handle:headers():get(":method")
interceptor.handle_request_interceptor(
request_handle,
{cluster_name=req_call_config[method].ClusterName, timeout=req_call_config[method].Timeout},
req_flow_list[method], resp_flow_list[method], inv_context
)
end
`
local req_flow_list = { {{ range $key, $value := .RequestFlow }} {{ $key }}={invocationContext={{$value.Include.InvocationContext}}, requestHeaders={{$value.Include.RequestHeaders}}, requestBody={{$value.Include.RequestBody}}, requestTrailer={{$value.Include.RequestTrailer}}},
{{ end }}}
local req_call_config = { {{ range $key, $value := .RequestFlow }} {{ $key }}={ClusterName="{{$value.ExternalCall.ClusterName}}", Timeout={{$value.ExternalCall.Timeout}}},
{{ end }}}
function envoy_on_request(request_handle)
method=request_handle:headers():get(":method")
if req_flow_list[method] ~= nil and req_call_config[method] ~= nil then
resp_flow = {}
if req_flow_list[method] ~= nil then
resp_flow = resp_flow_list[method]
end
interceptor.handle_request_interceptor(
request_handle,
{cluster_name=req_call_config[method].ClusterName, timeout=req_call_config[method].Timeout},
req_flow_list[method], resp_flow, inv_context
)
end
end
`
//get method in response flow
responseInterceptorTemplate = `
local res_call_config = {
{{ range $key, $value := .ResponseFlow }}
{{ $key }}= {ClusterName={{$value.ExternalCall.ClusterName}}, Timeout={{$value.ExternalCall.Timeout}}
{{ end }}
}
function envoy_on_response(response_handle)
interceptor.handle_response_interceptor(
method=request_handle:headers():get(":method")
response_handle,
{cluster_name=req_call_config[method].ClusterName, timeout=req_call_config[method].Timeout},
resp_flow_list[method]
)
end
`
local res_call_config = {
{{ range $key, $value := .ResponseFlow }}
{{ $key }}= {ClusterName="{{$value.ExternalCall.ClusterName}}", Timeout={{$value.ExternalCall.Timeout}}}
{{ end }}}
function envoy_on_response(response_handle)
if resp_flow_list[method] ~= nil and res_call_config[method] ~= nil then
interceptor.handle_response_interceptor(
response_handle, res_call_config, resp_flow_list
)
end
end
`
// defaultRequestInterceptorTemplate is the template that is applied when request flow is disabled
// just updated req flow info with resp flow without calling interceptor service
defaultRequestInterceptorTemplate = `
function envoy_on_request(request_handle)
method=request_handle:headers():get(":method")
interceptor.handle_request_interceptor(request_handle, {}, {}, resp_flow_list[method], inv_context, true)
end
`
function envoy_on_request(request_handle)
method=request_handle:headers():get(":method")
resp_flow = {}
if resp_flow_list[method] ~= nil and res_call_config[method] ~= nil then
resp_flow = resp_flow_list[method]
end
interceptor.handle_request_interceptor(request_handle, {}, {}, resp_flow, inv_context, true)
end
`
// defaultResponseInterceptorTemplate is the template that is applied when response flow is disabled
defaultResponseInterceptorTemplate = `
function envoy_on_response(response_handle)
end
`
function envoy_on_response(response_handle)
end
`
)

//GetInterceptor inject values and get request interceptor
// Note: This method is called only if one of request or response interceptor is enabled
func GetInterceptor(values *Interceptor) string {
templ := template.Must(template.New("lua-filter").Parse(getTemplate(values.RequestFlowEnable,
values.ResponseFlowEnable)))
t, err := template.New("lua-filter").Parse(getTemplate(values.RequestFlowEnable,
values.ResponseFlowEnable))
if err != nil {
logger.LoggerInterceptor.Error("error while parsing the interceptor template:", err)
return ""
}
templ := template.Must(t, err)
var out bytes.Buffer
err := templ.Execute(&out, values)
err = templ.Execute(&out, values)
if err != nil {
logger.LoggerInterceptor.Error("executing request interceptor template:", err)
return ""
}
println(out.String())
return out.String()
}

Expand Down
9 changes: 8 additions & 1 deletion adapter/internal/oasparser/envoyconf/routes_with_clusters.go
Expand Up @@ -290,10 +290,15 @@ func CreateRoutesWithClusters(mgwSwagger model.MgwSwagger, upstreamCerts map[str
operationalReqInterceptors := mgwSwagger.GetOperationInterceptors(apiRequestInterceptor, resourceRequestInterceptor, resource.GetMethod(),
xWso2requestInterceptor)
for method, opI := range operationalReqInterceptors {
println(opI.Enable)
println(opI.Level)
if opI.Enable && opI.Level == "operation" {
logger.LoggerOasparser.Debugf("Operation level request interceptors found for %v:%v-%v-%v", apiTitle, apiVersion, resource.GetPath(),
opI.ClusterName)

println(opI.ClusterName)
opI.ClusterName = getClusterName(requestInterceptClustersNamePrefix, organizationID, vHost, apiTitle, apiVersion, opI.ClusterName)
println(opI.ClusterName)
cluster, addresses, err := CreateLuaCluster(interceptorCerts, opI)
if err != nil {
logger.LoggerOasparser.Errorf("Error while adding operational level request intercept external cluster for %s. %v",
Expand Down Expand Up @@ -890,7 +895,9 @@ func getInlineLuaScript(requestInterceptor map[string]model.InterceptEndpoint, r
requestContext *interceptor.InvocationContext) string {

i := &interceptor.Interceptor{
Context: requestContext,
Context: requestContext,
RequestFlow: make(map[string]interceptor.Config),
ResponseFlow: make(map[string]interceptor.Config),
}
if len(requestInterceptor) > 0 {
i.RequestFlowEnable = true
Expand Down
2 changes: 1 addition & 1 deletion adapter/internal/oasparser/model/mgw_swagger.go
Expand Up @@ -1005,6 +1005,7 @@ func (swagger *MgwSwagger) GetOperationInterceptors(apiInterceptor InterceptEndp

for _, op := range operations {
operationInterceptor, _ := swagger.GetInterceptor(op.GetVendorExtensions(), extensionName, "operation")
operationInterceptor.ClusterName = op.iD
// if operation interceptor not given add resource level interceptor
if !operationInterceptor.Enable {
operationInterceptor = resourceInterceptor
Expand All @@ -1015,7 +1016,6 @@ func (swagger *MgwSwagger) GetOperationInterceptors(apiInterceptor InterceptEndp
}
// add opertaion to the list only if an interceptor is enabled for the operation
if operationInterceptor.Enable {
operationInterceptor.ClusterName = op.iD
interceptorOperationMap[strings.ToUpper(op.method)] = operationInterceptor
}
}
Expand Down
16 changes: 13 additions & 3 deletions router/src/main/resources/interceptor/lib/interceptor.lua
Expand Up @@ -366,16 +366,26 @@ end

---interceptor handler for response flow
---@param response_handle table - response_handle
---@param intercept_service {cluster_name: string, resource_path: string, timeout: number}
---@param resp_flow_includes {requestHeaders: boolean, requestBody: boolean, requestTrailer: boolean, responseHeaders: boolean, responseBody: boolean, responseTrailers: boolean}
function interceptor.handle_response_interceptor(response_handle, intercept_service, resp_flow_includes)
---@param intercept_service_list {method: {cluster_name: string, resource_path: string, timeout: number}}
---@param resp_flow_includes_list {method: {requestHeaders: boolean, requestBody: boolean, requestTrailer: boolean, responseHeaders: boolean, responseBody: boolean, responseTrailers: boolean}}
function interceptor.handle_response_interceptor(response_handle, intercept_service_list, resp_flow_includes_list)
local meta = response_handle:streamInfo():dynamicMetadata():get(LUA_FILTER_NAME)
local shared_info = meta and meta[SHARED_INFO_META_KEY]
if not shared_info then
-- no shared info found, request interceptor flow is not executed (eg: enforcer validation failed)
-- TODO: (renuka) check again, if we want to go response flow if enforcer validation failed, have to set request info metadata from enforcer
return
end
local method = shared_info[REQUEST.REQ_HEADERS][":method"]
if method == nil then
return
end
local resp_flow_includes = resp_flow_includes_list[method]
local intercept_service = intercept_service_list[method]
if resp_flow_includes == nil or intercept_service == nil then
return
end

local request_id = shared_info[SHARED.REQUEST_ID]
if shared_info[RESPONSE.DIRECT_RESPOND] then
response_handle:logDebug("Ignoring response path intercept since direct responded for the request_id: " .. request_id)
Expand Down

0 comments on commit de0cd81

Please sign in to comment.