1
//! Program configurations.
2

            
3
use std::{collections::HashMap, env};
4

            
5
use clap::{
6
    builder::{BoolValueParser, RangedU64ValueParser},
7
    Arg, ArgMatches, Command,
8
};
9
use serde::Deserialize;
10

            
11
use sylvia_iot_corelib::constants::{CacheEngine, DbEngine};
12

            
13
/// Configuration file object.
14
#[derive(Default, Deserialize)]
15
pub struct Config {
16
    /// **sylvia-iot-auth** API base path with host. For example: `http://localhost:1080/auth`.
17
    pub auth: Option<String>,
18
    pub db: Option<Db>,
19
    pub cache: Option<Cache>,
20
    pub mq: Option<Mq>,
21
    #[serde(rename = "mqChannels")]
22
    pub mq_channels: Option<MqChannels>,
23
    #[serde(rename = "apiScopes")]
24
    pub api_scopes: Option<HashMap<String, Vec<String>>>,
25
}
26

            
27
/// Database configuration object.
28
#[derive(Default, Deserialize)]
29
pub struct Db {
30
    /// Select the model implementation.
31
    /// - `mongodb`: pure MongoDB.
32
    /// - `sqlite`: pure SQLite.
33
    pub engine: Option<String>,
34
    pub mongodb: Option<MongoDb>,
35
    pub sqlite: Option<Sqlite>,
36
}
37

            
38
/// MongoDB configuration object.
39
#[derive(Default, Deserialize)]
40
pub struct MongoDb {
41
    /// Use `mongodb://username:password@host:port` format.
42
    pub url: Option<String>,
43
    pub database: Option<String>,
44
    #[serde(rename = "poolSize")]
45
    pub pool_size: Option<u32>,
46
}
47

            
48
/// SQLite configuration object.
49
#[derive(Default, Deserialize)]
50
pub struct Sqlite {
51
    /// Use absolute/relative path.
52
    pub path: Option<String>,
53
}
54

            
55
/// Cache configuration object.
56
#[derive(Default, Deserialize)]
57
pub struct Cache {
58
    /// Select the cache implementation.
59
    /// - `none`: disable cache.
60
    /// - `memory`: pure memory.
61
    pub engine: Option<String>,
62
    pub memory: Option<MemoryCache>,
63
}
64

            
65
/// Memory cache configuration object.
66
#[derive(Default, Deserialize)]
67
pub struct MemoryCache {
68
    /// Maximum number of device cache count.
69
    pub device: Option<usize>,
70
    /// Maximum number of device route cache count.
71
    #[serde(rename = "deviceRoute")]
72
    pub device_route: Option<usize>,
73
    /// Maximum number of network route cache count.
74
    #[serde(rename = "networkRoute")]
75
    pub network_route: Option<usize>,
76
}
77

            
78
/// Message queue configuration object.
79
#[derive(Default, Deserialize)]
80
pub struct Mq {
81
    /// AMQP QoS prefetch from **1** to **65535**. None or zero use default value **100**.
82
    pub prefetch: Option<u16>,
83
    /// AMQP persistent.
84
    pub persistent: Option<bool>,
85
    /// MQTT shared subscription topic prefix.
86
    #[serde(rename = "sharedPrefix")]
87
    pub shared_prefix: Option<String>,
88
}
89

            
90
/// Message channels configuration object.
91
#[derive(Default, Deserialize)]
92
pub struct MqChannels {
93
    pub unit: Option<BrokerCtrl>,
94
    pub application: Option<BrokerCtrl>,
95
    pub network: Option<BrokerCtrl>,
96
    pub device: Option<BrokerCtrl>,
97
    #[serde(rename = "deviceRoute")]
98
    pub device_route: Option<BrokerCtrl>,
99
    #[serde(rename = "networkRoute")]
100
    pub network_route: Option<BrokerCtrl>,
101
    pub data: Option<BrokerData>,
102
}
103

            
104
/// Channel `broker.ctrl` configuration object.
105
#[derive(Default, Deserialize)]
106
pub struct BrokerCtrl {
107
    /// Queue connection URL of the control channel.
108
    pub url: Option<String>,
109
    /// AMQP QoS prefetch from **1** to **65535**. None or zero use default value **100**.
110
    pub prefetch: Option<u16>,
111
}
112

            
113
/// Channel `broker.data` configuration object.
114
#[derive(Default, Deserialize)]
115
pub struct BrokerData {
116
    /// Queue connection URL of the data channel.
117
    pub url: Option<String>,
118
    /// AMQP persistent.
119
    pub persistent: Option<bool>,
120
}
121

            
122
pub const DEF_AUTH: &'static str = "http://localhost:1080/auth";
123
pub const DEF_ENGINE: &'static str = DbEngine::SQLITE;
124
pub const DEF_MONGODB_URL: &'static str = "mongodb://localhost:27017";
125
pub const DEF_MONGODB_DB: &'static str = "broker";
126
pub const DEF_SQLITE_PATH: &'static str = "broker.db";
127
pub const DEF_CACHE_ENGINE: &'static str = CacheEngine::NONE;
128
pub const DEF_MEMORY_DEVICE: usize = 1_000_000;
129
pub const DEF_MEMORY_DEVICE_ROUTE: usize = 1_000_000;
130
pub const DEF_MEMORY_NETWORK_ROUTE: usize = 1_000_000;
131
pub const DEF_MQ_PREFETCH: u16 = 100;
132
pub const DEF_MQ_PERSISTENT: bool = false;
133
pub const DEF_MQ_SHAREDPREFIX: &'static str = "$share/sylvia-iot-broker/";
134
pub const DEF_MQ_CHANNEL_URL: &'static str = "amqp://localhost";
135

            
136
/// To register Clap arguments.
137
16
pub fn reg_args(cmd: Command) -> Command {
138
16
    cmd.arg(
139
16
        Arg::new("broker.auth")
140
16
            .long("broker.auth")
141
16
            .help("sylvia-iot-auth host (ex: http://localhost:1080/auth)")
142
16
            .num_args(1),
143
16
    )
144
16
    .arg(
145
16
        Arg::new("broker.db.engine")
146
16
            .long("broker.db.engine")
147
16
            .help("database engine")
148
16
            .num_args(1)
149
16
            .value_parser([DbEngine::MONGODB, DbEngine::SQLITE]),
150
16
    )
151
16
    .arg(
152
16
        Arg::new("broker.db.mongodb.url")
153
16
            .long("broker.db.mongodb.url")
154
16
            .help("MongoDB URL (scheme://[username][:password][@][host][:port]")
155
16
            .num_args(1),
156
16
    )
157
16
    .arg(
158
16
        Arg::new("broker.db.mongodb.database")
159
16
            .long("broker.db.mongodb.database")
160
16
            .help("database nane")
161
16
            .num_args(1),
162
16
    )
163
16
    .arg(
164
16
        Arg::new("broker.db.mongodb.poolsize")
165
16
            .long("broker.db.mongodb.poolsize")
166
16
            .help("connection pool size")
167
16
            .num_args(1)
168
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u32::MAX as u64)),
169
16
    )
