Commit b644ba997670b5e5587fc610083d34c23551b687
1 parent
1031749311
Exists in
master
and in
1 other branch
modems.randomModemByPrefix
Showing 2 changed files with 270 additions and 7 deletions Inline Diff
lib/modems.js
1 | /* eslint-disable no-console */ | 1 | /* eslint-disable no-console */ |
2 | const DEBUG = !!process.env.DEBUG_KOMODO_CENTER_CP_EVO_MODEMS; | 2 | const DEBUG = !!process.env.DEBUG_KOMODO_CENTER_CP_EVO_MODEMS; |
3 | 3 | ||
4 | const config = require('komodo-sdk/config'); | 4 | const config = require('komodo-sdk/config'); |
5 | 5 | ||
6 | exports.modemsDictionary = (arrayOfModem) => { | 6 | exports.modemsDictionary = (arrayOfModem) => { |
7 | const modems = arrayOfModem || config.modems || []; | 7 | const modems = arrayOfModem || config.modems || []; |
8 | const retval = {}; | 8 | const retval = {}; |
9 | modems.forEach((modem) => { | 9 | modems.forEach((modem) => { |
10 | retval[modem.name] = modem; | 10 | retval[modem.name] = modem; |
11 | }); | 11 | }); |
12 | return retval; | 12 | return retval; |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /** | 15 | /** |
16 | * deprecated | 16 | * deprecated |
17 | */ | 17 | */ |
18 | exports.enabledModems = (arrayOfModem) => { | 18 | exports.enabledModems = (arrayOfModem) => { |
19 | const modems = arrayOfModem || config.modems || []; | 19 | const modems = arrayOfModem || config.modems || []; |
20 | return modems.filter((modem) => !modem.disabled); | 20 | return modems.filter((modem) => !modem.disabled); |
21 | }; | 21 | }; |
22 | 22 | ||
23 | exports.outgoingModems = (arrayOfModem) => { | 23 | exports.outgoingModems = (arrayOfModem) => { |
24 | const modems = arrayOfModem || config.modems || []; | 24 | const modems = arrayOfModem || config.modems || []; |
25 | return modems.filter((modem) => modem.outgoing); | 25 | return modems.filter((modem) => modem.outgoing); |
26 | }; | 26 | }; |
27 | 27 | ||
28 | exports.OUTGOING_MODEMS = this.outgoingModems(); | ||
29 | |||
30 | exports.prefixes = (arrayOfModem) => { | ||
31 | const prefixModemsObject = {}; | ||
32 | const prefixModemsArray = []; | ||
33 | |||
34 | const modems = this.outgoingModems(arrayOfModem); | ||
35 | modems.forEach((modem) => { | ||
36 | const modemPrefixes = modem.prefix || []; | ||
37 | modemPrefixes.forEach((prefix) => { | ||
38 | const normalizedPrefix = prefix.trim().replace(/^0/, '62'); | ||
39 | |||
40 | if (!prefixModemsObject[normalizedPrefix]) { | ||
41 | prefixModemsObject[normalizedPrefix] = [modem.name]; | ||
42 | } else { | ||
43 | prefixModemsObject[normalizedPrefix].push(modem.name); | ||
44 | } | ||
45 | }); | ||
46 | }); | ||
47 | |||
48 | // eslint-disable-next-line no-restricted-syntax | ||
49 | for (const [prefix, value] of Object.entries(prefixModemsObject)) { | ||
50 | prefixModemsArray.push({ prefix, modems: value }); | ||
51 | } | ||
52 | |||
53 | const retval = prefixModemsArray.sort((a, b) => { | ||
54 | if (a.prefix.length < b.prefix.length) return 1; | ||
55 | if (a.prefix.length > b.prefix.length) return -1; | ||
56 | |||
57 | if (a < b) return -1; | ||
58 | if (a > b) return 1; | ||
59 | return 0; | ||
60 | }); | ||
61 | |||
62 | retval.forEach((item) => { | ||
63 | // eslint-disable-next-line no-param-reassign | ||
64 | item.modems = item.modems.sort((a, b) => { | ||
65 | if (a < b) return -1; | ||
66 | if (a > b) return 1; | ||
67 | return 0; | ||
68 | }); | ||
69 | }); | ||
70 | |||
71 | return retval; | ||
72 | }; | ||
73 | |||
28 | exports.randomModem = (arrayOfModem) => { | 74 | exports.randomModem = (arrayOfModem) => { |
29 | const modems = this.outgoingModems(arrayOfModem); | 75 | const modems = this.outgoingModems(arrayOfModem); |
30 | 76 | ||
31 | if (DEBUG) { | 77 | if (DEBUG) { |
32 | console.log('DEBUG_MODEMS: Get random modems', { | 78 | console.log('DEBUG_MODEMS: Get random modems', { |
33 | haystack: modems, | 79 | haystack: modems, |
34 | }); | 80 | }); |
35 | } | 81 | } |
36 | const modemCount = modems.length; | 82 | const modemCount = modems.length; |
37 | 83 | ||
38 | if (!modemCount) return null; | 84 | if (!modemCount) return null; |
39 | 85 | ||
40 | const idx = Math.floor(Math.random() * modemCount); | 86 | const idx = Math.floor(Math.random() * modemCount); |
41 | return modems[idx]; | 87 | return modems[idx]; |
42 | }; | 88 | }; |
89 | |||
90 | exports.findPrefixForNumber = (number, prefixes) => prefixes.find( | ||
91 | (item) => number.replace(/^0/, '62').indexOf(item.prefix) === 0, | ||
92 | ); | ||
93 | |||
94 | exports.isFreePrefixModem = (modem) => !modem.prefix || !modem.prefix.length; | ||
95 | |||
96 | exports.randomModemByPrefix = (number, arrayOfModem) => { | ||
97 | const modems = this.outgoingModems(arrayOfModem); | ||
98 | const prefixes = this.prefixes(arrayOfModem); | ||
99 | const prefix = this.findPrefixForNumber(number, prefixes); | ||
100 | const modemNamesForPrefix = (prefix || {}).modems; | ||
101 | |||
102 | if (modemNamesForPrefix && modemNamesForPrefix.length) { | ||
103 | const count = modemNamesForPrefix.length; | ||
104 | const idx = Math.floor(Math.random() * count); | ||
105 | const modemName = modemNamesForPrefix[idx]; | ||
106 | |||
107 | return modems.find((modem) => modem.name === modemName); | ||
108 | } | ||
109 | |||
110 | const freeModems = modems.filter((modem) => this.isFreePrefixModem(modem)); | ||
111 | const count = freeModems.length; | ||
112 | const idx = Math.floor(Math.random() * count); | ||
113 | return freeModems[idx]; | ||
114 | }; | ||
43 | 115 |
test/modems.js
1 | /* eslint-disable no-console */ | ||
1 | /* global describe it */ | 2 | /* global describe it */ |
2 | const modems = require('../lib/modems'); | 3 | const modems = require('../lib/modems'); |
3 | 4 | ||
4 | require('should'); | 5 | const should = require('should'); |
5 | 6 | ||
6 | describe('#modems', () => { | 7 | describe('#modems', () => { |
7 | describe('#enabledModems', () => { | 8 | describe('#enabledModems', () => { |
8 | const test1 = modems.enabledModems([ | 9 | it('should return correctly', () => { |
10 | const test1 = modems.enabledModems([ | ||
11 | { | ||
12 | name: 'SENDER-AS13', | ||
13 | disabled: false, | ||
14 | outgoing: true, | ||
15 | imsi: null, | ||
16 | prefix: [], | ||
17 | }, | ||
18 | ]); | ||
19 | |||
20 | test1.should.ok(); | ||
21 | }); | ||
22 | }); | ||
23 | |||
24 | describe('#prefixes', () => { | ||
25 | it('should return correctly', () => { | ||
26 | const config = [ | ||
27 | { | ||
28 | name: 'XL1', | ||
29 | outgoing: true, | ||
30 | prefix: ['0818', '081'], | ||
31 | }, | ||
32 | { | ||
33 | name: 'TSEL1', | ||
34 | outgoing: true, | ||
35 | prefix: ['0812', '0811'], | ||
36 | }, | ||
37 | { | ||
38 | name: 'TSEL2', | ||
39 | outgoing: true, | ||
40 | prefix: ['0812', '0811'], | ||
41 | }, | ||
42 | { | ||
43 | name: 'ISAT1', | ||
44 | outgoing: true, | ||
45 | prefix: ['0815', '0816'], | ||
46 | }, | ||
47 | ]; | ||
48 | |||
49 | const prefixes = modems.prefixes(config); | ||
50 | |||
51 | prefixes[0].prefix.should.equal('62811'); | ||
52 | prefixes[1].prefix.should.equal('62812'); | ||
53 | prefixes[2].prefix.should.equal('62815'); | ||
54 | prefixes[3].prefix.should.equal('62816'); | ||
55 | prefixes[4].prefix.should.equal('62818'); | ||
56 | prefixes[5].prefix.should.equal('6281'); | ||
57 | |||
58 | prefixes[0].modems[0].should.equal('TSEL1'); | ||
59 | prefixes[0].modems[1].should.equal('TSEL2'); | ||
60 | prefixes[1].modems[0].should.equal('TSEL1'); | ||
61 | prefixes[1].modems[1].should.equal('TSEL2'); | ||
62 | prefixes[2].modems[0].should.equal('ISAT1'); | ||
63 | prefixes[3].modems[0].should.equal('ISAT1'); | ||
64 | prefixes[4].modems[0].should.equal('XL1'); | ||
65 | prefixes[5].modems[0].should.equal('XL1'); | ||
66 | }); | ||
67 | }); | ||
68 | |||
69 | describe('#findPrefixForNumber', () => { | ||
70 | it('should return correct prefix', () => { | ||
71 | const config = [ | ||
72 | { | ||
73 | name: 'XL1', | ||
74 | outgoing: true, | ||
75 | prefix: ['0818', '081'], | ||
76 | }, | ||
77 | { | ||
78 | name: 'TSEL1', | ||
79 | outgoing: true, | ||
80 | prefix: ['0812', '0811'], | ||
81 | }, | ||
82 | { | ||
83 | name: 'TSEL2', | ||
84 | outgoing: true, | ||
85 | prefix: ['0812', '0811'], | ||
86 | }, | ||
87 | { | ||
88 | name: 'ISAT1', | ||
89 | outgoing: true, | ||
90 | prefix: ['0815', '0816'], | ||
91 | }, | ||
92 | { | ||
93 | name: 'FREE1', | ||
94 | outgoing: true, | ||
95 | prefix: [], | ||
96 | }, | ||
97 | { | ||
98 | name: 'FREE2', | ||
99 | outgoing: true, | ||
100 | prefix: [], | ||
101 | }, | ||
102 | ]; | ||
103 | |||
104 | const prefixes = modems.prefixes(config); | ||
105 | modems.findPrefixForNumber('628188188', prefixes).prefix.should.equal('62818'); | ||
106 | modems.findPrefixForNumber('08188188', prefixes).prefix.should.equal('62818'); | ||
107 | modems.findPrefixForNumber('62812812', prefixes).prefix.should.equal('62812'); | ||
108 | modems.findPrefixForNumber('62810810', prefixes).prefix.should.equal('6281'); | ||
109 | should.not.exists(modems.findPrefixForNumber('6221212121', prefixes)); | ||
110 | }); | ||
111 | }); | ||
112 | |||
113 | describe('#randomModemByPrefix', () => { | ||
114 | const config = [ | ||
115 | { | ||
116 | name: 'XL1', | ||
117 | outgoing: true, | ||
118 | prefix: ['0818', '081'], | ||
119 | }, | ||
120 | { | ||
121 | name: 'TSEL1', | ||
122 | outgoing: true, | ||
123 | prefix: ['0812', '0811'], | ||
124 | }, | ||
9 | { | 125 | { |
10 | name: 'SENDER-AS13', | 126 | name: 'TSEL2', |
11 | disabled: false, | 127 | outgoing: true, |
128 | prefix: ['0812', '0811'], | ||
129 | }, | ||
130 | { | ||
131 | name: 'ISAT1', | ||
132 | outgoing: true, | ||
133 | prefix: ['0815', '0816'], | ||
134 | }, | ||
135 | { | ||
136 | name: 'FREE1', | ||
137 | outgoing: true, | ||
138 | prefix: [], | ||
139 | }, | ||
140 | { | ||
141 | name: 'FREE2', | ||
12 | outgoing: true, | 142 | outgoing: true, |
13 | imsi: null, | ||
14 | prefix: [], | 143 | prefix: [], |
15 | }, | 144 | }, |
16 | ]); | 145 | ]; |
146 | |||
147 | const loopCount = 100; | ||
148 | |||
149 | it('should return correctly for XL', () => { | ||
150 | for (let i = 0; i < loopCount; i += 1) { | ||
151 | modems.randomModemByPrefix('6281881818', config).name.should.equal('XL1'); | ||
152 | } | ||
153 | }); | ||
154 | |||
155 | it('should return correctly for TSEL', () => { | ||
156 | for (let i = 0; i < loopCount; i += 1) { | ||
157 | modems.randomModemByPrefix('62812812', config).name.should.equalOneOf('TSEL1', 'TSEL2'); | ||
158 | } | ||
159 | }); | ||
160 | |||
161 | it('should return correctly for INDOSAT', () => { | ||
162 | for (let i = 0; i < loopCount; i += 1) { | ||
163 | modems.randomModemByPrefix('62815815', config).name.should.equal('ISAT1'); | ||
164 | } | ||
165 | }); | ||
166 | |||
167 | it('should return correctly for UNKNOWN PREFIX', () => { | ||
168 | for (let i = 0; i < loopCount; i += 1) { | ||
169 | modems.randomModemByPrefix('628888888', config).name.should.equalOneOf('FREE1', 'FREE2'); | ||
170 | } | ||
171 | }); | ||
172 | |||
173 | it('should handle UNKNOWN PREFIX without free modem', () => { | ||
174 | // eslint-disable-next-line no-shadow | ||
175 | const config = [ | ||
176 | { | ||
177 | name: 'XL1', | ||
178 | outgoing: true, | ||
179 | prefix: ['0818', '081'], | ||
180 | }, | ||
181 | { | ||
182 | name: 'TSEL1', | ||
183 | outgoing: true, | ||
184 | prefix: ['0812', '0811'], | ||
185 | }, | ||
186 | { | ||
187 | name: 'TSEL2', | ||
188 | outgoing: true, | ||
189 | prefix: ['0812', '0811'], | ||
190 | }, | ||
191 | { | ||
192 | name: 'ISAT1', | ||
193 | outgoing: true, | ||
194 | prefix: ['0815', '0816'], | ||
195 | }, | ||
196 | { | ||
197 | name: 'FREE1', | ||
198 | outgoing: false, | ||
199 | prefix: [], | ||
200 | }, | ||
201 | { | ||
202 | name: 'FREE2', | ||
203 | outgoing: false, | ||
204 | prefix: [], | ||
205 | }, | ||
206 | ]; | ||
17 | 207 | ||
18 | test1.should.ok(); | 208 | should.not.exists(modems.randomModemByPrefix('628888888', config)); |
209 | }); | ||
19 | }); | 210 | }); |
20 | }); | 211 | }); |