Commit 43e9aa1eb3a2f227d0c13b53200c43a5e53997ae
1 parent
1a1c04fff5
Exists in
master
dispose and putBack
Showing 2 changed files with 30 additions and 1 deletions Inline Diff
index.js
1 | const MODULE_NAME = 'SDK-SUPPLIER-PRODUCT-QUOTA'; | 1 | const MODULE_NAME = 'SDK-SUPPLIER-PRODUCT-QUOTA'; |
2 | 2 | ||
3 | const logger = require('komodo-sdk/logger'); | 3 | const logger = require('komodo-sdk/logger'); |
4 | const config = require('komodo-sdk/config'); | 4 | const config = require('komodo-sdk/config'); |
5 | 5 | ||
6 | logger.info(`${MODULE_NAME}: Intializing`, { handlerName: config.handler_name }); | 6 | logger.info(`${MODULE_NAME}: Intializing`, { handlerName: config.handler_name }); |
7 | 7 | ||
8 | const redisUtil = require('./lib/redis-util'); | 8 | const redisUtil = require('./lib/redis-util'); |
9 | 9 | ||
10 | require('./lib/control-panel'); | 10 | require('./lib/control-panel'); |
11 | 11 | ||
12 | exports.decrement = redisUtil.decrement; | 12 | exports.dispose = redisUtil.dispose; |
13 | exports.putBack = redisUtil.putBack; | ||
13 | 14 |
lib/redis-util.js
1 | const MODULE_NAME = 'SDK-SUPPLIER-PRODUCT-QUOTA.REDIS-UTIL'; | 1 | const MODULE_NAME = 'SDK-SUPPLIER-PRODUCT-QUOTA.REDIS-UTIL'; |
2 | const DEFAULT_TTL = 3600 * 24 * 90; | 2 | const DEFAULT_TTL = 3600 * 24 * 90; |
3 | const LIMITED_SET_NAME = 'SPQ_8FB2B6EC_MANAGED'; | 3 | const LIMITED_SET_NAME = 'SPQ_8FB2B6EC_MANAGED'; |
4 | 4 | ||
5 | const redis = require('redis'); | 5 | const redis = require('redis'); |
6 | const { orderBy } = require('natural-orderby'); | 6 | const { orderBy } = require('natural-orderby'); |
7 | 7 | ||
8 | const config = require('komodo-sdk/config'); | 8 | const config = require('komodo-sdk/config'); |
9 | const logger = require('komodo-sdk/logger'); | 9 | const logger = require('komodo-sdk/logger'); |
10 | 10 | ||
11 | const redisClient = redis.createClient(); | 11 | const redisClient = redis.createClient(); |
12 | 12 | ||
13 | const composeKeyword = (product) => `SPQ_F7D526DB_COUNTER_${config.handler_name}_${product.trim().toUpperCase()}`; | 13 | const composeKeyword = (product) => `SPQ_F7D526DB_COUNTER_${config.handler_name}_${product.trim().toUpperCase()}`; |
14 | 14 | ||
15 | const set = (product, val, xid) => new Promise((resolve) => { | 15 | const set = (product, val, xid) => new Promise((resolve) => { |
16 | if (!(product || '').trim()) { | 16 | if (!(product || '').trim()) { |
17 | resolve(); | 17 | resolve(); |
18 | return; | 18 | return; |
19 | } | 19 | } |
20 | 20 | ||
21 | const keyword = composeKeyword(product); | 21 | const keyword = composeKeyword(product); |
22 | redisClient.set(keyword, Number(val), 'EX', DEFAULT_TTL, (err) => { | 22 | redisClient.set(keyword, Number(val), 'EX', DEFAULT_TTL, (err) => { |
23 | if (err) { | 23 | if (err) { |
24 | logger.warn(`F7D526DB ${MODULE_NAME}: Error on set value on redis`, { | 24 | logger.warn(`F7D526DB ${MODULE_NAME}: Error on set value on redis`, { |
25 | xid, product, val, eCode: err.code, eMessage: err.message, | 25 | xid, product, val, eCode: err.code, eMessage: err.message, |
26 | }); | 26 | }); |
27 | resolve(); | 27 | resolve(); |
28 | return; | 28 | return; |
29 | } | 29 | } |
30 | 30 | ||
31 | resolve(val); | 31 | resolve(val); |
32 | }); | 32 | }); |
33 | }); | 33 | }); |
34 | 34 | ||
35 | const get = (product, xid) => new Promise((resolve) => { | 35 | const get = (product, xid) => new Promise((resolve) => { |
36 | if (!(product || '').trim()) { | 36 | if (!(product || '').trim()) { |
37 | resolve(); | 37 | resolve(); |
38 | return; | 38 | return; |
39 | } | 39 | } |
40 | 40 | ||
41 | const keyword = composeKeyword(product); | 41 | const keyword = composeKeyword(product); |
42 | 42 | ||
43 | redisClient.get(keyword, (err, reply) => { | 43 | redisClient.get(keyword, (err, reply) => { |
44 | if (err) { | 44 | if (err) { |
45 | logger.warn(`277CFDD4 ${MODULE_NAME}: Error on get value on redis`, { | 45 | logger.warn(`277CFDD4 ${MODULE_NAME}: Error on get value on redis`, { |
46 | xid, product, eCode: err.code, eMessage: err.message, | 46 | xid, product, eCode: err.code, eMessage: err.message, |
47 | }); | 47 | }); |
48 | 48 | ||
49 | resolve(null); | 49 | resolve(null); |
50 | return; | 50 | return; |
51 | } | 51 | } |
52 | 52 | ||
53 | if (!reply) { | 53 | if (!reply) { |
54 | resolve(); | 54 | resolve(); |
55 | return; | 55 | return; |
56 | } | 56 | } |
57 | 57 | ||
58 | resolve(Number(reply)); | 58 | resolve(Number(reply)); |
59 | }); | 59 | }); |
60 | }); | 60 | }); |
61 | exports.get = get; | 61 | exports.get = get; |
62 | 62 | ||
63 | const isLimited = (product, xid) => new Promise((resolve) => { | 63 | const isLimited = (product, xid) => new Promise((resolve) => { |
64 | const supplier = config.handler_name; | 64 | const supplier = config.handler_name; |
65 | const val = JSON.stringify({ supplier, product }); | 65 | const val = JSON.stringify({ supplier, product }); |
66 | 66 | ||
67 | redisClient.sismember(LIMITED_SET_NAME, val, (err, reply) => { | 67 | redisClient.sismember(LIMITED_SET_NAME, val, (err, reply) => { |
68 | if (err) { | 68 | if (err) { |
69 | logger.warn(`20D042AC ${MODULE_NAME}: Error on checking if on managed set`, { | 69 | logger.warn(`20D042AC ${MODULE_NAME}: Error on checking if on managed set`, { |
70 | xid, product, eCode: err.code, eMessage: err.message, | 70 | xid, product, eCode: err.code, eMessage: err.message, |
71 | }); | 71 | }); |
72 | 72 | ||
73 | resolve(null); | 73 | resolve(null); |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
77 | resolve(!!reply); | 77 | resolve(!!reply); |
78 | }); | 78 | }); |
79 | }); | 79 | }); |
80 | exports.isLimited = isLimited; | 80 | exports.isLimited = isLimited; |
81 | 81 | ||
82 | const addToLimited = (product, xid) => new Promise((resolve) => { | 82 | const addToLimited = (product, xid) => new Promise((resolve) => { |
83 | if (!(product || '').trim()) { | 83 | if (!(product || '').trim()) { |
84 | resolve(); | 84 | resolve(); |
85 | return; | 85 | return; |
86 | } | 86 | } |
87 | 87 | ||
88 | const supplier = config.handler_name; | 88 | const supplier = config.handler_name; |
89 | const val = JSON.stringify({ supplier, product: product.trim().toUpperCase() }); | 89 | const val = JSON.stringify({ supplier, product: product.trim().toUpperCase() }); |
90 | 90 | ||
91 | redisClient.sadd(LIMITED_SET_NAME, val, (err, reply) => { | 91 | redisClient.sadd(LIMITED_SET_NAME, val, (err, reply) => { |
92 | if (err) { | 92 | if (err) { |
93 | logger.warn(`E5AA0994 ${MODULE_NAME}: Error on add to managed set`, { | 93 | logger.warn(`E5AA0994 ${MODULE_NAME}: Error on add to managed set`, { |
94 | xid, product, eCode: err.code, eMessage: err.message, | 94 | xid, product, eCode: err.code, eMessage: err.message, |
95 | }); | 95 | }); |
96 | 96 | ||
97 | resolve(); | 97 | resolve(); |
98 | return; | 98 | return; |
99 | } | 99 | } |
100 | 100 | ||
101 | resolve(reply); | 101 | resolve(reply); |
102 | }); | 102 | }); |
103 | }); | 103 | }); |
104 | exports.addToLimited = addToLimited; | 104 | exports.addToLimited = addToLimited; |
105 | 105 | ||
106 | const removeFromLimited = (product, xid) => new Promise((resolve) => { | 106 | const removeFromLimited = (product, xid) => new Promise((resolve) => { |
107 | const supplier = config.handler_name; | 107 | const supplier = config.handler_name; |
108 | const val = JSON.stringify({ supplier, product }); | 108 | const val = JSON.stringify({ supplier, product }); |
109 | 109 | ||
110 | redisClient.srem(LIMITED_SET_NAME, val, (err, reply) => { | 110 | redisClient.srem(LIMITED_SET_NAME, val, (err, reply) => { |
111 | if (err) { | 111 | if (err) { |
112 | logger.warn(`DD5CBDF2 ${MODULE_NAME}: Error on remove from managed set`, { | 112 | logger.warn(`DD5CBDF2 ${MODULE_NAME}: Error on remove from managed set`, { |
113 | xid, product, eCode: err.code, eMessage: err.message, | 113 | xid, product, eCode: err.code, eMessage: err.message, |
114 | }); | 114 | }); |
115 | 115 | ||
116 | resolve(); | 116 | resolve(); |
117 | return; | 117 | return; |
118 | } | 118 | } |
119 | 119 | ||
120 | resolve(reply); | 120 | resolve(reply); |
121 | }); | 121 | }); |
122 | }); | 122 | }); |
123 | exports.removeFromLimited = removeFromLimited; | 123 | exports.removeFromLimited = removeFromLimited; |
124 | 124 | ||
125 | const setLimit = async (product, newValue, xid) => { | 125 | const setLimit = async (product, newValue, xid) => { |
126 | await addToLimited(product, xid); | 126 | await addToLimited(product, xid); |
127 | await set(product, Number(newValue)); | 127 | await set(product, Number(newValue)); |
128 | }; | 128 | }; |
129 | exports.setLimit = setLimit; | 129 | exports.setLimit = setLimit; |
130 | 130 | ||
131 | const decrement = (product, xid) => new Promise((resolve) => { | 131 | const decrement = (product, xid) => new Promise((resolve) => { |
132 | const keyword = composeKeyword(product); | 132 | const keyword = composeKeyword(product); |
133 | 133 | ||
134 | redisClient.decr(keyword, (err, reply) => { | 134 | redisClient.decr(keyword, (err, reply) => { |
135 | if (err) { | 135 | if (err) { |
136 | logger.warn(`BA176849 ${MODULE_NAME}: Error on decrementing value`, { | 136 | logger.warn(`BA176849 ${MODULE_NAME}: Error on decrementing value`, { |
137 | xid, product, eCode: err.code, eMessage: err.message, | 137 | xid, product, eCode: err.code, eMessage: err.message, |
138 | }); | 138 | }); |
139 | 139 | ||
140 | resolve(null); | 140 | resolve(null); |
141 | return; | 141 | return; |
142 | } | 142 | } |
143 | 143 | ||
144 | redisClient.expire(keyword, DEFAULT_TTL); | 144 | redisClient.expire(keyword, DEFAULT_TTL); |
145 | 145 | ||
146 | resolve(reply); | 146 | resolve(reply); |
147 | }); | 147 | }); |
148 | }); | 148 | }); |
149 | exports.decrement = decrement; | 149 | exports.decrement = decrement; |
150 | 150 | ||
151 | const increment = (product, xid) => new Promise((resolve) => { | ||
152 | const keyword = composeKeyword(product); | ||
153 | |||
154 | redisClient.incr(keyword, (err, reply) => { | ||
155 | if (err) { | ||
156 | logger.warn(`8DA99C28 ${MODULE_NAME}: Error on incrementing`, { | ||
157 | xid, product, eCode: err.code, eMessage: err.message, | ||
158 | }); | ||
159 | |||
160 | redisClient.expire(keyword, DEFAULT_TTL); | ||
161 | |||
162 | resolve(null); | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | resolve(reply); | ||
167 | }); | ||
168 | }); | ||
169 | |||
151 | const incrementBy = (product, val, xid) => new Promise((resolve) => { | 170 | const incrementBy = (product, val, xid) => new Promise((resolve) => { |
152 | const keyword = composeKeyword(product); | 171 | const keyword = composeKeyword(product); |
153 | 172 | ||
154 | redisClient.incrby(keyword, Math.trunc(Number(val)), (err, reply) => { | 173 | redisClient.incrby(keyword, Math.trunc(Number(val)), (err, reply) => { |
155 | if (err) { | 174 | if (err) { |
156 | logger.warn(`83038699 ${MODULE_NAME}: Error on incrementing by`, { | 175 | logger.warn(`83038699 ${MODULE_NAME}: Error on incrementing by`, { |
157 | xid, product, eCode: err.code, eMessage: err.message, | 176 | xid, product, eCode: err.code, eMessage: err.message, |
158 | }); | 177 | }); |
159 | 178 | ||
160 | redisClient.expire(keyword, DEFAULT_TTL); | 179 | redisClient.expire(keyword, DEFAULT_TTL); |
161 | 180 | ||
162 | resolve(null); | 181 | resolve(null); |
163 | return; | 182 | return; |
164 | } | 183 | } |
165 | 184 | ||
166 | resolve(reply); | 185 | resolve(reply); |
167 | }); | 186 | }); |
168 | }); | 187 | }); |
169 | exports.incrementBy = incrementBy; | 188 | exports.incrementBy = incrementBy; |
170 | 189 | ||
171 | const dispose = async (product, xid) => { | 190 | const dispose = async (product, xid) => { |
172 | if (!await isLimited(product, xid)) { | 191 | if (!await isLimited(product, xid)) { |
173 | return true; | 192 | return true; |
174 | } | 193 | } |
175 | 194 | ||
176 | const remaining = await decrement(product, xid); | 195 | const remaining = await decrement(product, xid); |
177 | if (!remaining && remaining !== 0) { | 196 | if (!remaining && remaining !== 0) { |
178 | return true; | 197 | return true; |
179 | } | 198 | } |
180 | 199 | ||
181 | if (remaining < 0) { | 200 | if (remaining < 0) { |
182 | await set(product, 0, xid); | 201 | await set(product, 0, xid); |
183 | return 0; | 202 | return 0; |
184 | } | 203 | } |
185 | 204 | ||
186 | return remaining; | 205 | return remaining; |
187 | }; | 206 | }; |
188 | exports.dispose = dispose; | 207 | exports.dispose = dispose; |
189 | 208 | ||
209 | const putBack = async (product, xid) => { | ||
210 | if (!await isLimited(product, xid)) { | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | await increment(product, xid); | ||
215 | }; | ||
216 | exports.putBack = putBack; | ||
217 | |||
190 | const limitedList = (xid) => new Promise((resolve, reject) => { | 218 | const limitedList = (xid) => new Promise((resolve, reject) => { |
191 | redisClient.smembers(LIMITED_SET_NAME, (err, reply) => { | 219 | redisClient.smembers(LIMITED_SET_NAME, (err, reply) => { |
192 | if (err) { | 220 | if (err) { |
193 | const newError = new Error('Error getting limited list'); | 221 | const newError = new Error('Error getting limited list'); |
194 | newError.code = 'BA176849'; | 222 | newError.code = 'BA176849'; |
195 | logger.warn(`BA176849 ${MODULE_NAME}: ${newError.message}`, { | 223 | logger.warn(`BA176849 ${MODULE_NAME}: ${newError.message}`, { |
196 | xid, eCode: err.code, eMessage: err.message, newErrCode: newError.code, | 224 | xid, eCode: err.code, eMessage: err.message, newErrCode: newError.code, |
197 | }); | 225 | }); |
198 | 226 | ||
199 | reject(newError); | 227 | reject(newError); |
200 | return; | 228 | return; |
201 | } | 229 | } |
202 | 230 | ||
203 | const result = (reply || []) | 231 | const result = (reply || []) |
204 | .map((item) => JSON.parse(item)); | 232 | .map((item) => JSON.parse(item)); |
205 | 233 | ||
206 | resolve( | 234 | resolve( |
207 | orderBy( | 235 | orderBy( |
208 | result, | 236 | result, |
209 | [(item) => item.supplier, (item) => item.product], | 237 | [(item) => item.supplier, (item) => item.product], |
210 | ['asc', 'asc'], | 238 | ['asc', 'asc'], |
211 | ), | 239 | ), |
212 | ); | 240 | ); |
213 | }); | 241 | }); |
214 | }); | 242 | }); |
215 | exports.limitedList = limitedList; | 243 | exports.limitedList = limitedList; |
216 | 244 |