170
16
    .arg(
171
16
        Arg::new("broker.db.sqlite.path")
172
16
            .long("broker.db.sqlite.path")
173
16
            .help("SQLite path")
174
16
            .num_args(1),
175
16
    )
176
16
    .arg(
177
16
        Arg::new("broker.cache.engine")
178
16
            .long("broker.cache.engine")
179
16
            .help("cache engine")
180
16
            .num_args(1)
181
16
            .value_parser([CacheEngine::MEMORY, CacheEngine::NONE]),
182
16
    )
183
16
    .arg(
184
16
        Arg::new("broker.cache.memory.device")
185
16
            .long("broker.cache.memory.device")
186
16
            .help("Device cache size")
187
16
            .num_args(1)
188
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=usize::MAX as u64)),
189
16
    )
190
16
    .arg(
191
16
        Arg::new("broker.cache.memory.device-route")
192
16
            .long("broker.cache.memory.device-route")
193
16
            .help("Device route cache size")
194
16
            .num_args(1)
195
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=usize::MAX as u64)),
196
16
    )
197
16
    .arg(
198
16
        Arg::new("broker.cache.memory.network-route")
199
16
            .long("broker.cache.memory.network-route")
200
16
            .help("Network route cache size")
201
16
            .num_args(1)
202
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=usize::MAX as u64)),
203
16
    )
204
16
    .arg(
205
16
        Arg::new("broker.mq.prefetch")
206
16
            .long("broker.mq.prefetch")
207
16
            .help("AMQP prefetch")
208
16
            .num_args(1)
209
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
210
16
    )
211
16
    .arg(
212
16
        Arg::new("broker.mq.persistent")
213
16
            .long("broker.mq.persistent")
214
16
            .help("AMQP persistent")
215
16
            .num_args(1)
216
16
            .value_parser(BoolValueParser::new()),
217
16
    )
218
16
    .arg(
219
16
        Arg::new("broker.mq.sharedprefix")
220
16
            .long("broker.mq.sharedprefix")
221
16
            .help("MQTT shared subscription prefix")
222
16
            .num_args(1),
223
16
    )
224
16
    .arg(
225
16
        Arg::new("broker.mq-channels.unit.url")
226
16
            .long("broker.mq-channels.unit.url")
227
16
            .help("URL of `broker.ctrl.unit` channel")
228
16
            .num_args(1),
229
16
    )
