Issue-id: OCS-9
[msb/apigateway.git] / msb-core / openresty-ext / src / assembly / resources / openresty / nginx / luaext / openoapirouter.lua
1 --[[
2
3     Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
4
5     Licensed under the Apache License, Version 2.0 (the "License");
6     you may not use this file except in compliance with the License.
7     You may obtain a copy of the License at
8
9         http://www.apache.org/licenses/LICENSE-2.0
10
11     Unless required by applicable law or agreed to in writing, software
12     distributed under the License is distributed on an "AS IS" BASIS,
13     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14     See the License for the specific language governing permissions and
15     limitations under the License.
16
17         Author: Zhaoxing Meng
18         email: meng.zhaoxing1@zte.com.cn
19
20 ]]
21 -- put red into the connection pool of size 100,
22 -- with 10 seconds max idle time
23 local function close_redis(red)
24         if not red then
25                 return
26         end
27         --release connection to the pool
28         local pool_max_idle_time = 10000
29         local pool_size = 100
30         local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
31         if not ok then
32                 ngx.log(ngx.ERR, "set keepalive error:", err)
33         end
34         return
35 end
36
37 local function rewrite_api_url()
38         local apiserver=ngx.var.apiserver
39         if apiserver=="fallback" then
40                 ngx.status = ngx.HTTP_NOT_FOUND
41                 ngx.exit(ngx.status)
42         end
43         local apiurl=ngx.var.apiurl
44         local uri = ngx.re.sub(ngx.var.uri, "^/openoapi/([^/]+)(/[Vv][^/]*)?(.*)", apiurl.."$3", "o")
45         ngx.req.set_uri(uri)
46 end
47
48 local function query_api_info()
49         local apiserver = ngx.var.apiserver
50         local apiname = ngx.var.apiname
51         local apiversion = ngx.var.apiversion
52         apiversion=string.sub(apiversion,2,string.len(apiversion))
53
54         -- Check if key exists in local cache
55         local cache = ngx.shared.ceryx
56         local server, flags = cache:get("server:api:"..apiname..":"..apiversion)
57         local url, flags = cache:get("url:api:"..apiname..":"..apiversion)
58         if server and url then
59                 ngx.var.apiserver = server
60                 ngx.var.apiurl = url
61                 ngx.log(ngx.WARN, "==using api cache:", server.."&&"..url)
62                 return
63         end
64
65         local redis = require "resty.redis"
66         local red = redis:new()
67         red:set_timeout(1000) -- 1000 ms
68         local redis_host = "127.0.0.1" 
69         local redis_port = 6379 
70         local res, err = red:connect(redis_host, redis_port)
71
72         -- Return if could not connect to Redis
73         if not res then
74                 ngx.log(ngx.ERR, "connect to redis error:", err)
75                 return
76         end
77
78         -- Construct Redis key
79         local prefix =  "msb"
80         local keyprefix = prefix..":routing:api:"..apiname..":"..apiversion
81
82         local infokey=keyprefix..":info"
83         -- first of all check whether the status is 1(enabled)
84         local status = red:hget(infokey,"status")
85         if not (status=="1")  then
86                 ngx.log(ngx.WARN, keyprefix.."is disabled.status=", status)
87                 return close_redis(red)
88         end
89         
90         -- Try to get url for apiname
91         local url, err = red:hget(infokey,"url")
92         ngx.log(ngx.WARN, "==url:", url)
93         if not url or url == ngx.null then
94                 return close_redis(red) 
95         end
96
97         -- Try to get ip:port for apiname
98         local serverkey=keyprefix..":lb:server1"
99         local server, err = red:hget(serverkey,"ip")..":"..red:hget(serverkey,"port")
100         ngx.log(ngx.WARN, "==server:", server)
101         if not server or server == ngx.null then
102                 return close_redis(red) 
103         end
104
105
106         -- Save found key to local cache for 5 seconds
107         cache:set("server:api:"..apiname..":"..apiversion, server, 5)
108         cache:set("url:api:"..apiname..":"..apiversion, url, 5)
109
110         ngx.log(ngx.WARN, "==api result:", server.."&&"..url)
111         ngx.var.apiserver = server
112         ngx.var.apiurl = url
113
114         return close_redis(red)
115 end
116 query_api_info()
117 rewrite_api_url()