un-cli 0.0.53 → 0.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/adminlog.mjs +33 -0
- package/cmd.txt +1 -1
- package/index.mjs +155 -55
- package/makerequest.mjs +1 -6
- package/package.json +2 -2
- package/portal.mjs +5 -5
- package/utilitynetwork.node.mjs +37 -42
- package/test.txt +0 -6
package/README.md
CHANGED
|
@@ -51,5 +51,5 @@ export subnetworks -new
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
> uncli --portal https://utilitynetwork.esri.com/portal --service NapervilleElectric_SQLServer --user tester --password tester.108 --file commands.txt
|
|
54
|
+
> uncli --portal https://utilitynetwork.esri.com/portal --service NapervilleElectric_SQLServer --user tester --password tester.108 --file commands.txt --verify true
|
|
55
55
|
|
package/adminlog.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
//Author : Hussein Nasser
|
|
3
|
+
//Date : Oct-13-2021
|
|
4
|
+
//Twitter: @hnasr
|
|
5
|
+
import fetch from "node-fetch";
|
|
6
|
+
import { logger } from "./logger.mjs"
|
|
7
|
+
|
|
8
|
+
export class AdminLog {
|
|
9
|
+
|
|
10
|
+
constructor(token, serverUrl)
|
|
11
|
+
{
|
|
12
|
+
this.adminServerUrl = serverUrl + "/admin";
|
|
13
|
+
this.token = token;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
query (codes, serviceName ="*", pageSize = 10000)
|
|
17
|
+
{
|
|
18
|
+
const url = this.adminServerUrl + "/logs/query?f=pjson"
|
|
19
|
+
const level = "DEBUG"
|
|
20
|
+
const filterType="json"
|
|
21
|
+
const token = this.token
|
|
22
|
+
const filter = {
|
|
23
|
+
"codes": codes,
|
|
24
|
+
"services": serviceName
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const queryLogUrl = url + `&token=${token}&level=${level}&filterType=${filterType}&filter=${encodeURIComponent(JSON.stringify(filter))}&pageSize=${pageSize}`
|
|
28
|
+
logger.info(queryLogUrl);
|
|
29
|
+
return fetch(queryLogUrl);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
}
|
package/cmd.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
arlogs --byrule
|
package/index.mjs
CHANGED
|
@@ -2,11 +2,13 @@ import readline from "readline"
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { Portal } from "./portal.mjs"
|
|
4
4
|
import { UtilityNetwork } from "./utilitynetwork.node.mjs"
|
|
5
|
+
import { AdminLog } from "./adminlog.mjs"
|
|
6
|
+
|
|
5
7
|
import { logger } from "./logger.mjs"
|
|
6
8
|
import fetch from "node-fetch"
|
|
7
9
|
//update version
|
|
8
|
-
let version = "0.0.
|
|
9
|
-
const GENERATE_TOKEN_TIME_MIN =
|
|
10
|
+
let version = "0.0.57";
|
|
11
|
+
const GENERATE_TOKEN_TIME_MIN = 30;
|
|
10
12
|
|
|
11
13
|
let rl = null;
|
|
12
14
|
|
|
@@ -14,7 +16,7 @@ let rl = null;
|
|
|
14
16
|
//uncli --portal https://utilitynetwork.esri.com/portal --service AllStar_oracle --user unadmin --password unadmin.108
|
|
15
17
|
let portal = null;
|
|
16
18
|
let un = null;
|
|
17
|
-
|
|
19
|
+
let adminLog = null;
|
|
18
20
|
|
|
19
21
|
//parse input for parameters
|
|
20
22
|
function parseInput(){
|
|
@@ -25,8 +27,9 @@ function parseInput(){
|
|
|
25
27
|
"--user" ,
|
|
26
28
|
"--password",
|
|
27
29
|
"--command",
|
|
28
|
-
"--
|
|
29
|
-
"--file"
|
|
30
|
+
"--gdbversion",
|
|
31
|
+
"--file",
|
|
32
|
+
"--verify"
|
|
30
33
|
]
|
|
31
34
|
|
|
32
35
|
const params = {
|
|
@@ -35,8 +38,9 @@ function parseInput(){
|
|
|
35
38
|
"user": null,
|
|
36
39
|
"password": null,
|
|
37
40
|
"command": "",
|
|
38
|
-
"
|
|
39
|
-
"file": ""
|
|
41
|
+
"gdbversion": "SDE.DEFAULT",
|
|
42
|
+
"file": "",
|
|
43
|
+
"verify": "true"
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
for (let i = 0; i < process.argv.length ; i++){
|
|
@@ -49,8 +53,9 @@ function parseInput(){
|
|
|
49
53
|
|
|
50
54
|
if (Object.values(params).includes(null))
|
|
51
55
|
{
|
|
52
|
-
console.log ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password --file commandfile*")
|
|
56
|
+
console.log ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password [--gdbversion* user.version --file commandfile* --verify true|false]")
|
|
53
57
|
console.log("--file commandfile is optional and you can pass a path to a file with a list of command to execute. ")
|
|
58
|
+
console.log("--gdbversion is optional and allows the UN to be opened in that version. When not specified sde.DEFAULT is used.")
|
|
54
59
|
process.exit();
|
|
55
60
|
}
|
|
56
61
|
|
|
@@ -62,7 +67,7 @@ async function getToken(parameters) {
|
|
|
62
67
|
portal = new Portal(parameters.portal, parameters.user, parameters.password)
|
|
63
68
|
logger.info("About to connect..")
|
|
64
69
|
const token = await portal.connect()
|
|
65
|
-
logger.info(`Token
|
|
70
|
+
logger.info(`Token generanted successfully.`)
|
|
66
71
|
return token;
|
|
67
72
|
}
|
|
68
73
|
|
|
@@ -94,7 +99,9 @@ async function connect(parameters) {
|
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
const serviceUrl = portal.serverUrl + `/rest/services/${parameters.service}/FeatureServer`
|
|
97
|
-
un = new UtilityNetwork(token, serviceUrl)
|
|
102
|
+
un = new UtilityNetwork(token, serviceUrl, parameters.gdbversion)
|
|
103
|
+
//create a new admin object (user might not be admin we won't use it until the user call log )
|
|
104
|
+
adminLog = new AdminLog(token, portal.serverUrl)
|
|
98
105
|
console.log("Loading utility network...")
|
|
99
106
|
await un.load();
|
|
100
107
|
console.log("Connected.")
|
|
@@ -118,15 +125,15 @@ async function connect(parameters) {
|
|
|
118
125
|
console.error(`Cannot open specified file ${file}.`)
|
|
119
126
|
|
|
120
127
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
//execute one off command
|
|
129
|
+
if ( command != "")
|
|
130
|
+
executeInput(command);
|
|
124
131
|
|
|
125
132
|
|
|
126
133
|
|
|
127
|
-
|
|
134
|
+
askInput();
|
|
128
135
|
|
|
129
|
-
|
|
136
|
+
setTimeout( async ()=> await regenerateToken(parameters) , 1000*60*GENERATE_TOKEN_TIME_MIN)
|
|
130
137
|
}
|
|
131
138
|
catch(ex){
|
|
132
139
|
console.error(ex)
|
|
@@ -151,24 +158,27 @@ const inputs = {
|
|
|
151
158
|
"version": "Displays the version of uncli",
|
|
152
159
|
"ls": "List all services",
|
|
153
160
|
"def": "Show the feature service definition",
|
|
154
|
-
"def
|
|
161
|
+
"def --layers" : "List all layers in this service",
|
|
155
162
|
"subnetworks" : "Lists all subnetworks",
|
|
156
|
-
"subnetworks
|
|
157
|
-
"subnetworks
|
|
163
|
+
"subnetworks --dirty" : "Lists only dirty subnetworks",
|
|
164
|
+
"subnetworks --deleted" : "Lists dirty and deleted subnetworks",
|
|
158
165
|
"evaluate" : "Evaluate in parallel",
|
|
159
|
-
"trace
|
|
166
|
+
"trace --subnetwork <subnetwork>": "Traces input subnetwork and returns the time and number of elements returned .",
|
|
160
167
|
"topology" : "Displays the topology status",
|
|
161
|
-
"topology
|
|
162
|
-
"topology
|
|
163
|
-
"topology
|
|
164
|
-
"update subnetworks
|
|
165
|
-
"update subnetworks
|
|
166
|
-
"update subnetworks
|
|
167
|
-
"export subnetworks
|
|
168
|
-
"export subnetworks
|
|
169
|
-
"export subnetworks
|
|
168
|
+
"topology --disable" : "Disable topology",
|
|
169
|
+
"topology --enable" : "Enable topology",
|
|
170
|
+
"topology --validate" : "Validate topology (full extent)",
|
|
171
|
+
"update subnetworks --all": "Update all dirty subnetworks synchronously",
|
|
172
|
+
"update subnetworks --deleted": "Update all deleted dirty subnetworks synchronously",
|
|
173
|
+
"update subnetworks --all --async": "Update all dirty subnetworks asynchronously",
|
|
174
|
+
"export subnetworks --all": "Export all subnetworks with ACK ",
|
|
175
|
+
"export subnetworks --new": "Export all subnetworks with ACK that haven't been exported ",
|
|
176
|
+
"export subnetworks --deleted": "Export all subnetworks with ACK that are deleted ",
|
|
170
177
|
"count": "Lists the number of rows in all feature layers.",
|
|
171
|
-
"count
|
|
178
|
+
"count --system": "Lists the number of rows in system layers.",
|
|
179
|
+
"connect --service": "Connects to the another service",
|
|
180
|
+
"arlogs": "Lists attribute rules execution logs (requires admin)",
|
|
181
|
+
"arlogs --byrule": "Lists attribute rules execution summary by rule (requires admin)",
|
|
172
182
|
"whoami": "Lists the current login info",
|
|
173
183
|
"clear": "Clears this screen",
|
|
174
184
|
"quit": "Exit this program"
|
|
@@ -177,10 +187,10 @@ const inputs = {
|
|
|
177
187
|
},
|
|
178
188
|
"^whoami$": async () => {
|
|
179
189
|
|
|
180
|
-
console.log(`${parameters.user}@${parameters.service}@${parameters.
|
|
190
|
+
console.log(`${parameters.user}@${parameters.service}@${parameters.gdbversion}`)
|
|
181
191
|
|
|
182
192
|
},
|
|
183
|
-
"^def
|
|
193
|
+
"^def --layers$|^layers$": async () => {
|
|
184
194
|
const layerProperties = [
|
|
185
195
|
"id",
|
|
186
196
|
"name",
|
|
@@ -243,7 +253,7 @@ const inputs = {
|
|
|
243
253
|
})
|
|
244
254
|
console.table(topoMoments)
|
|
245
255
|
},
|
|
246
|
-
"^topology
|
|
256
|
+
"^topology --enable$": async () => {
|
|
247
257
|
console.log("Enabling topology ...");
|
|
248
258
|
const fromDate = new Date();
|
|
249
259
|
const result = await un.enableTopology()
|
|
@@ -252,7 +262,7 @@ const inputs = {
|
|
|
252
262
|
result.duration = numberWithCommas(Math.round(timeEnable/1000)) + " s"
|
|
253
263
|
console.table(result)
|
|
254
264
|
},
|
|
255
|
-
"^topology
|
|
265
|
+
"^topology --disable$": async () => {
|
|
256
266
|
const fromDate = new Date();
|
|
257
267
|
console.log("Disabling topology ...");
|
|
258
268
|
const result = await un.disableTopology()
|
|
@@ -288,7 +298,7 @@ const inputs = {
|
|
|
288
298
|
//progress
|
|
289
299
|
//timeouts
|
|
290
300
|
//in case failure you don't lose everything
|
|
291
|
-
"^topology
|
|
301
|
+
"^topology --validate -fn$": async () => {
|
|
292
302
|
console.log("Validating Network topology ...");
|
|
293
303
|
|
|
294
304
|
const fullExtent = un.featureServiceJson.fullExtent;
|
|
@@ -335,7 +345,7 @@ const inputs = {
|
|
|
335
345
|
|
|
336
346
|
},
|
|
337
347
|
|
|
338
|
-
"^topology
|
|
348
|
+
"^topology --validate$": async () => {
|
|
339
349
|
console.log("Validating Network topology ...");
|
|
340
350
|
const fromDate = new Date();
|
|
341
351
|
const result = await un.validateNetworkTopology()
|
|
@@ -344,7 +354,7 @@ const inputs = {
|
|
|
344
354
|
result.duration = numberWithCommas(Math.round(timeEnable/1000)) + " s"
|
|
345
355
|
console.table(result)
|
|
346
356
|
},
|
|
347
|
-
"^subnetworks
|
|
357
|
+
"^subnetworks --dirty$": async () => {
|
|
348
358
|
const subnetworks = await un.getSubnetworks("isdirty=1");
|
|
349
359
|
if (subnetworks.features.length === 0) {
|
|
350
360
|
console.log("No dirty subnetworks found.")
|
|
@@ -356,7 +366,7 @@ const inputs = {
|
|
|
356
366
|
const rowCount = subs.length;
|
|
357
367
|
console.log (`${numberWithCommas(rowCount)} rows returned.`)
|
|
358
368
|
},
|
|
359
|
-
"^subnetworks
|
|
369
|
+
"^subnetworks --deleted$": async () => {
|
|
360
370
|
const subnetworks = await un.getSubnetworks("isdirty=1 and isdeleted=1");
|
|
361
371
|
if (subnetworks.features.length === 0) {
|
|
362
372
|
console.log("No dirty and deleted subnetworks found.")
|
|
@@ -369,7 +379,7 @@ const inputs = {
|
|
|
369
379
|
console.log (`${numberWithCommas(rowCount)} rows returned.`)
|
|
370
380
|
},
|
|
371
381
|
|
|
372
|
-
"^update subnetworks
|
|
382
|
+
"^update subnetworks --deleted$" : async () => {
|
|
373
383
|
console.log("Querying all subnetworks that are dirty and deleted.");
|
|
374
384
|
let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1 and isdeleted=1");
|
|
375
385
|
console.log(`Discovered ${subnetworks.features.length} dirty deleted subnetworks.`);
|
|
@@ -393,7 +403,7 @@ const inputs = {
|
|
|
393
403
|
}
|
|
394
404
|
},
|
|
395
405
|
|
|
396
|
-
"^update subnetworks
|
|
406
|
+
"^update subnetworks --all$" : async () => {
|
|
397
407
|
console.log("Querying all subnetworks that are dirty.");
|
|
398
408
|
let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1");
|
|
399
409
|
console.log(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
|
|
@@ -415,7 +425,7 @@ const inputs = {
|
|
|
415
425
|
console.log(`Result ${JSON.stringify(subnetworkResult)}`)
|
|
416
426
|
}
|
|
417
427
|
},
|
|
418
|
-
"^update subnetworks
|
|
428
|
+
"^update subnetworks --all --async$" : async () => {
|
|
419
429
|
console.log("Querying all subnetworks that are dirty.");
|
|
420
430
|
let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1");
|
|
421
431
|
console.log(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
|
|
@@ -426,7 +436,7 @@ const inputs = {
|
|
|
426
436
|
console.log(`Result from submitting job ${JSON.stringify(subnetworkResult)}`)
|
|
427
437
|
}
|
|
428
438
|
},
|
|
429
|
-
"^export subnetworks
|
|
439
|
+
"^export subnetworks --all$" : async input => {
|
|
430
440
|
|
|
431
441
|
|
|
432
442
|
//create folder
|
|
@@ -473,13 +483,13 @@ const inputs = {
|
|
|
473
483
|
},
|
|
474
484
|
|
|
475
485
|
|
|
476
|
-
"^export subnetworks
|
|
486
|
+
"^export subnetworks --new --folder .*$|^export subnetworks --new$" : async input => {
|
|
477
487
|
|
|
478
488
|
//create folder
|
|
479
|
-
const file = input.match(
|
|
489
|
+
const file = input.match(/--folder .*/gm)
|
|
480
490
|
let inputDir = "Exported"
|
|
481
491
|
if (file != null && file.length > 0)
|
|
482
|
-
inputDir = file[0].replace("
|
|
492
|
+
inputDir = file[0].replace("--folder ", "")
|
|
483
493
|
//create directory if doesn't exists
|
|
484
494
|
if (!fs.existsSync(inputDir)) fs.mkdirSync(inputDir)
|
|
485
495
|
|
|
@@ -509,17 +519,26 @@ const inputs = {
|
|
|
509
519
|
const result = await un.returnInvalidAssociations();
|
|
510
520
|
console.log("Invalid Associations " + JSON.stringify(result))
|
|
511
521
|
},
|
|
522
|
+
"^connect --service": async input =>{
|
|
512
523
|
|
|
513
|
-
|
|
524
|
+
const inputParam = input.match(/--service .*/gm)
|
|
525
|
+
let serviceName = null;
|
|
526
|
+
if (inputParam != null && inputParam.length > 0)
|
|
527
|
+
serviceName = inputParam[0].replace("--service ", "")
|
|
528
|
+
|
|
529
|
+
parameters.service = serviceName
|
|
530
|
+
connect(parameters)
|
|
531
|
+
},
|
|
532
|
+
"^trace --subnetwork": async input => {
|
|
514
533
|
//get subnetwork name
|
|
515
534
|
|
|
516
535
|
const fromDate = new Date();
|
|
517
536
|
|
|
518
537
|
|
|
519
|
-
const inputParam = input.match(
|
|
538
|
+
const inputParam = input.match(/--subnetwork .*/gm)
|
|
520
539
|
let subnetworkName = null;
|
|
521
540
|
if (inputParam != null && inputParam.length > 0)
|
|
522
|
-
subnetworkName = inputParam[0].replace("
|
|
541
|
+
subnetworkName = inputParam[0].replace("--subnetwork ", "")
|
|
523
542
|
|
|
524
543
|
console.log(`Tracing subnetwork ${subnetworkName}`);
|
|
525
544
|
const result = await un.subnetworkTraceSimple(subnetworkName)
|
|
@@ -535,7 +554,7 @@ const inputs = {
|
|
|
535
554
|
console.table(newResult)
|
|
536
555
|
|
|
537
556
|
},
|
|
538
|
-
"^export subnetworks
|
|
557
|
+
"^export subnetworks --deleted$" : async input => {
|
|
539
558
|
|
|
540
559
|
//create folder
|
|
541
560
|
const file = input.match(/-f .*/gm)
|
|
@@ -572,11 +591,11 @@ const inputs = {
|
|
|
572
591
|
|
|
573
592
|
},
|
|
574
593
|
|
|
575
|
-
"^write
|
|
594
|
+
"^write --folder.*$": async input => {
|
|
576
595
|
|
|
577
596
|
|
|
578
|
-
const file = input.match(
|
|
579
|
-
const inputDir = file[0].replace("
|
|
597
|
+
const file = input.match(/--folder .*/gm)
|
|
598
|
+
const inputDir = file[0].replace("--folder ", "")
|
|
580
599
|
//create directory if doesn't exists
|
|
581
600
|
if (!fs.existsSync(inputDir)) fs.mkdirSync(inputDir)
|
|
582
601
|
fs.writeFileSync(`${inputDir}/${Math.random()}`, Math.random())
|
|
@@ -625,12 +644,11 @@ const inputs = {
|
|
|
625
644
|
},
|
|
626
645
|
|
|
627
646
|
|
|
628
|
-
"^count
|
|
647
|
+
"^count --system$": async () => {
|
|
629
648
|
console.log("Querying all system layers....")
|
|
630
649
|
|
|
631
650
|
const systemLayers = un.getSystemLayers();
|
|
632
|
-
|
|
633
|
-
|
|
651
|
+
let totalRows = 0;
|
|
634
652
|
|
|
635
653
|
const layerCount = []
|
|
636
654
|
for (let i = 0; i < systemLayers.length; i++ )
|
|
@@ -640,6 +658,7 @@ const inputs = {
|
|
|
640
658
|
|
|
641
659
|
const result = await un.queryCount(l.id);
|
|
642
660
|
|
|
661
|
+
totalRows+=result.count;
|
|
643
662
|
layerCount.push( {
|
|
644
663
|
"layerId": l.id,
|
|
645
664
|
"name": l.name ,
|
|
@@ -648,9 +667,87 @@ const inputs = {
|
|
|
648
667
|
|
|
649
668
|
}
|
|
650
669
|
|
|
651
|
-
console.table(layerCount)
|
|
670
|
+
console.table(layerCount)
|
|
671
|
+
console.log(`Total number of rows in all system layers : ${numberWithCommas(totalRows)} .`)
|
|
672
|
+
|
|
652
673
|
},
|
|
653
674
|
|
|
675
|
+
"^arlogs$": async () => {
|
|
676
|
+
console.log(`Querying attribute rules logs for ${parameters.service} ...`)
|
|
677
|
+
const result= await adminLog.query([102003], parameters.service)
|
|
678
|
+
const jsonRes = await result.json()
|
|
679
|
+
const arMessages = jsonRes.logMessages
|
|
680
|
+
.filter(m => m.message.indexOf("Attribute rule execution complete:") > -1)
|
|
681
|
+
.map (m => JSON.parse(m.message.replace("Attribute rule execution complete:", "")))
|
|
682
|
+
.map( m => {
|
|
683
|
+
m["Elapsed Time (ms)"] = Math.round(m["Elapsed Time"]*1000000)/1000
|
|
684
|
+
// m["Arcade Evaluation Time:"] = Math.round(m["Arcade Evaluation Time:"]*1000,6)
|
|
685
|
+
//m.ArcadeTime = m["Arcade Evaluation Time:"]
|
|
686
|
+
|
|
687
|
+
delete m["Arcade Evaluation Time:"];
|
|
688
|
+
delete m["Elapsed Time"];
|
|
689
|
+
//delete m ['GlobalID'];
|
|
690
|
+
return m
|
|
691
|
+
})
|
|
692
|
+
.sort( (m1, m2) => m2["Elapsed Time (ms)"]- m1["Elapsed Time (ms)"])
|
|
693
|
+
console.table(arMessages)
|
|
694
|
+
/*
|
|
695
|
+
code:102003
|
|
696
|
+
elapsed:''
|
|
697
|
+
machine:'DEV0015932.ESRI.COM'
|
|
698
|
+
message:'requestProperties = {"token":"HfauSFGoSwTMA5KLvsL-I8EORea_KEvz1GcAMNCsvTuzeJ1QuYbQm0EGI7eC2zr1lOm8857U18oZOjG0BeuEwKj7fvCk-_DuWKFvClU5p06SRLE8RjEzPB0gjMTFQnjVnTRmQzZFWXCj1VRssMECQg..","referer":null,"privilege":"ADMINISTER","privileges":["features:user:edit","features:user:fullEdit","features:user:manageVersions","portal:user:viewTracks","premium:user:geocode:stored","premium:user:geocode:temporary","premium:user:networkanalysis:closestfacility","premium:user:networkanalysis:locationallocation","premium:user:networkanalysis:optimizedrouting","premium:user:networkanalysis:origindestinationcostmatrix","premium:user:networkanalysis:routing","premium:user:networkanalysis:servicearea","premium:user:networkanalysis:vehiclerouting","traceNetwork","utilityNetwork","parcelFabric"],"securityProvider":"portal"}'
|
|
699
|
+
methodName:'GetServerEnvironmentRequestProperties'
|
|
700
|
+
process:'30940'
|
|
701
|
+
requestID:'fccb7fba-cba9-4ebb-84b2-cb3645979d8e'
|
|
702
|
+
source:'RedTrolley_Postgres.MapServer'
|
|
703
|
+
thread:'29408'
|
|
704
|
+
time:1634165691074
|
|
705
|
+
type:'DEBUG'
|
|
706
|
+
user:'unadmin'
|
|
707
|
+
*/
|
|
708
|
+
|
|
709
|
+
},
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
"^arlogs --byrule$": async () => {
|
|
713
|
+
console.log(`Querying attribute rules logs for ${parameters.service} ...`)
|
|
714
|
+
const result= await adminLog.query([102003], parameters.service)
|
|
715
|
+
const jsonRes = await result.json()
|
|
716
|
+
const arMessages = jsonRes.logMessages
|
|
717
|
+
.filter(m => m.message.indexOf("Attribute rule execution complete:") > -1)
|
|
718
|
+
.map (m => JSON.parse(m.message.replace("Attribute rule execution complete:", "")))
|
|
719
|
+
.map( m => {
|
|
720
|
+
m["Elapsed Time (ms)"] = Math.round(m["Elapsed Time"]*1000000)/1000
|
|
721
|
+
// m["Arcade Evaluation Time:"] = Math.round(m["Arcade Evaluation Time:"]*1000,6)
|
|
722
|
+
//m.ArcadeTime = m["Arcade Evaluation Time:"]
|
|
723
|
+
|
|
724
|
+
delete m["Arcade Evaluation Time:"];
|
|
725
|
+
delete m["Elapsed Time"];
|
|
726
|
+
//delete m ['GlobalID'];
|
|
727
|
+
return m
|
|
728
|
+
})
|
|
729
|
+
.sort( (m1, m2) => m2["Elapsed Time (ms)"]- m1["Elapsed Time (ms)"])
|
|
730
|
+
.reduce( ( prev, cur ) => {
|
|
731
|
+
if (prev [cur["Rule name"]] === undefined)
|
|
732
|
+
prev [cur["Rule name"]] = 0;
|
|
733
|
+
|
|
734
|
+
prev [cur["Rule name"]] = cur["Elapsed Time (ms)"]
|
|
735
|
+
return prev
|
|
736
|
+
}, {})
|
|
737
|
+
|
|
738
|
+
const rules = Object.keys(arMessages)
|
|
739
|
+
.map(a => {
|
|
740
|
+
|
|
741
|
+
const rule = {}
|
|
742
|
+
rule["Attribute Rule"] = a;
|
|
743
|
+
rule["Total Cost (ms)"] = arMessages[a];
|
|
744
|
+
return rule;
|
|
745
|
+
})
|
|
746
|
+
.sort( (m1, m2) => m2["Total Cost (ms)"] -m1["Total Cost (ms)"])
|
|
747
|
+
console.table(rules)
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
},
|
|
654
751
|
|
|
655
752
|
"^version$": () => console.log(version),
|
|
656
753
|
"^clear$|^cls$": () => console.clear(),
|
|
@@ -829,6 +926,9 @@ export async function run (){
|
|
|
829
926
|
}
|
|
830
927
|
console.log(`uncli ${version} is experimental command line utility for basic utility network services. Use as is.`)
|
|
831
928
|
parameters = await parseInput( )
|
|
929
|
+
//set certificate verification
|
|
930
|
+
const verifyCert = parameters["verify"] === 'true' ? 1 : 0;
|
|
931
|
+
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = verifyCert;
|
|
832
932
|
setTimeout( async ()=> await regenerateToken(parameters) , 1000*60*GENERATE_TOKEN_TIME_MIN)
|
|
833
933
|
await connect(parameters)
|
|
834
934
|
}
|
package/makerequest.mjs
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import fetch from "node-fetch";
|
|
2
|
-
import { logger } from "./logger.mjs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//UNCOMMENT THIS LINE IF YOU DON'T HAVE SECURE CERTIFICATE
|
|
6
|
-
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
|
|
7
2
|
|
|
8
3
|
export function makeRequest (opts) {
|
|
9
4
|
|
|
@@ -28,7 +23,7 @@ export function makeRequest (opts) {
|
|
|
28
23
|
if (opts.headers)
|
|
29
24
|
Object.keys(opts.headers).forEach( key => headers[key] = opts.headers[key] )
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
//console.log(opts)
|
|
32
27
|
const result = await fetch(opts.url, {
|
|
33
28
|
"method" : opts.method,
|
|
34
29
|
"headers": headers,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "un-cli",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Command line interface for working with ArcGIS Utility Network",
|
|
3
|
+
"version": "0.0.57",
|
|
4
|
+
"description": "Command line interface for working with ArcGIS Utility Network Extension",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"uncli": "un.mjs"
|
package/portal.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { makeRequest } from "./makerequest.mjs"
|
|
2
2
|
import { logger } from "./logger.mjs"
|
|
3
3
|
|
|
4
|
-
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
|
|
5
4
|
export class Portal{
|
|
6
5
|
|
|
7
6
|
constructor(url, username, password, expiration = 300)
|
|
@@ -33,9 +32,9 @@ export class Portal{
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
//query for token
|
|
36
|
-
logger.info("
|
|
35
|
+
logger.info("Generating Token Sending POST request..")
|
|
37
36
|
const result = await makeRequest({method: 'POST', url: tokenUrl, params: postJson });
|
|
38
|
-
logger.info("
|
|
37
|
+
logger.info("Got result.")
|
|
39
38
|
if (result.error) reject(JSON.stringify(result.error))
|
|
40
39
|
self.token = result.token;
|
|
41
40
|
|
|
@@ -45,8 +44,9 @@ export class Portal{
|
|
|
45
44
|
|
|
46
45
|
}
|
|
47
46
|
catch(ex){
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
logger.error(ex.status.message)
|
|
48
|
+
console.error(ex.status.errno)
|
|
49
|
+
reject(`Failed to connect to portal, check your username or password or add --verify false if you are using a self-signed certificate. Normally a production system should have a valid certificate signed by a CA and you should NOT disable verification in that case.)`)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
}
|
package/utilitynetwork.node.mjs
CHANGED
|
@@ -4,32 +4,23 @@
|
|
|
4
4
|
//Mod : May-18-2020
|
|
5
5
|
//Twitter: @hnasr
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
//import('node-fetch').then(f => fetch = f ).catch(e => console.error("can't load , not node"))
|
|
9
|
-
//import("./logger.mjs").then(l => logger = l ).catch(e => console.error("can't load , not node"))
|
|
10
7
|
|
|
11
8
|
/*
|
|
12
9
|
import fetch from "node-fetch"
|
|
13
10
|
*/
|
|
14
11
|
import { logger } from "./logger.mjs"
|
|
15
12
|
import ProgressBar from "progress"
|
|
16
|
-
|
|
17
|
-
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
//UNCOMMENT THIS LINE IF YOU DON'T HAVE SECURE CERTIFICATE
|
|
23
|
-
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
|
|
24
14
|
|
|
25
15
|
|
|
26
16
|
export class UtilityNetwork {
|
|
27
17
|
|
|
28
|
-
constructor(token, featureServiceUrl)
|
|
18
|
+
constructor(token, featureServiceUrl, gdbVersion="sde.DEFAULT")
|
|
29
19
|
{
|
|
30
20
|
|
|
31
21
|
this.featureServiceUrl = featureServiceUrl;
|
|
32
|
-
this.token = token;
|
|
22
|
+
this.token = token;
|
|
23
|
+
this.gdbVersion = gdbVersion;
|
|
33
24
|
}
|
|
34
25
|
|
|
35
26
|
///first function one should call after creating an instance of a utility network
|
|
@@ -197,6 +188,7 @@ export class UtilityNetwork {
|
|
|
197
188
|
const momentsToReturn = JSON.stringify(moment)
|
|
198
189
|
let postJson = {
|
|
199
190
|
token: this.token,
|
|
191
|
+
gdbVersion:this.gdbVersion,
|
|
200
192
|
momentsToReturn: momentsToReturn,
|
|
201
193
|
f: "json"
|
|
202
194
|
}
|
|
@@ -211,8 +203,7 @@ export class UtilityNetwork {
|
|
|
211
203
|
|
|
212
204
|
}
|
|
213
205
|
|
|
214
|
-
|
|
215
|
-
getAll
|
|
206
|
+
|
|
216
207
|
//return the domainNetwork object.
|
|
217
208
|
getDomainNetwork(domainNetworkName)
|
|
218
209
|
{
|
|
@@ -233,7 +224,7 @@ export class UtilityNetwork {
|
|
|
233
224
|
return tier;
|
|
234
225
|
}
|
|
235
226
|
//query the subnetwokrs table
|
|
236
|
-
getSubnetworks(domainNetworkName, tierName
|
|
227
|
+
getSubnetworks(domainNetworkName, tierName)
|
|
237
228
|
{
|
|
238
229
|
let subnetworkTableUrl = this.featureServiceUrl + "/" + this.layerDefinition.systemLayers.subnetworksTableId + "/query";
|
|
239
230
|
|
|
@@ -242,7 +233,8 @@ export class UtilityNetwork {
|
|
|
242
233
|
where: "DOMAINNETWORKNAME = '" + domainNetworkName + "' AND TIERNAME = '" + tierName + "'",
|
|
243
234
|
outFields: "SUBNETWORKNAME",
|
|
244
235
|
orderByFields: "SUBNETWORKNAME",
|
|
245
|
-
gdbVersion:
|
|
236
|
+
gdbVersion:this.gdbVersion,
|
|
237
|
+
|
|
246
238
|
returnDistinctValues: true,
|
|
247
239
|
f: "json"
|
|
248
240
|
}
|
|
@@ -251,7 +243,7 @@ export class UtilityNetwork {
|
|
|
251
243
|
|
|
252
244
|
}
|
|
253
245
|
|
|
254
|
-
getSubnetworks(whereclause = "1=1"
|
|
246
|
+
getSubnetworks(whereclause = "1=1") {
|
|
255
247
|
|
|
256
248
|
let subnetworkTableUrl = this.featureServiceUrl + "/" + this.layerDefinition.systemLayers.subnetworksTableId + "/query";
|
|
257
249
|
|
|
@@ -260,21 +252,21 @@ export class UtilityNetwork {
|
|
|
260
252
|
where: whereclause,
|
|
261
253
|
outFields: "DOMAINNETWORKNAME, TIERNAME, SUBNETWORKNAME",
|
|
262
254
|
orderByFields: "DOMAINNETWORKNAME, TIERNAME, SUBNETWORKNAME",
|
|
263
|
-
gdbVersion:
|
|
255
|
+
gdbVersion:this.gdbVersion,
|
|
264
256
|
returnDistinctValues: true,
|
|
265
257
|
f: "json"
|
|
266
258
|
}
|
|
267
259
|
|
|
268
260
|
return makeRequest({method: 'POST', url: subnetworkTableUrl, params: postJson});
|
|
269
261
|
}
|
|
270
|
-
queryCount(layerId, where ="1=1"
|
|
262
|
+
queryCount(layerId, where ="1=1") {
|
|
271
263
|
|
|
272
264
|
let queryJson = {
|
|
273
265
|
f: "json",
|
|
274
266
|
token: this.token,
|
|
275
267
|
returnCountOnly: true,
|
|
276
268
|
where: where,
|
|
277
|
-
gdbVersion:
|
|
269
|
+
gdbVersion:this.gdbVersion,
|
|
278
270
|
}
|
|
279
271
|
|
|
280
272
|
queryJson.layerId = layerId
|
|
@@ -283,14 +275,14 @@ export class UtilityNetwork {
|
|
|
283
275
|
|
|
284
276
|
}
|
|
285
277
|
|
|
286
|
-
queryDistinct(layerId, field, where
|
|
278
|
+
queryDistinct(layerId, field, where) {
|
|
287
279
|
|
|
288
280
|
let queryJson = {
|
|
289
281
|
f: "json",
|
|
290
282
|
token: this.token,
|
|
291
283
|
outFields: field,
|
|
292
284
|
where: where,
|
|
293
|
-
gdbVersion:
|
|
285
|
+
gdbVersion:this.gdbVersion,
|
|
294
286
|
returnDistinctValues: true
|
|
295
287
|
}
|
|
296
288
|
|
|
@@ -307,7 +299,7 @@ export class UtilityNetwork {
|
|
|
307
299
|
|
|
308
300
|
}
|
|
309
301
|
//query that projects to webmercator.
|
|
310
|
-
query(layerId, where, obj, objectids, outFields = "*",
|
|
302
|
+
query(layerId, where, obj, objectids, outFields = "*", resultOffset = 0, resultRecordCount=2000)
|
|
311
303
|
{
|
|
312
304
|
let webMercSpatialReference = {
|
|
313
305
|
"wkid": 102100,
|
|
@@ -329,7 +321,7 @@ export class UtilityNetwork {
|
|
|
329
321
|
token: this.token,
|
|
330
322
|
outFields: outFields,
|
|
331
323
|
where: where,
|
|
332
|
-
gdbVersion:
|
|
324
|
+
gdbVersion:this.gdbVersion,
|
|
333
325
|
outSR: JSON.stringify(webMercSpatialReference),
|
|
334
326
|
resultOffset: resultOffset,
|
|
335
327
|
resultRecordCount: resultRecordCount
|
|
@@ -391,7 +383,7 @@ export class UtilityNetwork {
|
|
|
391
383
|
|
|
392
384
|
|
|
393
385
|
|
|
394
|
-
|
|
386
|
+
if (this.layerDefinition.systemLayers.pointErrorsLayerId)
|
|
395
387
|
systemLayers.push({
|
|
396
388
|
"id": this.layerDefinition.systemLayers.pointErrorsLayerId,
|
|
397
389
|
"name": "Point Errors",
|
|
@@ -399,7 +391,7 @@ export class UtilityNetwork {
|
|
|
399
391
|
"geometryType": "Point"
|
|
400
392
|
})
|
|
401
393
|
|
|
402
|
-
|
|
394
|
+
if (this.layerDefinition.systemLayers.lineErrorsLayerId)
|
|
403
395
|
systemLayers.push({
|
|
404
396
|
"id": this.layerDefinition.systemLayers.lineErrorsLayerId,
|
|
405
397
|
"name": "Line Errors",
|
|
@@ -407,7 +399,7 @@ export class UtilityNetwork {
|
|
|
407
399
|
"geometryType": "Line"
|
|
408
400
|
})
|
|
409
401
|
|
|
410
|
-
|
|
402
|
+
if (this.layerDefinition.systemLayers.polygonErrorsLayerId)
|
|
411
403
|
systemLayers.push({
|
|
412
404
|
"id": this.layerDefinition.systemLayers.polygonErrorsLayerId,
|
|
413
405
|
"name": "Polygon Errors",
|
|
@@ -648,6 +640,7 @@ export class UtilityNetwork {
|
|
|
648
640
|
f: "json",
|
|
649
641
|
token: this.token,
|
|
650
642
|
traceType : traceType,
|
|
643
|
+
gdbVersion:this.gdbVersion,
|
|
651
644
|
traceLocations: JSON.stringify(traceLocations),
|
|
652
645
|
traceConfiguration: JSON.stringify(traceConfiguration)
|
|
653
646
|
}
|
|
@@ -812,7 +805,7 @@ export class UtilityNetwork {
|
|
|
812
805
|
|
|
813
806
|
}
|
|
814
807
|
|
|
815
|
-
applyEdits(layerId, adds, updates, deletes, returnServiceEdits=false
|
|
808
|
+
applyEdits(layerId, adds, updates, deletes, returnServiceEdits=false) {
|
|
816
809
|
|
|
817
810
|
// "updates": [{
|
|
818
811
|
// "attributes": {"GLOBALID": deviceGlobalId,"DEVICESTATUS":0},
|
|
@@ -846,7 +839,7 @@ export class UtilityNetwork {
|
|
|
846
839
|
token: this.token,
|
|
847
840
|
useGlobalIds: true,
|
|
848
841
|
returnEditMoment: false,
|
|
849
|
-
gdbVersion:
|
|
842
|
+
gdbVersion:this.gdbVersion,
|
|
850
843
|
edits: JSON.stringify(c)
|
|
851
844
|
}
|
|
852
845
|
|
|
@@ -871,7 +864,8 @@ export class UtilityNetwork {
|
|
|
871
864
|
token: this.token,
|
|
872
865
|
useGlobalIds: true,
|
|
873
866
|
returnEditMoment: false,
|
|
874
|
-
|
|
867
|
+
gdbVersion:this.gdbVersion,
|
|
868
|
+
|
|
875
869
|
edits: JSON.stringify(c)
|
|
876
870
|
}
|
|
877
871
|
|
|
@@ -881,7 +875,7 @@ export class UtilityNetwork {
|
|
|
881
875
|
|
|
882
876
|
}
|
|
883
877
|
|
|
884
|
-
evaluate (extent, selectionSet, evaluationTypes, async = false
|
|
878
|
+
evaluate (extent, selectionSet, evaluationTypes, async = false) {
|
|
885
879
|
|
|
886
880
|
console.log("Evaluating... ")
|
|
887
881
|
/*
|
|
@@ -912,7 +906,7 @@ export class UtilityNetwork {
|
|
|
912
906
|
evaluationType: JSON.stringify(evaluationTypes),
|
|
913
907
|
selection: selectionJson,
|
|
914
908
|
evaluationArea: extentJson,
|
|
915
|
-
gdbVersion:
|
|
909
|
+
gdbVersion:this.gdbVersion,
|
|
916
910
|
async: async
|
|
917
911
|
}
|
|
918
912
|
|
|
@@ -940,7 +934,7 @@ export class UtilityNetwork {
|
|
|
940
934
|
|
|
941
935
|
}
|
|
942
936
|
|
|
943
|
-
disableTopology(
|
|
937
|
+
disableTopology() {
|
|
944
938
|
|
|
945
939
|
let thisObj = this;
|
|
946
940
|
|
|
@@ -950,8 +944,8 @@ export class UtilityNetwork {
|
|
|
950
944
|
let jsonPayload = {
|
|
951
945
|
f: "json",
|
|
952
946
|
token: this.token,
|
|
953
|
-
gdbVersion:
|
|
954
|
-
|
|
947
|
+
gdbVersion:this.gdbVersion,
|
|
948
|
+
}
|
|
955
949
|
|
|
956
950
|
return makeRequest({method:'POST', params: jsonPayload, url: url })
|
|
957
951
|
|
|
@@ -982,8 +976,8 @@ export class UtilityNetwork {
|
|
|
982
976
|
allSubnetworksInTier: false,
|
|
983
977
|
continueOnFailure: false,
|
|
984
978
|
async: async,
|
|
985
|
-
gdbVersion:
|
|
986
|
-
|
|
979
|
+
gdbVersion:this.gdbVersion,
|
|
980
|
+
}
|
|
987
981
|
let un = this;
|
|
988
982
|
|
|
989
983
|
return makeRequest({method:'POST', params: updatesubnetworkJson, url: updatesubnetworkUrl })
|
|
@@ -1015,8 +1009,8 @@ export class UtilityNetwork {
|
|
|
1015
1009
|
continueOnFailure: false,
|
|
1016
1010
|
traceConfiguration: subnetworkDef,
|
|
1017
1011
|
async: async,
|
|
1018
|
-
gdbVersion:
|
|
1019
|
-
|
|
1012
|
+
gdbVersion:this.gdbVersion,
|
|
1013
|
+
}
|
|
1020
1014
|
let un = this;
|
|
1021
1015
|
|
|
1022
1016
|
return makeRequest({method:'POST', params: exportsubnetworkJson, url: exportsubnetworkUrl })
|
|
@@ -1025,7 +1019,7 @@ export class UtilityNetwork {
|
|
|
1025
1019
|
|
|
1026
1020
|
}
|
|
1027
1021
|
|
|
1028
|
-
validateNetworkTopology (
|
|
1022
|
+
validateNetworkTopology (extentArea = null) {
|
|
1029
1023
|
|
|
1030
1024
|
const t = {"includeContainers":false,"includeContent":false,"includeStructures":true,"includeBarriers":true,"validateConsistency":true,"includeIsolated":false,"ignoreBarriersAtStartingPoints":false,"domainNetworkName":"","tierName":"","targetTierName":"","subnetworkName":"","diagramTemplateName":"","shortestPathNetworkAttributeName":"","filterBitsetNetworkAttributeName":"","traversabilityScope":"junctionsAndEdges","conditionBarriers":[{"name":"Operational Device Status","type":"networkAttribute","operator":"equal","value":1,"combineUsingOr":false,"isSpecificValue":true}],"functionBarriers":[],"arcadeExpressionBarrier":"","filterBarriers":[],"filterFunctionBarriers":[],"filterScope":"junctionsAndEdges","functions":[],"nearestNeighbor":{"count":-1,"costNetworkAttributeName":"","nearestCategories":[],"nearestAssets":[]},"outputFilters":[],"outputConditions":[],"propagators":[]}
|
|
1031
1025
|
|
|
@@ -1045,8 +1039,8 @@ export class UtilityNetwork {
|
|
|
1045
1039
|
token: this.token,
|
|
1046
1040
|
validateArea: JSON.stringify(extent),
|
|
1047
1041
|
async: false,
|
|
1048
|
-
gdbVersion:
|
|
1049
|
-
|
|
1042
|
+
gdbVersion:this.gdbVersion,
|
|
1043
|
+
}
|
|
1050
1044
|
|
|
1051
1045
|
return makeRequest({method:'POST', params: validateJson, url: validateUrl })
|
|
1052
1046
|
|
|
@@ -1079,6 +1073,7 @@ export class UtilityNetwork {
|
|
|
1079
1073
|
if (opts.headers)
|
|
1080
1074
|
Object.keys(opts.headers).forEach( key => headers[key] = opts.headers[key] )
|
|
1081
1075
|
|
|
1076
|
+
// console.log(params)
|
|
1082
1077
|
import("node-fetch")
|
|
1083
1078
|
.then( fetch => {
|
|
1084
1079
|
|
package/test.txt
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
echo topology -disable>cmd.txt
|
|
2
|
-
node un.mjs --portal https://utilitynetwork.esri.com/portal --user unadmin --password unadmin.108 --service GettingToKnow_Postgres --file cmd.txt
|
|
3
|
-
echo topology -enable>cmd.txt
|
|
4
|
-
node un.mjs --portal https://utilitynetwork.esri.com/portal --user unadmin --password unadmin.108 --service GettingToKnow_Postgres --file cmd.txt
|
|
5
|
-
echo update subnetworks -all>cmd.txt
|
|
6
|
-
node un.mjs --portal https://utilitynetwork.esri.com/portal --user unadmin --password unadmin.108 --service GettingToKnow_Postgres --file cmd.txt
|