230
16
    .arg(
231
16
        Arg::new("broker.mq-channels.unit.prefetch")
232
16
            .long("broker.mq-channels.unit.prefetch")
233
16
            .help("AMQP prefetch for `broker.ctrl.unit` channel")
234
16
            .num_args(1)
235
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
236
16
    )
237
16
    .arg(
238
16
        Arg::new("broker.mq-channels.application.url")
239
16
            .long("broker.mq-channels.application.url")
240
16
            .help("URL of `broker.ctrl.application` channel")
241
16
            .num_args(1),
242
16
    )
243
16
    .arg(
244
16
        Arg::new("broker.mq-channels.application.prefetch")
245
16
            .long("broker.mq-channels.application.prefetch")
246
16
            .help("AMQP prefetch for `broker.ctrl.application` channel")
247
16
            .num_args(1)
248
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
249
16
    )
250
16
    .arg(
251
16
        Arg::new("broker.mq-channels.network.url")
252
16
            .long("broker.mq-channels.network.url")
253
16
            .help("URL of `broker.ctrl.network` channel")
254
16
            .num_args(1),
255
16
    )
256
16
    .arg(
257
16
        Arg::new("broker.mq-channels.network.prefetch")
258
16
            .long("broker.mq-channels.network.prefetch")
259
16
            .help("AMQP prefetch for `broker.ctrl.network` channel")
260
16
            .num_args(1)
261
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
262
16
    )
263
16
    .arg(
264
16
        Arg::new("broker.mq-channels.device.url")
265
16
            .long("broker.mq-channels.device.url")
266
16
            .help("URL of `broker.ctrl.device` channel")
267
16
            .num_args(1),
268
16
    )
269
16
    .arg(
270
16
        Arg::new("broker.mq-channels.device.prefetch")
271
16
            .long("broker.mq-channels.device.prefetch")
272
16
            .help("AMQP prefetch for `broker.ctrl.device` channel")
273
16
            .num_args(1)
274
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
275
16
    )
276
16
    .arg(
277
16
        Arg::new("broker.mq-channels.device-route.url")
278
16
            .long("broker.mq-channels.device-route.url")
279
16
            .help("URL of `broker.ctrl.device-route` channel")
280
16
            .num_args(1),
281
16
    )
282
16
    .arg(
283
16
        Arg::new("broker.mq-channels.device-route.prefetch")
284
16
            .long("broker.mq-channels.device-route.prefetch")
285
16
            .help("AMQP prefetch for `broker.ctrl.device-route` channel")
286
16
            .num_args(1)
287
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
288
16
    )
289
16
    .arg(
290
16
        Arg::new("broker.mq-channels.network-route.url")
291
16
            .long("broker.mq-channels.network-route.url")
292
16
            .help("URL of `broker.ctrl.network-route` channel")
293
16
            .num_args(1),
294
16
    )
295
16
    .arg(
296
16
        Arg::new("broker.mq-channels.network-route.prefetch")
297
16
            .long("broker.mq-channels.network-route.prefetch")
298
16
            .help("AMQP prefetch for `broker.ctrl.network-route` channel")
299
16
            .num_args(1)
300
16
            .value_parser(RangedU64ValueParser::<u64>::new().range(1..=u16::MAX as u64)),
301
16
    )
302
16
    .arg(
303
16
        Arg::new("broker.mq-channels.data.url")
304
16
            .long("broker.mq-channels.data.url")
305
16
            .help("URL of `broker.data` channel")
306
16
            .num_args(1),
307
16
    )
308
16
    .arg(
309
16
        Arg::new("broker.mq-channels.data.persistent")
310
16
            .long("broker.mq-channels.data.persistent")
311
16
            .help("AMQP persistent for `broker.data` channel")
312
16
            .num_args(1)
313
16
            .value_parser(BoolValueParser::new()),
314
16
    )
315
16
    .arg(
316
16
        Arg::new("broker.api-scopes")
317
16
            .long("broker.api-scopes")
318
16
            .help("API scopes")
319
16
            .num_args(0..),
320
16
    )
