1. Adjust the directory hierarchy
[msb/apigateway.git] / msb-core / openresty-ext / src / assembly / resources / openresty / nginx / luaext / dao / redis_db.lua
1 --[[\r
2 \r
3     Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)\r
4 \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
8 \r
9             http://www.apache.org/licenses/LICENSE-2.0\r
10 \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
16 \r
17 --]]\r
18 \r
19 -- the client for redis, include the connection pool management and api implements\r
20 local redis = require('resty.redis')\r
21 local tbl_util  = require('lib.utils.table_util')\r
22 \r
23 local _M = {\r
24 }\r
25 _M._VERSION = '0.0.1'\r
26 _M._DESCRIPTION = 'msb_redis_module'\r
27 \r
28 local mt = { __index = _M }\r
29 \r
30 local tbl_insert = table.insert\r
31 local tbl_sort = table.sort\r
32 local tbl_isempty = tbl_util.isempty\r
33 \r
34 function _M.new(self, conf)\r
35         self.host        = conf.host\r
36         self.port        = conf.port\r
37         self.timeout     = conf.timeout\r
38         self.dbid        = conf.dbid\r
39         self.poolsize    = conf.poolsize\r
40         self.idletimeout = conf.idletimeout\r
41 \r
42         local red = redis:new()\r
43         return setmetatable({redis = red}, mt)\r
44 end\r
45 \r
46 function _M.connectdb(self)\r
47         local host  = self.host\r
48         local port  = self.port\r
49         local dbid  = self.dbid\r
50         local red   = self.redis\r
51 \r
52         if not (host and port) then\r
53                 return nil, 'no host:port avaliable provided'\r
54         end\r
55 \r
56         --set default value\r
57         if not dbid then dbid = 0 end\r
58         local timeout   = self.timeout \r
59         if not timeout then \r
60                 timeout = 1000   -- 1s\r
61         end\r
62 \r
63         red:set_timeout(timeout)\r
64 \r
65         local ok, err \r
66         if host and port then\r
67                 ok, err = red:connect(host, port)\r
68                 if ok then return red:select(dbid) end\r
69         end\r
70 \r
71         return ok, err\r
72 end\r
73 \r
74 function _M.keepalivedb(self)\r
75         local   max_idle_timeout  = self.idletimeout --ms\r
76         local   pool_size         = self.poolsize\r
77 \r
78         if not pool_size then pool_size = 100 end\r
79         if not max_idle_timeout then max_idle_timeout = 90000 end --90s\r
80 \r
81         local ok, err = self.redis:set_keepalive(max_idle_timeout, pool_size)\r
82         if not ok then\r
83                 ngx.log(ngx.ERR, "redis pool keepalive error",err)\r
84                 return\r
85         end\r
86         return\r
87 end\r
88 \r
89 --inner function,only used in this module\r
90 local function _hgetall(red,key)\r
91         local resp,err = red:hgetall(key)\r
92         --if not resp or next(resp) == nil then\r
93         if tbl_isempty(resp) then\r
94                 return nil, "key "..key.." not found"\r
95         end\r
96         local hashinfo = red:array_to_hash(resp)\r
97         return hashinfo,nil\r
98 end\r
99 \r
100 function _M.getserviceinfo(self,key)\r
101         if not key then\r
102                 return nil,'no key is provided'\r
103         end\r
104         local c, err = self:connectdb()\r
105         if not c then\r
106                 return nil, err\r
107         end\r
108 \r
109         local red   = self.redis\r
110 \r
111         local resp,err = red:hgetall(key) --the key will create dynamically\r
112         --if not resp or next(resp) == nil then\r
113         if tbl_isempty(resp) then\r
114                 self:keepalivedb()\r
115                 return nil, "key "..key.." not found"\r
116         end\r
117 \r
118         local serviceinfo = red:array_to_hash(resp)\r
119 \r
120         self:keepalivedb()\r
121 \r
122         return serviceinfo,nil\r
123 end\r
124 \r
125 function _M.getbackservers(self,keypattern)\r
126         if not keypattern then\r
127                 return nil,'no keypattern is provided'\r
128         end\r
129         local c, err = self:connectdb()\r
130         if not c then\r
131                 return nil, err\r
132         end\r
133 \r
134         local red = self.redis\r
135 \r
136         local resp, err = red:keys(keypattern)\r
137         if tbl_isempty(resp) then\r
138                 self:keepalivedb()\r
139                 return nil, "no server matched"\r
140         end\r
141 \r
142         local servers = {}\r
143         for i, v in ipairs(resp) do\r
144                 local serverinfo,err = _hgetall(red,v)\r
145                 if serverinfo then\r
146                         tbl_insert(servers,serverinfo)\r
147                 end\r
148         end\r
149         self:keepalivedb()\r
150         return servers,nil\r
151 end\r
152 \r
153 function _M.getcustomsvcnames(self,keypattern)\r
154         if not keypattern then\r
155                 return nil,'no keypattern is provided'\r
156         end\r
157         local c, err = self:connectdb()\r
158         if not c then\r
159                 return nil, err\r
160         end\r
161 \r
162         local red = self.redis\r
163 \r
164         local resp, err = red:keys(keypattern)\r
165         if tbl_isempty(resp) then\r
166                 self:keepalivedb()\r
167                 return {}, "no custome service name found"\r
168         end\r
169 \r
170         local svcnames = {}\r
171         --store svc names into the Set\r
172         local key_set={}\r
173         local name\r
174         for key, value in ipairs(resp) do\r
175                 local m, err = ngx.re.match(value, "^.+:custom:([^:]+):.*", "o")\r
176                 if m then\r
177                         name = m[1]\r
178                         key_set[name]=true              \r
179                 end\r
180         end\r
181 \r
182         for key,_ in pairs(key_set) do\r
183                 tbl_insert(svcnames,key)\r
184         end\r
185         --sort the key_table in reverse order\r
186         tbl_sort(svcnames, function (a, b)\r
187                         return a > b\r
188                 end)\r
189 \r
190         self:keepalivedb()\r
191         return svcnames,nil\r
192 end\r
193 return _M