3 Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
\r
5 Licensed under the Apache License, Version 2.0 (the "License");
\r
6 you may not use this file except in compliance with the License.
\r
7 You may obtain a copy of the License at
\r
9 http://www.apache.org/licenses/LICENSE-2.0
\r
11 Unless required by applicable law or agreed to in writing, software
\r
12 distributed under the License is distributed on an "AS IS" BASIS,
\r
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 See the License for the specific language governing permissions and
\r
15 limitations under the License.
\r
19 local msbConf = require('conf.msbinit')
\r
20 local svcConf = require('conf.svcconf')
\r
21 local dbclient = require('dao.db_access')
\r
22 local tbl_util = require('lib.utils.table_util')
\r
23 local svc_util = require('lib.utils.svc_util')
\r
24 local log_util = require('lib.utils.log_util')
\r
26 local tbl_concat = table.concat
\r
27 local tbl_isempty = tbl_util.isempty
\r
28 local svc_isactive = svc_util.isactive
\r
29 local svc_setauthheader = svc_util.setauthheader
\r
30 local svc_isautodiscover = svc_util.isautodiscover
\r
32 local str_sub = string.sub
\r
33 local str_len = string.len
\r
34 local str_low = string.lower
\r
35 local ngx_var = ngx.var
\r
36 local ngx_ctx = ngx.ctx
\r
37 local log = log_util.log
\r
39 local defaultport = msbConf.systemConf.defaultport
\r
40 local defaultprefix = msbConf.systemConf.defaultprefix
\r
41 local enablefullsearch = msbConf.systemConf.enablefullsearch
\r
42 local useconsultemplate = msbConf.systemConf.useconsultemplate
\r
43 local apiRelatedTypes = svcConf.apiRelatedTypes
\r
44 local urlfieldMap = svcConf.urlfieldMap
\r
46 local donotfound = function()
\r
47 if enablefullsearch then
\r
48 -- test against the custom services after the commonrewrite phase
\r
49 ngx.status = ngx.HTTP_GONE
\r
51 ngx.status = ngx.HTTP_NOT_FOUND
\r
52 ngx.say("service info not found!")
\r
54 return ngx.exit(ngx.status)
\r
57 ---------------------------------------------------------------
\r
59 -- determine whether it is websocket request
\r
60 -- and do internal redirect
\r
61 ---------------------------------------------------------------
\r
62 local http_upgrade = ngx_var.http_upgrade
\r
63 if(ngx_var.websocket_internal_redirect == "on") and http_upgrade and str_low(http_upgrade) == "websocket" then
\r
64 ngx.log(ngx.ERR, "Websocket request and redirect to @commonwebsocket")
\r
65 return ngx.exec("@commonwebsocket");
\r
68 ---------------------------------------------------------------
\r
71 -- svc_server_keypattern
\r
72 ---------------------------------------------------------------
\r
73 local svc_name = ngx_var.svc_name
\r
74 local req_res = ngx_var.req_res
\r
75 local svc_type = ngx_var.svc_type
\r
77 local sys_prefix = ""
\r
78 local server_port = ngx_var.server_port
\r
79 if(server_port == defaultport) then
\r
80 sys_prefix = defaultprefix
\r
82 sys_prefix = server_port
\r
85 local svc_info_key = ""
\r
86 local svc_server_keypattern = ""
\r
87 local upstream_name_consultemplate = ""
\r
88 if(apiRelatedTypes[svc_type]) then
\r
89 -- process version info first
\r
90 local version1 = ngx_var.svc_version1
\r
91 local version2 = ngx_var.svc_version2
\r
93 -- check version info appearing befor or after
\r
94 if(not version2) then version2 = "" end --convert nil to empty sting avoiding throw error
\r
95 if(not version1 or version1 == "") then
\r
99 req_res = version2..req_res
\r
101 -- remove the slash in front of the version (e.g. /V1.0)
\r
102 local svc_version=str_sub(version,2,str_len(version))
\r
103 svc_info_key = tbl_concat({sys_prefix,"api",svc_name,svc_version,"info"},":")
\r
104 svc_server_keypattern = tbl_concat({sys_prefix,"api",svc_name,svc_version,"lb:server*"},":")
\r
105 upstream_name_consultemplate = svc_name
\r
107 svc_info_key = tbl_concat({sys_prefix,"iui",svc_name,"info"},":")
\r
108 svc_server_keypattern = tbl_concat({sys_prefix,"iui",svc_name,"lb:server*"},":")
\r
109 upstream_name_consultemplate = "IUI_"..svc_name
\r
112 ---------------------------------------------------------------
\r
113 --step1:query the service info from share memory or back db
\r
114 -- svcinfo: the requested service information
\r
115 ---------------------------------------------------------------
\r
116 local svcinfo = dbclient.load_serviceinfo(svc_info_key)
\r
117 if not svc_isactive(svcinfo) then
\r
121 local svc_url = svcinfo[urlfieldMap[svc_type]]
\r
122 if not svc_url then
\r
126 ---------------------------------------------------------------
\r
127 --step2:rewrite the request uri using the svcinfo
\r
128 ---------------------------------------------------------------
\r
129 local rewrited_uri = svc_url..req_res
\r
130 --special handling: avoid throws internal error when it is empty
\r
131 if (rewrited_uri == "") then rewrited_uri = "/" end
\r
132 ngx.req.set_uri(rewrited_uri)
\r
134 log("matchedservice",svc_name)
\r
135 log("rewrited_uri",rewrited_uri)
\r
136 ---------------------------------------------------------------
\r
137 --step2.1:if this service is inter-system,add custom http header
\r
138 ---------------------------------------------------------------
\r
139 svc_setauthheader(svcinfo)
\r
141 ---------------------------------------------------------------
\r
142 --step3:process the proxy upstream part
\r
143 -- con1-using consul template:set the upstream name
\r
144 -- con2-using msb balancer:query the server list and store in the ctx
\r
145 ---------------------------------------------------------------
\r
146 if useconsultemplate and svc_isautodiscover(svcinfo) then
\r
147 ngx_var.backend = upstream_name_consultemplate
\r
149 local backservers = dbclient.load_backservers(svc_server_keypattern)
\r
150 if tbl_isempty(backservers) then
\r
153 ngx_ctx.backservers = backservers
\r
154 ngx_ctx.svcserverpattern = svc_server_keypattern
\r