const MODULE_NAME = 'SDK-SUPPLIER-PRODUCT-QUOTA.REDIS-UTIL'; const DEFAULT_TTL = 3600 * 24 * 90; const LIMITED_SET_NAME = 'SPQ_8FB2B6EC_MANAGED'; const redis = require('redis'); const { orderBy } = require('natural-orderby'); const config = require('komodo-sdk/config'); const logger = require('komodo-sdk/logger'); const redisClient = redis.createClient(); const composeKeyword = (product) => `SPQ_F7D526DB_COUNTER_${config.handler_name}_${product.trim().toUpperCase()}`; const set = (product, val, xid) => new Promise((resolve) => { if (!(product || '').trim()) { resolve(); return; } const keyword = composeKeyword(product); redisClient.set(keyword, Number(val), 'EX', DEFAULT_TTL, (err) => { if (err) { logger.warn(`F7D526DB ${MODULE_NAME}: Error on set value on redis`, { xid, product, val, eCode: err.code, eMessage: err.message, }); resolve(); return; } resolve(val); }); }); const get = (product, xid) => new Promise((resolve) => { if (!(product || '').trim()) { resolve(); return; } const keyword = composeKeyword(product); redisClient.get(keyword, (err, reply) => { if (err) { logger.warn(`277CFDD4 ${MODULE_NAME}: Error on get value on redis`, { xid, product, eCode: err.code, eMessage: err.message, }); resolve(null); return; } if (!reply) { resolve(); return; } resolve(Number(reply)); }); }); exports.get = get; const isLimited = (product, xid) => new Promise((resolve) => { const supplier = config.handler_name; const val = JSON.stringify({ supplier, product }); redisClient.sismember(LIMITED_SET_NAME, val, (err, reply) => { if (err) { logger.warn(`20D042AC ${MODULE_NAME}: Error on checking if on managed set`, { xid, product, eCode: err.code, eMessage: err.message, }); resolve(null); return; } resolve(!!reply); }); }); exports.isLimited = isLimited; const addToLimited = (product, xid) => new Promise((resolve) => { if (!(product || '').trim()) { resolve(); return; } const supplier = config.handler_name; const val = JSON.stringify({ supplier, product: product.trim().toUpperCase() }); redisClient.sadd(LIMITED_SET_NAME, val, (err, reply) => { if (err) { logger.warn(`E5AA0994 ${MODULE_NAME}: Error on add to managed set`, { xid, product, eCode: err.code, eMessage: err.message, }); resolve(); return; } resolve(reply); }); }); exports.addToLimited = addToLimited; const removeFromLimited = (product, xid) => new Promise((resolve) => { const supplier = config.handler_name; const val = JSON.stringify({ supplier, product }); redisClient.srem(LIMITED_SET_NAME, val, (err, reply) => { if (err) { logger.warn(`DD5CBDF2 ${MODULE_NAME}: Error on remove from managed set`, { xid, product, eCode: err.code, eMessage: err.message, }); resolve(); return; } resolve(reply); }); }); exports.removeFromLimited = removeFromLimited; const setLimit = async (product, newValue, xid) => { await addToLimited(product, xid); await set(product, Number(newValue)); }; exports.setLimit = setLimit; const decrement = (product, xid) => new Promise((resolve) => { const keyword = composeKeyword(product); redisClient.decr(keyword, (err, reply) => { if (err) { logger.warn(`BA176849 ${MODULE_NAME}: Error on decrementing value`, { xid, product, eCode: err.code, eMessage: err.message, }); resolve(null); return; } redisClient.expire(keyword, DEFAULT_TTL); resolve(reply); }); }); exports.decrement = decrement; const increment = (product, xid) => new Promise((resolve) => { const keyword = composeKeyword(product); redisClient.incr(keyword, (err, reply) => { if (err) { logger.warn(`8DA99C28 ${MODULE_NAME}: Error on incrementing`, { xid, product, eCode: err.code, eMessage: err.message, }); redisClient.expire(keyword, DEFAULT_TTL); resolve(null); return; } resolve(reply); }); }); const incrementBy = (product, val, xid) => new Promise((resolve) => { const keyword = composeKeyword(product); redisClient.incrby(keyword, Math.trunc(Number(val)), (err, reply) => { if (err) { logger.warn(`83038699 ${MODULE_NAME}: Error on incrementing by`, { xid, product, eCode: err.code, eMessage: err.message, }); redisClient.expire(keyword, DEFAULT_TTL); resolve(null); return; } resolve(reply); }); }); exports.incrementBy = incrementBy; const dispose = async (product, xid) => { if (!await isLimited(product, xid)) { return true; } const remaining = await decrement(product, xid); if (!remaining && remaining !== 0) { return true; } if (remaining < 0) { await set(product, 0, xid); return 0; } return remaining; }; exports.dispose = dispose; const putBack = async (product, xid) => { if (!await isLimited(product, xid)) { return; } await increment(product, xid); }; exports.putBack = putBack; const limitedList = (xid) => new Promise((resolve, reject) => { redisClient.smembers(LIMITED_SET_NAME, (err, reply) => { if (err) { const newError = new Error('Error getting limited list'); newError.code = 'BA176849'; logger.warn(`BA176849 ${MODULE_NAME}: ${newError.message}`, { xid, eCode: err.code, eMessage: err.message, newErrCode: newError.code, }); reject(newError); return; } const result = (reply || []) .map((item) => JSON.parse(item)); resolve( orderBy( result, [(item) => item.supplier, (item) => item.product], ['asc', 'asc'], ), ); }); }); exports.limitedList = limitedList;