321
16
}
322

            
323
/// To read input arguments from command-line arguments and environment variables.
324
///
325
/// This function will call [`apply_default()`] to fill missing values so you do not need call it
326
/// again.
327
16
pub fn read_args(args: &ArgMatches) -> Config {
328
16
    apply_default(&Config {
329
16
        auth: match args.get_one::<String>("broker.auth") {
330
12
            None => match env::var("BROKER_AUTH") {
331
6
                Err(_) => None,
332
6
                Ok(v) => Some(v),
333
            },
334
4
            Some(v) => Some(v.clone()),
335
        },
336
        db: Some(Db {
337
16
            engine: match args.get_one::<String>("broker.db.engine") {
338
10
                None => match env::var("BROKER_DB_ENGINE") {
339
4
                    Err(_) => None,
340
6
                    Ok(v) => Some(v),
341
                },
342
6
                Some(v) => Some(v.clone()),
343
            },
344
            mongodb: Some(MongoDb {
345
16
                url: match args.get_one::<String>("broker.db.mongodb.url") {
346
12
                    None => match env::var("BROKER_DB_MONGODB_URL") {
347
6
                        Err(_) => None,
348
6
                        Ok(v) => Some(v),
349
                    },
350
4
                    Some(v) => Some(v.clone()),
351
                },
352
16
                database: match args.get_one::<String>("broker.db.mongodb.database") {
353
12
                    None => match env::var("BROKER_DB_MONGODB_DATABASE") {
354
6
                        Err(_) => None,
355
6
                        Ok(v) => Some(v),
356
                    },
357
4
                    Some(v) => Some(v.clone()),
358
                },
359
16
                pool_size: match args.get_one::<u64>("broker.db.mongodb.poolsize") {
360
12
                    None => match env::var("BROKER_DB_MONGODB_POOLSIZE") {
361
6
                        Err(_) => None,
362
6
                        Ok(v) => match v.parse::<u32>() {
363
2
                            Err(_) => None,
364
4
                            Ok(v) => Some(v),
365
                        },
366
                    },
367
4
                    Some(v) => Some(*v as u32),
368
                },
369
            }),
370
            sqlite: Some(Sqlite {
371
16
                path: match args.get_one::<String>("broker.db.sqlite.path") {
372
12
                    None => match env::var("BROKER_DB_SQLITE_PATH") {
373
6
                        Err(_) => None,
374
6
                        Ok(v) => Some(v),
375
                    },
376
4
                    Some(v) => Some(v.clone()),
377
                },
378
            }),
379
        }),
380
        cache: Some(Cache {
381
16
            engine: match args.get_one::<String>("broker.cache.engine") {
382
10
                None => match env::var("BROKER_CACHE_ENGINE") {
383
4
                    Err(_) => None,
384
6
                    Ok(v) => Some(v),
385
                },
386
6
                Some(v) => Some(v.clone()),
387
            },
388
            memory: Some(MemoryCache {
389
16
                device: match args.get_one::<u64>("broker.cache.memory.device") {
390
12
                    None => match env::var("BROKER_CACHE_MEMORY_DEVICE") {
391
6
                        Err(_) => None,
392
6
                        Ok(v) => match v.parse::<usize>() {
393
2
                            Err(_) => None,
394
4
                            Ok(v) => Some(v),
395
                        },
396
                    },
397
4
                    Some(v) => Some(*v as usize),
398
                },
399
16
                device_route: match args.get_one::<u64>("broker.cache.memory.device-route") {
400
12
                    None => match env::var("BROKER_CACHE_MEMORY_DEVICE_ROUTE") {
401
6
                        Err(_) => None,
402
6
                        Ok(v) => match v.parse::<usize>() {
403
2
                            Err(_) => None,
404
4
                            Ok(v) => Some(v),
405
                        },
406
                    },
407
4
                    Some(v) => Some(*v as usize),
408
                },
409
16
                network_route: match args.get_one::<u64>("broker.cache.memory.network-route") {
410
12
                    None => match env::var("BROKER_CACHE_MEMORY_NETWORK_ROUTE") {
411
6
                        Err(_) => None,
412
6
                        Ok(v) => match v.parse::<usize>() {
413
2
                            Err(_) => None,
414
4
                            Ok(v) => Some(v),
415
                        },
416
                    },
417
4
                    Some(v) => Some(*v as usize),
418
                },
419
            }),
420
        }),
421
        mq: Some(Mq {
422
16
            prefetch: match args.get_one::<u64>("broker.mq.prefetch") {
423
12
                None => match env::var("BROKER_MQ_PREFETCH") {
424
6
                    Err(_) => None,
425
6
                    Ok(v) => match v.parse::<u16>() {
426
2
                        Err(_) => None,
427
4
                        Ok(v) => Some(v),
428
                    },
429
                },
430
4
                Some(v) => Some(*v as u16),
431
            },
432
16
            persistent: match args.get_one::<bool>("broker.mq.persistent") {
433
12
                None => match env::var("BROKER_MQ_PERSISTENT") {
434
6
                    Err(_) => None,
435
6
                    Ok(v) => match v.parse::<bool>() {
436
2
                        Err(_) => None,
437
4
                        Ok(v) => Some(v),
438
                    },
439
                },
440
4
                Some(v) => Some(*v as bool),
441
            },
442
16
            shared_prefix: match args.get_one::<String>("broker.mq.sharedprefix") {
443
10
                None => match env::var("BROKER_MQ_SHAREDPREFIX") {
444
4
                    Err(_) => None,
445
6
                    Ok(v) => Some(v),
446
                },
447
6
                Some(v) => Some(v.clone()),
448
            },
449
        }),
450
        mq_channels: Some(MqChannels {
451
            unit: Some(BrokerCtrl {
452
16
                url: match args.get_one::<String>("broker.mq-channels.unit.url") {
453
12
                    None => match env::var("BROKER_MQCHANNELS_UNIT_URL") {
454
6
                        Err(_) => None,
455
6
                        Ok(v) => Some(v),
456
                    },
457
4
                    Some(v) => Some(v.clone()),
458
                },
459
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.unit.prefetch") {
460
12
                    None => match env::var("BROKER_MQCHANNELS_UNIT_PREFETCH") {
461
6
                        Err(_) => None,
462
6
                        Ok(v) => match v.parse::<u16>() {
463
2
                            Err(_) => None,
464
4
                            Ok(v) => Some(v),
465
                        },
466
                    },
467
4
                    Some(v) => Some(*v as u16),
468
                },
469
            }),
470
            application: Some(BrokerCtrl {
471
16
                url: match args.get_one::<String>("broker.mq-channels.application.url") {
472
12
                    None => match env::var("BROKER_MQCHANNELS_APPLICATION_URL") {
473
6
                        Err(_) => None,
474
6
                        Ok(v) => Some(v),
475
                    },
476
4
                    Some(v) => Some(v.clone()),
477
                },
478
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.application.prefetch") {
479
12
                    None => match env::var("BROKER_MQCHANNELS_APPLICATION_PREFETCH") {
480
6
                        Err(_) => None,
481
6
                        Ok(v) => match v.parse::<u16>() {
482
2
                            Err(_) => None,
483
4
                            Ok(v) => Some(v),
484
                        },
485
                    },
486
4
                    Some(v) => Some(*v as u16),
487
                },
488
            }),
489
            network: Some(BrokerCtrl {
490
16
                url: match args.get_one::<String>("broker.mq-channels.network.url") {
491
12
                    None => match env::var("BROKER_MQCHANNELS_NETWORK_URL") {
492
6
                        Err(_) => None,
493
6
                        Ok(v) => Some(v),
494
                    },
495
4
                    Some(v) => Some(v.clone()),
496
                },
497
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.network.prefetch") {
498
12
                    None => match env::var("BROKER_MQCHANNELS_NETWORK_PREFETCH") {
499
6
                        Err(_) => None,
500
6
                        Ok(v) => match v.parse::<u16>() {
501
2
                            Err(_) => None,
502
4
                            Ok(v) => Some(v),
503
                        },
504
                    },
505
4
                    Some(v) => Some(*v as u16),
506
                },
507
            }),
508
            device: Some(BrokerCtrl {
509
16
                url: match args.get_one::<String>("broker.mq-channels.device.url") {
510
12
                    None => match env::var("BROKER_MQCHANNELS_DEVICE_URL") {
511
6
                        Err(_) => None,
512
6
                        Ok(v) => Some(v),
513
                    },
514
4
                    Some(v) => Some(v.clone()),
515
                },
516
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.device.prefetch") {
517
12
                    None => match env::var("BROKER_MQCHANNELS_DEVICE_PREFETCH") {
518
6
                        Err(_) => None,
519
6
                        Ok(v) => match v.parse::<u16>() {
520
2
                            Err(_) => None,
521
4
                            Ok(v) => Some(v),
522
                        },
523
                    },
524
4
                    Some(v) => Some(*v as u16),
525
                },
526
            }),
527
            device_route: Some(BrokerCtrl {
528
16
                url: match args.get_one::<String>("broker.mq-channels.device-route.url") {
529
12
                    None => match env::var("BROKER_MQCHANNELS_DEVICE_ROUTE_URL") {
530
6
                        Err(_) => None,
531
6
                        Ok(v) => Some(v),
532
                    },
533
4
                    Some(v) => Some(v.clone()),
534
                },
535
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.device-route.prefetch") {
536
12
                    None => match env::var("BROKER_MQCHANNELS_DEVICE_ROUTE_PREFETCH") {
537
6
                        Err(_) => None,
538
6
                        Ok(v) => match v.parse::<u16>() {
539
2
                            Err(_) => None,
540
4
                            Ok(v) => Some(v),
541
                        },
542
                    },
543
4
                    Some(v) => Some(*v as u16),
544
                },
545
            }),
