| ofs | hex dump | ascii |
|---|
| 0000 | 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | MZ......................@....... |
| 0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 | ................................ |
| 0040 | 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f | ........!..L.!This.program.canno |
| 0060 | 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 | t.be.run.in.DOS.mode....$....... |
| 0080 | 50 45 00 00 4c 01 07 00 53 ac d7 4a 00 fc 04 00 6e 07 00 00 e0 00 06 23 0b 01 02 38 00 9c 02 00 | PE..L...S..J....n......#...8.... |
| 00a0 | 00 5c 02 00 00 06 00 00 a4 10 00 00 00 10 00 00 00 b0 02 00 00 00 60 66 00 10 00 00 00 02 00 00 | .\....................`f........ |
| 00c0 | 04 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00 00 40 05 00 00 04 00 00 b4 c8 05 00 03 00 00 00 | .................@.............. |
| 00e0 | 00 00 20 00 00 10 00 00 00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00 00 f0 04 00 35 18 00 00 | ............................5... |
| 0100 | 00 10 05 00 70 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ....p........................... |
| 0120 | 00 20 05 00 08 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2e 74 65 78 74 00 00 00 | .........................text... |
| 0180 | 10 9b 02 00 00 10 00 00 00 9c 02 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 30 60 | ..............................0` |
| 01a0 | 2e 64 61 74 61 00 00 00 ac 01 00 00 00 b0 02 00 00 02 00 00 00 a0 02 00 00 00 00 00 00 00 00 00 | .data........................... |
| 01c0 | 00 00 00 00 40 00 60 c0 2e 72 64 61 74 61 00 00 04 19 02 00 00 c0 02 00 00 1a 02 00 00 a2 02 00 | ....@.`..rdata.................. |
| 01e0 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 60 40 2e 62 73 73 00 00 00 00 94 04 00 00 00 e0 04 00 | ............@.`@.bss............ |
| 0200 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 40 c0 2e 65 64 61 74 61 00 00 | ......................@..edata.. |
| 0220 | 35 18 00 00 00 f0 04 00 00 1a 00 00 00 bc 04 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 30 40 | 5...........................@.0@ |
| 0240 | 2e 69 64 61 74 61 00 00 70 08 00 00 00 10 05 00 00 0a 00 00 00 d6 04 00 00 00 00 00 00 00 00 00 | .idata..p....................... |
| 0260 | 00 00 00 00 40 00 30 c0 2e 72 65 6c 6f 63 00 00 08 1a 00 00 00 20 05 00 00 1c 00 00 00 e0 04 00 | ....@.0..reloc.................. |
| 0280 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 30 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ............@.0B................ |
| 02a0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 02c0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 02e0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0300 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0320 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0340 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0360 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0380 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 03a0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 03c0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 03e0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................................ |
| 0400 | 83 ec 0c c7 44 24 08 10 e0 64 66 c7 44 24 04 00 e0 64 66 8b 44 24 10 89 04 24 e8 f9 99 02 00 83 | ....D$...df.D$...df.D$...$...... |
| 0420 | c4 0c c3 83 ec 0c c7 44 24 08 10 e0 64 66 c7 44 24 04 00 e0 64 66 8b 44 24 10 89 04 24 e8 d6 99 | .......D$...df.D$...df.D$...$... |
| 0440 | 02 00 83 f8 01 19 c0 83 c4 0c c3 53 83 ec 08 8b 15 00 e0 64 66 85 d2 74 3a 8b 0d 10 e0 64 66 8d | ...........S.......df..t:....df. |
| 0460 | 41 fc 39 c2 77 1b 8d 59 f8 8b 43 04 85 c0 74 08 ff d0 8b 15 00 e0 64 66 89 d8 83 eb 04 39 c2 76 | A.9.w..Y..C...t.......df.....9.v |
| 0480 | e8 89 14 24 e8 7f 99 02 00 c7 05 00 e0 64 66 00 00 00 00 c7 04 24 00 00 00 00 e8 71 99 02 00 83 | ...$.........df......$.....q.... |
| 04a0 | c4 08 5b c3 56 53 83 ec 14 8b 5c 24 24 83 fb 01 74 39 8b 44 24 28 89 44 24 08 89 5c 24 04 8b 44 | ..[.VS....\$$...t9.D$(.D$..\$..D |
| 04c0 | 24 20 89 04 24 e8 3a 98 02 00 83 ec 0c 89 c6 85 db 75 0e a1 00 e0 64 66 85 c0 74 68 e8 6a ff ff | $...$.:..........u....df..th.j.. |
| 04e0 | ff 89 f0 83 c4 14 5b 5e c2 0c 00 c7 04 24 80 00 00 00 e8 01 99 02 00 a3 00 e0 64 66 85 c0 74 50 | ......[^.....$............df..tP |
| 0500 | c7 00 00 00 00 00 a3 10 e0 64 66 e8 fc 97 02 00 e8 94 98 02 00 8b 44 24 28 89 44 24 08 c7 44 24 | .........df...........D$(.D$..D$ |
| 0520 | 04 01 00 00 00 8b 44 24 20 89 04 24 e8 d3 97 02 00 83 ec 0c 89 c6 85 c0 74 a2 89 f0 83 c4 14 5b | ......D$...$............t......[ |
| 0540 | 5e c2 0c 00 31 f6 89 f0 83 c4 14 5b 5e c2 0c 00 e8 ab 98 02 00 c7 00 0c 00 00 00 31 f6 eb 82 90 | ^...1......[^..............1.... |
| 0560 | 55 89 e5 57 56 53 83 ec 30 8b 7d 08 8b 5d 0c 8b 75 10 56 53 57 e8 f2 1b 00 00 83 c4 10 85 c0 75 | U..WVS..0.}..]..u.VSW..........u |
| 0580 | 5b 81 fb 3e 01 00 00 0f 84 4b 01 00 00 77 5d 81 fb 16 01 00 00 0f 84 85 01 00 00 0f 87 e9 00 00 | [..>.....K...w]................. |
| 05a0 | 00 81 fb 07 01 00 00 0f 84 e0 03 00 00 0f 86 3d 02 00 00 81 fb 12 01 00 00 0f 84 c9 02 00 00 81 | ...............=................ |
| 05c0 | fb 15 01 00 00 0f 84 aa 02 00 00 81 fb 0a 01 00 00 0f 84 43 02 00 00 90 31 c0 eb 08 b8 01 00 00 | ...................C....1....... |
| 05e0 | 00 8d 76 00 8d 65 f4 5b 5e 5f c9 c3 81 fb 12 02 00 00 0f 84 06 01 00 00 77 4f 81 fb 50 01 00 00 | ..v..e.[^_..............wO..P... |
| 0600 | 0f 84 27 02 00 00 0f 86 bb 01 00 00 81 fb 53 01 00 00 0f 84 4a 02 00 00 81 fb 11 02 00 00 0f 84 | ..'...........S.....J........... |
| 0620 | 2c 02 00 00 81 fb 52 01 00 00 75 ac 8b 16 8b 87 a8 00 00 00 66 89 02 8b 56 04 8b 87 ac 00 00 00 | ,.....R...u.........f...V....... |
| 0640 | 89 02 b8 01 00 00 00 eb 9b 81 fb e3 80 00 00 0f 84 a1 02 00 00 0f 86 d6 00 00 00 81 fb e5 80 00 | ................................ |
| 0660 | 00 0f 84 6d 02 00 00 0f 82 53 02 00 00 81 fb e6 80 00 00 0f 85 5f ff ff ff 8b 16 8b 47 4c 89 02 | ...m.....S..........._......GL.. |
| 0680 | b8 01 00 00 00 e9 5a ff ff ff 81 fb 1c 01 00 00 0f 84 d7 02 00 00 0f 86 00 01 00 00 81 fb 2d 01 | ......Z.......................-. |
| 06a0 | 00 00 0f 84 79 02 00 00 81 fb 3d 01 00 00 0f 84 56 02 00 00 81 fb 28 01 00 00 0f 85 18 ff ff ff | ....y.....=.....V.....(......... |
| 06c0 | 8b 16 8b 87 88 00 00 00 66 89 02 b8 01 00 00 00 e9 0f ff ff ff 8d 76 00 c7 05 40 e0 64 66 16 05 | ........f.............v...@.df.. |
| 06e0 | b1 3e c7 05 44 e0 64 66 3c 95 b7 3e 8b 06 c7 00 40 e0 64 66 b8 01 00 00 00 e9 e6 fe ff ff 8b 16 | .>..D.df<..>....@.df............ |
| 0700 | 8b 87 cc 00 00 00 66 89 02 8b 56 04 66 8b 87 ce 00 00 00 66 89 02 b8 01 00 00 00 e9 c4 fe ff ff | ......f...V.f......f............ |
| 0720 | 8b 16 8b 47 64 89 02 b8 01 00 00 00 e9 b3 fe ff ff 81 fb 13 02 00 00 0f 84 6e 01 00 00 81 fb 14 | ...Gd....................n...... |
| 0740 | 02 00 00 0f 85 8f fe ff ff 0f b7 4f 54 b8 01 00 00 00 d3 e0 48 50 db 04 24 83 c4 04 31 c0 a3 20 | ...........OT.......HP..$...1... |
| 0760 | e0 64 66 d9 15 24 e0 64 66 a3 28 e0 64 66 d9 15 2c e0 64 66 a3 30 e0 64 66 d9 1d 34 e0 64 66 66 | .df..$.df.(.df..,.df.0.df..4.dff |
| 0780 | 83 7f 5a 06 0f 84 2a 02 00 00 8b 06 c7 00 20 e0 64 66 b8 01 00 00 00 e9 48 fe ff ff 81 fb 18 01 | ..Z...*.........df......H....... |
| 07a0 | 00 00 0f 84 db 01 00 00 81 fb 19 01 00 00 0f 85 24 fe ff ff 8b 16 66 8b 47 6a 66 89 02 b8 01 00 | ................$.....f.Gjf..... |
| 07c0 | 00 00 e9 1d fe ff ff 81 fb 4c 01 00 00 0f 84 12 01 00 00 81 fb 4e 01 00 00 0f 85 f9 fd ff ff 8b | .........L...........N.......... |
| 07e0 | 06 66 c7 00 04 00 b8 01 00 00 00 e9 f4 fd ff ff 81 fb fe 00 00 00 0f 84 9e 00 00 00 81 fb 02 01 | .f.............................. |
| 0800 | 00 00 0f 85 d0 fd ff ff 8b 16 8b 47 54 66 89 02 b8 01 00 00 00 e9 ca fd ff ff 8b 16 66 8b 47 5e | ...........GTf..............f.G^ |
| 0820 | 66 89 02 b8 01 00 00 00 e9 b7 fd ff ff 8b 06 66 c7 00 00 00 8b 56 04 0f b7 4f 54 b8 01 00 00 00 | f..............f.....V...OT..... |
| 0840 | d3 e0 48 66 89 02 b8 01 00 00 00 e9 94 fd ff ff 8b 06 c7 00 18 b0 62 66 b8 01 00 00 00 e9 82 fd | ..Hf..................bf........ |
| 0860 | ff ff 8b 16 66 8b 47 56 66 89 02 b8 01 00 00 00 e9 6f fd ff ff 8b 16 66 8b 47 62 66 89 02 b8 01 | ....f.GVf........o.....f.Gbf.... |
| 0880 | 00 00 00 e9 5c fd ff ff 8b 16 8b 47 60 66 89 02 b8 01 00 00 00 e9 4a fd ff ff 8b 16 8b 47 50 89 | ....\......G`f........J......GP. |
| 08a0 | 02 b8 01 00 00 00 e9 39 fd ff ff 8b 16 8b 87 d0 00 00 00 66 89 02 b8 01 00 00 00 e9 24 fd ff ff | .......9...........f........$... |
| 08c0 | 8b 16 66 8b 47 56 48 66 89 02 b8 01 00 00 00 e9 10 fd ff ff 8b 16 8b 47 40 89 02 b8 01 00 00 00 | ..f.GVHf...............G@....... |
| 08e0 | e9 ff fc ff ff 8b 06 66 c7 00 01 00 b8 01 00 00 00 e9 ee fc ff ff 8b 16 66 83 bf a8 00 00 00 01 | .......f................f....... |
| 0900 | 0f 84 99 00 00 00 31 c0 eb a9 8b 06 8b 97 38 02 00 00 8b 12 66 89 10 b8 01 00 00 00 e9 c3 fc ff | ......1.......8.....f........... |
| 0920 | ff 8b 87 d4 00 00 00 85 c0 0f 84 97 00 00 00 0f b7 4f 62 0f b7 9f a8 00 00 00 8b 16 8b 87 d4 00 | .................Ob............. |
| 0940 | 00 00 89 02 29 d9 49 0f 8e 8f fc ff ff 8b 56 04 8b 87 d8 00 00 00 89 02 8b 56 08 8b 87 dc 00 00 | ....).I.......V..........V...... |
| 0960 | 00 89 02 b8 01 00 00 00 e9 77 fc ff ff 8b 16 66 8b 87 8a 00 00 00 66 89 02 b8 01 00 00 00 e9 61 | .........w.....f......f........a |
| 0980 | fc ff ff 8b 16 8b 47 68 e9 26 ff ff ff 8b 16 8b 47 5c 66 89 02 b8 01 00 00 00 e9 45 fc ff ff 8b | ......Gh.&......G\f........E.... |
| 09a0 | 87 ac 00 00 00 66 83 38 01 0f 94 c0 83 e0 01 e9 ff fe ff ff 8b 06 c7 00 00 b0 62 66 b8 01 00 00 | .....f.8..................bf.... |
| 09c0 | 00 e9 1e fc ff ff c7 87 dc 00 00 00 00 00 00 00 c7 87 d8 00 00 00 00 00 00 00 c7 87 d4 00 00 00 | ................................ |
| 09e0 | 00 00 00 00 8b 4f 54 66 83 f9 1d 0f 87 85 01 00 00 c7 45 d8 01 00 00 00 d3 65 d8 8b 45 d8 d1 e0 | .....OTf..........E......e..E... |
| 0a00 | 89 45 d4 83 ec 0c 50 e8 a4 77 02 00 89 87 d4 00 00 00 83 c4 10 85 c0 0f 84 59 01 00 00 66 c7 00 | .E....P..w...............Y...f.. |
| 0a20 | 00 00 83 7d d8 01 7e 77 d9 05 30 c0 62 66 da 6d d8 dd 5d e0 c7 45 dc 01 00 00 00 8b 5d dc d1 e3 | ...}..~w..0.bf.m..]..E......]... |
| 0a40 | 03 9f d4 00 00 00 68 99 99 01 40 68 9a 99 99 99 dd 45 e0 da 7d dc 83 ec 08 dd 1c 24 e8 c7 93 02 | ......h...@h.....E..}......$.... |
| 0a60 | 00 d8 0d 34 c0 62 66 d8 05 38 c0 62 66 dd 1c 24 e8 ab 93 02 00 83 c4 10 d9 7d ee 66 8b 45 ee b4 | ...4.bf..8.bf..$.........}.f.E.. |
| 0a80 | 0c 66 89 45 ec d9 6d ec db 5d e8 d9 6d ee 8b 45 e8 66 89 03 ff 45 dc 8b 45 d8 39 45 dc 75 9c 0f | .f.E..m..]..m..E.f...E..E.9E.u.. |
| 0aa0 | b7 4f 62 0f b7 9f a8 00 00 00 89 c8 29 d8 48 0f 8e 85 fe ff ff 83 ec 0c ff 75 d4 e8 f0 76 02 00 | .Ob.........).H..........u...v.. |
| 0ac0 | 89 87 d8 00 00 00 83 c4 10 85 c0 74 49 53 ff 75 d4 ff b7 d4 00 00 00 50 e8 a3 76 02 00 59 ff 75 | ...........tIS.u.......P..v..Y.u |
| 0ae0 | d4 e8 ca 76 02 00 89 87 dc 00 00 00 83 c4 10 85 c0 74 23 52 ff 75 d4 ff b7 d4 00 00 00 50 e8 7d | ...v.............t#R.u.......P.} |
| 0b00 | 76 02 00 83 c4 10 0f b7 4f 62 0f b7 9f a8 00 00 00 e9 24 fe ff ff 8b 87 d4 00 00 00 85 c0 74 0c | v.......Ob........$...........t. |
| 0b20 | 83 ec 0c 50 e8 7b 76 02 00 83 c4 10 8b 87 d8 00 00 00 85 c0 74 0c 83 ec 0c 50 e8 65 76 02 00 83 | ...P.{v.............t....P.ev... |
| 0b40 | c4 10 8b 87 dc 00 00 00 85 c0 74 0c 83 ec 0c 50 e8 4f 76 02 00 83 c4 10 c7 87 dc 00 00 00 00 00 | ..........t....P.Ov............. |
| 0b60 | 00 00 c7 87 d8 00 00 00 00 00 00 00 c7 87 d4 00 00 00 00 00 00 00 50 68 00 c0 62 66 ff 37 ff b7 | ......................Ph..bf.7.. |
| 0b80 | 64 02 00 00 e8 7b 8c 00 00 31 c0 83 c4 10 e9 51 fa ff ff 90 55 89 e5 83 ec 1c 8d 45 10 89 45 fc | d....{...1.....Q....U......E..E. |
| 0ba0 | 50 ff 75 0c ff 75 08 e8 b4 f9 ff ff c9 c3 66 90 55 89 e5 57 56 53 83 ec 0c 8b 75 08 8b 5d 10 8b | P.u..u........f.U..WVS....u..].. |
| 0bc0 | 55 14 85 db 74 04 85 d2 75 22 ff 75 18 68 24 c0 62 66 ff 36 ff b6 64 02 00 00 e8 25 8c 00 00 31 | U...t...u".u.h$.bf.6..d....%...1 |
| 0be0 | c0 83 c4 10 8d 65 f4 5b 5e 5f c9 c3 89 d1 0f af cb 89 c8 89 d7 31 d2 f7 f7 39 d8 75 cd 83 ec 08 | .....e.[^_...........1...9.u.... | <using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using Tango.BL;
using Tango.PPC.Common.Web;
using System.Data.Entity;
using Tango.BL.DTO;
using Tango.PPC.Common.Connection;
using Tango.BL.Builders;
using Tango.Settings;
using Tango.Core;
using Tango.PPC.Common.Authentication;
using Tango.Logging;
using System.Diagnostics;
using Tango.BL.Enumerations;
using Tango.PPC.Common.Application;
using Tango.Core.DI;
namespace Tango.PPC.Common.Synchronization
{
public class DefaultMachineDataSynchronizer : ExtendedObject, IMachineDataSynchronizer
{
private Timer _synchTimer;
private PPCWebClient client;
private IMachineProvider _machineProvider;
private IAuthenticationProvider _authenticationProvider;
private List<LogItemBase> _logs;
private bool _synchronizedOnce;
[TangoInject(TangoInjectMode.WhenAvailable)]
private IPPCApplicationManager _appManager;
public event EventHandler<SynchronizationStatusChangedEventArgs> CurrentStatusChanged;
public event EventHandler SynchronizationStarted;
public event EventHandler<SynchronizationEndedEventArgs> SynchronizationEnded;
public int MaxJobs { get; set; }
public int MaxJobRuns { get; set; }
public int MaxMachinesEvents { get; set; }
public int MaxOfflineUpdates { get; set; }
private SynchronizationStatus _currentStatus;
public SynchronizationStatus CurrentStatus
{
get { return _currentStatus; }
private set { _currentStatus = value; RaisePropertyChangedAuto(); }
}
private SynchronizationStatus _lastStatus;
public SynchronizationStatus LastStatus
{
get { return _lastStatus; }
private set { _lastStatus = value; RaisePropertyChangedAuto(); }
}
public SynchronizedObservableCollection<SynchronizationStatus> StatusHistory { get; private set; }
public TimeSpan Interval { get; set; }
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set { _isEnabled = value; OnEnableChanged(); RaisePropertyChangedAuto(); }
}
private bool _isSynchronizing;
public bool IsSynchronizing
{
get { return _isSynchronizing; }
set { _isSynchronizing = value; RaisePropertyChangedAuto(); }
}
public DefaultMachineDataSynchronizer()
{
StatusHistory = new SynchronizedObservableCollection<SynchronizationStatus>();
MaxJobs = 10;
MaxJobRuns = 10;
MaxMachinesEvents = 10;
MaxOfflineUpdates = 10;
var settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
Interval = settings.SynchronizationInterval;
_synchTimer = new Timer(Interval.TotalMilliseconds);
_synchTimer.Elapsed += _synchTimer_Elapsed;
_synchTimer.Enabled = true;
ExecuteNewStatus(TimeSpan.FromMinutes(2));
LastStatus = CurrentStatus;
}
public DefaultMachineDataSynchronizer(PPCWebClient ppcWebClient, IMachineProvider machineProvider, IAuthenticationProvider authenticationProvider) : this()
{
_logs = new List<LogItemBase>();
_machineProvider = machineProvider;
client = new PPCWebClient(ppcWebClient, TimeSpan.FromMinutes(10));
_authenticationProvider = authenticationProvider;
LogManager.NewLog += LogManager_NewLog;
}
private void LogManager_NewLog(object sender, LogItemBase e)
{
if (IsSynchronizing)
{
_logs.Add(e);
}
}
private String GetLogsStringAndClear()
{
String logsString = String.Join(Environment.NewLine, _logs.ToList().Select(x => x.ToString()));
_logs.Clear();
return logsString;
}
private void OnEnableChanged()
{
_synchTimer.Interval = Interval.TotalMilliseconds;
if (IsEnabled)
{
CurrentStatus.State = SynchronizationState.Pending;
}
else
{
CurrentStatus.State = SynchronizationState.Disabled;
}
}
private void _synchTimer_Elapsed(object sender, ElapsedEventArgs e)
{
_synchTimer.Interval = Interval.TotalMilliseconds;
try
{
Synchronize().GetAwaiter().GetResult();
}
catch { }
}
private async Task<UploadMachineDataRequest> CreateUploadMachineDataRequest(bool syncJobs, bool syncDiagnostics)
{
UploadMachineDataRequest request = new UploadMachineDataRequest();
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
if (syncJobs)
{
LogManager.Log("Checking Jobs...");
var jobs = await new JobsCollectionBuilder(db).Set(x => !x.IsSynchronized).WithSegments().WithBrushStops().Query(x => x.Take(MaxJobs).OrderByDescending(z => z.LastUpdated)).BuildListAsync();
List<JobDTO> dtos = new List<JobDTO>();
foreach (var job in jobs)
{
var dto = JobDTO.FromObservable(job);
request.Jobs.Add(dto);
}
}
if (syncDiagnostics)
{
LogManager.Log("Checking Job Runs...");
var jobRuns = await db.JobRuns.Where(x => !x.IsSynchronized).Take(MaxJobRuns).OrderByDescending(x => x.LastUpdated).ToListAsync();
List<JobRunDTO> dtos = new List<JobRunDTO>();
foreach (var jobRun in jobRuns)
{
var dto = JobRunDTO.FromObservable(jobRun);
request.JobRuns.Add(dto);
}
}
if (syncDiagnostics)
{
LogManager.Log("Checking Events...");
var machineEvents = await db.MachinesEvents.Where(x => !x.IsSynchronized).Take(MaxMachinesEvents).OrderByDescending(x => x.LastUpdated).ToListAsync();
List<MachinesEventDTO> dtos = new List<MachinesEventDTO>();
foreach (var machineEvent in machineEvents)
{
machineEvent.IsSynchronized = true;
var dto = MachinesEventDTO.FromObservable(machineEvent);
request.MachineEvents.Add(dto);
}
}
if (syncDiagnostics)
{
LogManager.Log("Checking Offline Updates...");
var tangoUpdates = await db.TangoUpdates.Where(x => !x.IsSynchronized && (x.Status == (int)TangoUpdateStatuses.OfflineUpdateCompleted || x.Status == (int)TangoUpdateStatuses.OfflineUpdateFailed || x.Status == (int)TangoUpdateStatuses.OfflineFirmwareUpgradeCompleted || x.Status == (int)TangoUpdateStatuses.OfflineFirmwareUpgradeFailed)).Take(MaxOfflineUpdates).OrderByDescending(x => x.LastUpdated).ToListAsync();
List<TangoUpdateDTO> dtos = new List<TangoUpdateDTO>();
foreach (var tangoUpdate in tangoUpdates)
{
tangoUpdate.IsSynchronized = true;
var dto = TangoUpdateDTO.FromObservable(tangoUpdate);
request.OfflineUpdates.Add(dto);
}
}
}
return request;
}
private async Task FinalizeMachineDataUpload(UploadMachineDataRequest request, UploadMachineDataResponse response)
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
//Finalize jobs
foreach (var job in request.Jobs)
{
var failedJob = response.FailedJobs.SingleOrDefault(x => x.Guid == job.Guid);
if (failedJob == null)
{
var dbJob = await db.Jobs.SingleOrDefaultAsync(x => x.Guid == job.Guid);
dbJob.IsSynchronized = true;
}
else
{
LogManager.Log($"Synchronization Error - Job '{job.Name}' cannot be stored on the server due to the following reason:\n{failedJob.Reason}", LogCategory.Error);
}
}
//Finalize job runs
foreach (var jobRun in request.JobRuns)
{
var failedJobRun = response.FailedJobRuns.SingleOrDefault(x => x.Guid == jobRun.Guid);
if (failedJobRun == null)
{
var dbJobRun = await db.JobRuns.SingleOrDefaultAsync(x => x.Guid == jobRun.Guid);
dbJobRun.IsSynchronized = true;
}
else
{
LogManager.Log($"Synchronization Error - JobRun '{jobRun.ID}' cannot be stored on the server due to the following reason:\n{failedJobRun.Reason}", LogCategory.Error);
}
}
//Finalize machine events
foreach (var machineEvent in request.MachineEvents)
{
var failedMachineEvent = response.FailedMachineEvents.SingleOrDefault(x => x.Guid == machineEvent.Guid);
if (failedMachineEvent == null)
{
var dbMachineEvent = await db.MachinesEvents.SingleOrDefaultAsync(x => x.Guid == machineEvent.Guid);
dbMachineEvent.IsSynchronized = true;
}
else
{
LogManager.Log($"Synchronization Error - Event '{machineEvent.ID}' cannot be stored on the server due to the following reason:\n{failedMachineEvent.Reason}", LogCategory.Error);
}
}
//Finalize tango updates
foreach (var tangoUpdate in request.OfflineUpdates)
{
var failedTangoUpdate = response.FailedOfflineUpdates.SingleOrDefault(x => x.Guid == tangoUpdate.Guid);
if (failedTangoUpdate == null)
{
var dbTangoUpdate = await db.TangoUpdates.SingleOrDefaultAsync(x => x.Guid == tangoUpdate.Guid);
dbTangoUpdate.IsSynchronized = true;
}
else
{
LogManager.Log($"Synchronization Error - TangoUpdate '{tangoUpdate.ID}' cannot be stored on the server due to the following reason:\n{failedTangoUpdate.Reason}", LogCategory.Error);
}
}
await db.SaveChangesAsync();
}
}
private async Task<DownloadMachineDataResponse> DownloadMachineData(bool syncJobs, bool syncDiagnostics)
{
return await client.DownloadMachineData(new DownloadMachineDataRequest()
{
RequestJobs = syncJobs,
RequestJobRuns = syncDiagnostics,
RequestMachineEvents = syncDiagnostics,
MaxJobs = MaxJobs,
MaxJobRuns = MaxJobRuns,
MaxMachinesEvents = MaxMachinesEvents,
});
}
private async Task<NotifyMachineDataDownloadCompletedRequest> InsertReplaceMachineData(DownloadMachineDataResponse response)
{
NotifyMachineDataDownloadCompletedRequest request = new NotifyMachineDataDownloadCompletedRequest();
//Insert/Replace Jobs.
if (response.Jobs.Count > 0)
{
LogManager.Log("Inserting/Replacing Jobs...");
}
foreach (var dto in response.Jobs)
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
try
{
var job = dto.ToObservable();
job.ID = 0;
job.UserGuid = _authenticationProvider.CurrentUser.Guid;
job.CustomerGuid = null;
job.IsSynchronized = true;
var existingJob = await db.Jobs.SingleOrDefaultAsync(x => x.Guid == job.Guid);
if (existingJob == null)
{
db.Jobs.Add(job);
await db.SaveChangesAsync();
}
else if (job.LastUpdated > existingJob.LastUpdated)
{
existingJob.Delete(db);
db.Jobs.Add(job);
await db.SaveChangesAsync();
}
request.SynchronizedJobs.Add(job.Guid);
}
catch (Exception ex)
{
LogManager.Log($"Synchronization Error - Job '{dto.Name}' cannot be stored locally due to the following reason:\n{ex.FlattenMessage()}", LogCategory.Error);
}
}
}
//Insert JobRuns.
if (response.JobRuns.Count > 0)
{
LogManager.Log("Inserting/Replacing Job Runs...");
}
foreach (var dto in response.JobRuns)
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
try
{
var run = dto.ToObservable();
run.ID = 0;
run.IsSynchronized = true;
if (await db.JobRuns.SingleOrDefaultAsync(x => x.Guid == run.Guid) == null)
{
db.JobRuns.Add(run);
await db.SaveChangesAsync();
}
request.SynchronizedJobRuns.Add(run.Guid);
}
catch (Exception ex)
{
LogManager.Log($"Synchronization Error - JobRun '{dto.ID}' cannot be stored locally due to the following reason:\n{ex.FlattenMessage()}", LogCategory.Error);
}
}
}
//Insert MachineEvents.
if (response.MachineEvents.Count > 0)
{
LogManager.Log("Inserting/Replacing Events...");
}
foreach (var dto in response.MachineEvents)
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
try
{
var ev = dto.ToObservable();
ev.ID = 0;
ev.UserGuid = _authenticationProvider.CurrentUser.Guid;
ev.IsSynchronized = true;
if (await db.MachinesEvents.SingleOrDefaultAsync(x => x.Guid == ev.Guid) == null)
{
db.MachinesEvents.Add(ev);
await db.SaveChangesAsync();
}
request.SynchronizedMachineEvents.Add(ev.Guid);
}
catch (Exception ex)
{
LogManager.Log($"Synchronization Error - Event '{dto.ID}' cannot be stored locally due to the following reason:\n{ex.FlattenMessage()}", LogCategory.Error);
}
}
}
return request;
}
public async Task Synchronize()
{
_synchronizedOnce = true;
if (!IsEnabled || IsSynchronizing) return;
var settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
var syncJobs = settings.SynchronizeJobs;
var syncDiagnostics = settings.SynchronizeDiagnostics;
if (!syncJobs && !syncDiagnostics) return;
IsSynchronizing = true;
SynchronizationStarted?.Invoke(this, new EventArgs());
_logs.Clear();
_synchTimer.Stop();
LogManager.Log("Starting machine data synchronization...");
LogManager.Log($"Synchronization interval: {Interval}.");
CurrentStatus.StartDateTime = DateTime.Now;
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Starting synchronization...");
Stopwatch watch = new Stopwatch();
watch.Start();
String notifyToken = null;
int newChangedJobs = 0;
int newJobRuns = 0;
int newMachineEvents = 0;
try
{
LogManager.Log("Authenticating with machine service...");
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Authenticating with machine service...");
if (!this.client.IsAuthenticated)
{
await this.client.Login(new LoginRequest()
{
Mode = LoginMode.Machine,
SerialNumber = _machineProvider.Machine.SerialNumber,
});
}
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Preparing machine data for upload...");
LogManager.Log("Preparing machine data for upload...");
var request = await CreateUploadMachineDataRequest(syncJobs, syncDiagnostics);
request.ApplicationVersion = _appManager.Version.ToString();
request.FirmwareVersion = _appManager.FirmwareVersion.ToString();
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Uploading machine data...");
LogManager.Log($"Uploading machine data:\nJobs: {request.Jobs.Count}\nJob Runs: {request.JobRuns.Count}\nEvents: {request.MachineEvents.Count}\nOffline Updates: {request.OfflineUpdates.Count}");
var response = await this.client.UploadMachineData(request);
notifyToken = response.NotifyCompletedToken;
LogManager.Log($"Upload response received:\nFailed Jobs: {response.FailedJobs.Count}\nFailed Job Runs: {response.FailedJobRuns.Count}\nFailed Events: {response.FailedMachineEvents.Count}\nFailed Offline Updates: {response.FailedOfflineUpdates.Count}");
LogManager.Log("Finalizing upload...");
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Finalizing upload...");
await FinalizeMachineDataUpload(request, response);
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Downloading machine data from service...");
LogManager.Log("Downloading machine data from server...");
var downloadResponse = await DownloadMachineData(syncJobs, syncDiagnostics);
newChangedJobs = downloadResponse.Jobs.Count;
newJobRuns = downloadResponse.JobRuns.Count;
newMachineEvents = downloadResponse.MachineEvents.Count;
LogManager.Log($"Download response received:\nJobs: {downloadResponse.Jobs.Count}\nJob Runs: {downloadResponse.JobRuns.Count}\nEvents: {downloadResponse.MachineEvents.Count}");
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Updating local database...");
LogManager.Log("Updating local database...");
var notifyRequest = await InsertReplaceMachineData(downloadResponse);
LogManager.Log($"Finalizing download:\nSynchronized Jobs: {notifyRequest.SynchronizedJobs.Count}\nSynchronized Job Runs: {notifyRequest.SynchronizedJobRuns.Count}\nSynchronized Events: {notifyRequest.SynchronizedMachineEvents.Count}");
UpdateCurrentStatus(SynchronizationState.Synchronizing, "Finalizing download...");
var notifyResponse = await this.client.NotifyMachineDataDownloadCompleted(notifyRequest);
if (notifyToken != null)
{
try
{
await client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
{
Token = notifyToken,
Status = TangoUpdateStatuses.SynchronizationCompleted,
});
}
catch (Exception ex)
{
LogManager.Log(ex, "Synchronization completed successfully but an error occurred when trying to notify about the completion.");
}
}
LogManager.Log("Machine data synchronization completed successfully.");
UpdateCurrentStatus(SynchronizationState.Completed, "Synchronization completed successfully.", null, watch.Elapsed);
}
catch (Exception ex)
{
if (notifyToken != null)
{
try
{
await client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
{
Token = notifyToken,
Status = TangoUpdateStatuses.SynchronizationFailed,
FailedReason = ex.FlattenMessage(),
FailedLog = GetLogsStringAndClear(),
});
}
catch (Exception ee)
{
LogManager.Log(ee, "Synchronization completed successfully but an error occurred when trying to notify about the completion.");
}
}
UpdateCurrentStatus(SynchronizationState.Failed, "Synchronization failed.", ex.FlattenMessage(), watch.Elapsed);
throw LogManager.Log(ex, "Error occurred while synchronizing machine data.");
}
finally
{
watch.Stop();
LogManager.Log($"Synchronization duration: {watch.Elapsed}.");
LastStatus = CurrentStatus;
CreateNewStatus();
IsSynchronizing = false;
SynchronizationEnded?.Invoke(this, new SynchronizationEndedEventArgs()
{
NewChangedJobs = newChangedJobs,
NewJobRuns = newJobRuns,
NewMachineEvents = newMachineEvents,
});
}
_synchTimer.Start();
}
private void CreateNewStatus()
{
CurrentStatus = new SynchronizationStatus();
CurrentStatus.State = SynchronizationState.Pending;
CurrentStatus.StartDateTime = DateTime.Now.Add(Interval);
StatusHistory.Insert(0, CurrentStatus);
}
private async void ExecuteNewStatus(TimeSpan delay)
{
CurrentStatus = new SynchronizationStatus();
CurrentStatus.State = SynchronizationState.Pending;
CurrentStatus.StartDateTime = DateTime.Now.Add(delay);
StatusHistory.Insert(0, CurrentStatus);
await Task.Delay(delay);
try
{
if (!_synchronizedOnce)
{
await Synchronize();
}
}
catch { }
}
private void UpdateCurrentStatus(SynchronizationState state, String message, String errorReason = null, TimeSpan? duration = null)
{
CurrentStatus.State = state;
CurrentStatus.Message = message;
CurrentStatus.ErrorReason = errorReason;
CurrentStatus.Duration = duration;
CurrentStatusChanged?.Invoke(this, new SynchronizationStatusChangedEventArgs()
{
Status = CurrentStatus,
});
}
}
}