546
            network_route: Some(BrokerCtrl {
547
16
                url: match args.get_one::<String>("broker.mq-channels.network-route.url") {
548
12
                    None => match env::var("BROKER_MQCHANNELS_NETWORK_ROUTE_URL") {
549
6
                        Err(_) => None,
550
6
                        Ok(v) => Some(v),
551
                    },
552
4
                    Some(v) => Some(v.clone()),
553
                },
554
16
                prefetch: match args.get_one::<u64>("broker.mq-channels.network-route.prefetch") {
555
12
                    None => match env::var("BROKER_MQCHANNELS_NETWORK_ROUTE_PREFETCH") {
556
6
                        Err(_) => None,
557
6
                        Ok(v) => match v.parse::<u16>() {
558
2
                            Err(_) => None,
559
4
                            Ok(v) => Some(v),
560
                        },
561
                    },
562
4
                    Some(v) => Some(*v as u16),
563
                },
564
            }),
565
            data: Some(BrokerData {
566
16
                url: match args.get_one::<String>("broker.mq-channels.data.url") {
567
12
                    None => match env::var("BROKER_MQCHANNELS_DATA_URL") {
568
6
                        Err(_) => None,
569
6
                        Ok(v) => Some(v),
570
                    },
571
4
                    Some(v) => Some(v.clone()),
572
                },
573
16
                persistent: match args.get_one::<bool>("broker.mq-channels.data.persistent") {
574
10
                    None => match env::var("BROKER_MQCHANNELS_DATA_PERSISTENT") {
575
4
                        Err(_) => None,
576
6
                        Ok(v) => match v.parse::<bool>() {
577
2
                            Err(_) => None,
578
4
                            Ok(v) => Some(v),
579
                        },
580
                    },
581
6
                    Some(v) => Some(*v as bool),
582
                },
583
            }),
584
        }),
585
16
        api_scopes: match args.get_one::<String>("broker.api-scopes") {
586
8
            None => match env::var("BROKER_API_SCOPES") {
587
2
                Err(_) => None,
588
6
                Ok(v) => match v.len() {
589
2
                    0 => None,
590
4
                    _ => match serde_json::from_str::<HashMap<String, Vec<String>>>(v.as_str()) {
591
2
                        Err(_) => None,
592
2
                        Ok(v) => Some(v),
593
                    },
594
                },
595
            },
596
8
            Some(v) => match v.len() {
597
2
                0 => None,
598
6
                _ => match serde_json::from_str::<HashMap<String, Vec<String>>>(v.as_str()) {
599
2
                    Err(_) => None,
600
4
                    Ok(v) => Some(v),
601
                },
602
            },
603
        },
604
    })
605
16
}
606

            
607
/// Fill missing configuration with default values.
608
54
pub fn apply_default(config: &Config) -> Config {
609
54
    Config {
610
54
        auth: match config.auth.as_ref() {
611
18
            None => Some(DEF_AUTH.to_string()),
612
36
            Some(auth) => Some(auth.clone()),
613
        },
614
54
        db: match config.db.as_ref() {
615
4
            None => Some(Db {
616
4
                engine: Some(DEF_ENGINE.to_string()),
617
4
                mongodb: Some(MongoDb {
618
4
                    url: Some(DEF_MONGODB_URL.to_string()),
619
4
                    database: Some(DEF_MONGODB_DB.to_string()),
620
4
                    pool_size: None,
621
4
                }),
622
4
                sqlite: Some(Sqlite {
623
4
                    path: Some(DEF_SQLITE_PATH.to_string()),
624
4
                }),
625
4
            }),
626
50
            Some(db) => Some(Db {
627
50
                engine: match db.engine.as_ref() {
628
6
                    None => Some(DEF_ENGINE.to_string()),
629
44
                    Some(engine) => match engine.as_str() {
630
44
                        DbEngine::MONGODB => Some(DbEngine::MONGODB.to_string()),
631
26
                        DbEngine::SQLITE => Some(DbEngine::SQLITE.to_string()),
632
6
                        _ => Some(DEF_ENGINE.to_string()),
633
                    },
634
                },
635
50
                mongodb: match db.mongodb.as_ref() {
636
8
                    None => Some(MongoDb {
637
8
                        url: Some(DEF_MONGODB_URL.to_string()),
638
8
                        database: Some(DEF_MONGODB_DB.to_string()),
639
8
                        pool_size: None,
640
8
                    }),
641
42
                    Some(mongodb) => Some(MongoDb {
642
42
                        url: match mongodb.url.as_ref() {
643
6
                            None => Some(DEF_MONGODB_URL.to_string()),
644
36
                            Some(url) => Some(url.to_string()),
645
                        },
646
42
                        database: match mongodb.database.as_ref() {
647
6
                            None => Some(DEF_MONGODB_DB.to_string()),
648
36
                            Some(database) => Some(database.to_string()),
649
                        },
650
42
                        pool_size: mongodb.pool_size,
651
                    }),
652
                },
653
50
                sqlite: match db.sqlite.as_ref() {
654
8
                    None => Some(Sqlite {
655
8
                        path: Some(DEF_SQLITE_PATH.to_string()),
656
8
                    }),
657
42
                    Some(sqlite) => Some(Sqlite {
658
42
                        path: match sqlite.path.as_ref() {
659
6
                            None => Some(DEF_SQLITE_PATH.to_string()),
660
36
                            Some(path) => Some(path.to_string()),
661
                        },
662
                    }),
663
                },
664
            }),
665
        },
666
54
        cache: match config.cache.as_ref() {
667
14
            None => Some(Cache {
668
14
                engine: Some(DEF_CACHE_ENGINE.to_string()),
669
14
                memory: Some(MemoryCache {
670
14
                    device: Some(DEF_MEMORY_DEVICE),
671
14
                    device_route: Some(DEF_MEMORY_DEVICE_ROUTE),
672
14
                    network_route: Some(DEF_MEMORY_NETWORK_ROUTE),
673
14
                }),
674
14
            }),
675
40
            Some(cache) => Some(Cache {
676
40
                engine: match cache.engine.as_ref() {
677
6
                    None => Some(DEF_CACHE_ENGINE.to_string()),
678
34
                    Some(engine) => match engine.as_str() {
679
34
                        CacheEngine::MEMORY => Some(CacheEngine::MEMORY.to_string()),
680
20
                        _ => Some(DEF_CACHE_ENGINE.to_string()),
681
                    },
682
                },
683
40
                memory: match cache.memory.as_ref() {
684
22
                    None => Some(MemoryCache {
685
22
                        device: Some(DEF_MEMORY_DEVICE),
686
22
                        device_route: Some(DEF_MEMORY_DEVICE_ROUTE),
687
22
                        network_route: Some(DEF_MEMORY_NETWORK_ROUTE),
688
22
                    }),
689
18
                    Some(memory) => Some(MemoryCache {
690
18
                        device: match memory.device {
691
8
                            None | Some(0) => Some(DEF_MEMORY_DEVICE),
692
10
                            Some(v) => Some(v),
693
                        },
694
18
                        device_route: match memory.device_route {
695
8
                            None | Some(0) => Some(DEF_MEMORY_DEVICE_ROUTE),
696
10
                            Some(v) => Some(v),
697
                        },
698
18
                        network_route: match memory.network_route {
699
8
                            None | Some(0) => Some(DEF_MEMORY_NETWORK_ROUTE),
700
10
                            Some(v) => Some(v),
701
                        },
702
                    }),
703
                },
704
            }),
705
        },
706
54
        mq: match config.mq.as_ref() {
707
32
            None => Some(Mq {
708
32
                prefetch: Some(DEF_MQ_PREFETCH),
709
32
                persistent: Some(DEF_MQ_PERSISTENT),
710
32
                shared_prefix: Some(DEF_MQ_SHAREDPREFIX.to_string()),
711
32
            }),
712
22
            Some(mq) => Some(Mq {
713
22
                prefetch: match mq.prefetch {
714
12
                    None | Some(0) => Some(DEF_MQ_PREFETCH),
715
10
                    Some(prefetch) => Some(prefetch),
716
                },
717
22
                persistent: match mq.persistent {
718
12
                    None => Some(DEF_MQ_PERSISTENT),
719
10
                    Some(persistent) => Some(persistent),
720
                },
721
22
                shared_prefix: match mq.shared_prefix.as_ref() {
722
8
                    None => Some(DEF_MQ_SHAREDPREFIX.to_string()),
723
14
                    Some(shared_prefix) => Some(shared_prefix.to_string()),
724
                },
725
            }),
726
        },
727
54
        mq_channels: match config.mq_channels.as_ref() {
728
16
            None => Some(MqChannels {
729
16
                unit: Some(BrokerCtrl {
730
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
731
16
                    prefetch: Some(DEF_MQ_PREFETCH),
732
16
                }),
733
16
                application: Some(BrokerCtrl {
734
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
735
16
                    prefetch: Some(DEF_MQ_PREFETCH),
736
16
                }),
737
16
                network: Some(BrokerCtrl {
738
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
739
16
                    prefetch: Some(DEF_MQ_PREFETCH),
740
16
                }),
741
16
                device: Some(BrokerCtrl {
742
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
743
16
                    prefetch: Some(DEF_MQ_PREFETCH),
744
16
                }),
745
16
                device_route: Some(BrokerCtrl {
746
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
747
16
                    prefetch: Some(DEF_MQ_PREFETCH),
748
16
                }),
749
16
                network_route: Some(BrokerCtrl {
750
16
                    url: Some(DEF_MQ_CHANNEL_URL.to_string()),
751
16
                    prefetch: Some(DEF_MQ_PREFETCH),
752
16
                }),
753
16
                data: None,
754
16
            }),
755
38
            Some(mq_channels) => Some(MqChannels {
756
38
                unit: match mq_channels.unit.as_ref() {
757
18
                    None => Some(BrokerCtrl {
758
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
759
18
                        prefetch: Some(DEF_MQ_PREFETCH),
760
18
                    }),
761
20
                    Some(channel) => Some(BrokerCtrl {
762
20
                        url: match channel.url.as_ref() {
763
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
764
12
                            Some(url) => Some(url.to_string()),
765
                        },
766
20
                        prefetch: match channel.prefetch {
767
10
                            None => Some(DEF_MQ_PREFETCH),
768
10
                            Some(prefetch) => Some(prefetch),
769
                        },
770
                    }),
771
                },
772
38
                application: match mq_channels.application.as_ref() {
773
18
                    None => Some(BrokerCtrl {
774
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
775
18
                        prefetch: Some(DEF_MQ_PREFETCH),
776
18
                    }),
777
20
                    Some(channel) => Some(BrokerCtrl {
778
20
                        url: match channel.url.as_ref() {
779
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
780
12
                            Some(url) => Some(url.to_string()),
781
                        },
782
20
                        prefetch: match channel.prefetch {
783
10
                            None => Some(DEF_MQ_PREFETCH),
784
10
                            Some(prefetch) => Some(prefetch),
785
                        },
786
                    }),
787
                },
788
38
                network: match mq_channels.network.as_ref() {
789
18
                    None => Some(BrokerCtrl {
790
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
791
18
                        prefetch: Some(DEF_MQ_PREFETCH),
792
18
                    }),
793
20
                    Some(channel) => Some(BrokerCtrl {
794
20
                        url: match channel.url.as_ref() {
795
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
796
12
                            Some(url) => Some(url.to_string()),
797
                        },
798
20
                        prefetch: match channel.prefetch {
799
10
                            None => Some(DEF_MQ_PREFETCH),
800
10
                            Some(prefetch) => Some(prefetch),
801
                        },
802
                    }),
803
                },
804
38
                device: match mq_channels.device.as_ref() {
805
18
                    None => Some(BrokerCtrl {
806
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
807
18
                        prefetch: Some(DEF_MQ_PREFETCH),
808
18
                    }),
809
20
                    Some(channel) => Some(BrokerCtrl {
810
20
                        url: match channel.url.as_ref() {
811
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
812
12
                            Some(url) => Some(url.to_string()),
813
                        },
814
20
                        prefetch: match channel.prefetch {
815
10
                            None => Some(DEF_MQ_PREFETCH),
816
10
                            Some(prefetch) => Some(prefetch),
817
                        },
818
                    }),
819
                },
820
38
                device_route: match mq_channels.device_route.as_ref() {
821
18
                    None => Some(BrokerCtrl {
822
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
823
18
                        prefetch: Some(DEF_MQ_PREFETCH),
824
18
                    }),
825
20
                    Some(channel) => Some(BrokerCtrl {
826
20
                        url: match channel.url.as_ref() {
827
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
828
12
                            Some(url) => Some(url.to_string()),
829
                        },
830
20
                        prefetch: match channel.prefetch {
831
10
                            None => Some(DEF_MQ_PREFETCH),
832
10
                            Some(prefetch) => Some(prefetch),
833
                        },
834
                    }),
835
                },
836
38
                network_route: match mq_channels.network_route.as_ref() {
837
18
                    None => Some(BrokerCtrl {
838
18
                        url: Some(DEF_MQ_CHANNEL_URL.to_string()),
839
18
                        prefetch: Some(DEF_MQ_PREFETCH),
840
18
                    }),
841
20
                    Some(channel) => Some(BrokerCtrl {
842
20
                        url: match channel.url.as_ref() {
843
8
                            None => Some(DEF_MQ_CHANNEL_URL.to_string()),
844
12
                            Some(url) => Some(url.to_string()),
845
                        },
846
20
                        prefetch: match channel.prefetch {
847
10
                            None => Some(DEF_MQ_PREFETCH),
848
10
                            Some(prefetch) => Some(prefetch),
849
                        },
850
                    }),
851
                },
852
38
                data: match mq_channels.data.as_ref() {
853
2
                    None => None,
854
36
                    Some(channel) => Some(BrokerData {
855
36
                        url: match channel.url.as_ref() {
856
8
                            None => None,
857
28
                            Some(url) => Some(url.to_string()),
858
                        },
859
36
                        persistent: match channel.persistent {
860
24
                            None => Some(DEF_MQ_PERSISTENT),
861
12
                            Some(persistent) => Some(persistent),
862
                        },
863
                    }),
864
                },
865
            }),
866
        },
867
54
        api_scopes: match config.api_scopes.as_ref() {
868
46
            None => Some(HashMap::new()),
869
8
            Some(scopes) => Some(scopes.clone()),
870
        },
871
    }
872
54
}