mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-01 23:56:25 +08:00
Compare commits
751 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e6ea7b193 | |||
| fe3e17c3ad | |||
| 38912aed76 | |||
| 98215396f1 | |||
| bdf93565a3 | |||
| 406a77d5b8 | |||
| 84f8074d6a | |||
| 75af5447ae | |||
| e6d502f0ff | |||
| 1f6225db41 | |||
| 16c2028687 | |||
| fd87d70b56 | |||
| 5dbeac7dcf | |||
| c32b437821 | |||
| 535736bad1 | |||
| 3b9ff16b3b | |||
| 22b1403819 | |||
| 3658f2b198 | |||
| 37bd1526d7 | |||
| 8a2d0e9e3a | |||
| c411cc4bc8 | |||
| 055853593a | |||
| 31778c9cdf | |||
| 5fd464979d | |||
| a2fc790cba | |||
| 20bb77f0f7 | |||
| 52fcf70739 | |||
| e92a09ecf5 | |||
| a23ecb1710 | |||
| d7c66c6f45 | |||
| d7802e15a8 | |||
| 95b1d09a3c | |||
| 32b60db21b | |||
| e62f5d8d7c | |||
| 2f1d9f6265 | |||
| 06a5ef9417 | |||
| 4203705bf5 | |||
| bfd1df751e | |||
| 6716a92085 | |||
| d9c7c57343 | |||
| 5a9ecbf295 | |||
| 70b6cd360d | |||
| 04474c6747 | |||
| f5dcc6c8a3 | |||
| aee309097b | |||
| 732afeab3c | |||
| c42a47b6b9 | |||
| cb14fca6c7 | |||
| a7a2bd3e4f | |||
| e55bd7adae | |||
| 9468589cc7 | |||
| bcf2f0f443 | |||
| 1c67fab186 | |||
| e82a08bbbd | |||
| 29dade90ec | |||
| ec6036b5fa | |||
| fea3c5358a | |||
| 4b8af3be2e | |||
| 7059d6b5fb | |||
| c02f3cc8d5 | |||
| ece2498d18 | |||
| 7bf9d5a305 | |||
| c64657d0b7 | |||
| c2e1d5a21e | |||
| 05889706dd | |||
| 91cb0607e3 | |||
| 5d82447e92 | |||
| 0ae58dac79 | |||
| 4bdf6be372 | |||
| f44ba40098 | |||
| ffba76cc6b | |||
| e547266755 | |||
| f75bfdabe6 | |||
| f6756008b0 | |||
| ff22ea7108 | |||
| 28fad04d5c | |||
| a3e3dc03c9 | |||
| d50a24e9b1 | |||
| b494c73328 | |||
| c2b7d3bc2c | |||
| 54bba9a867 | |||
| 7bb069d435 | |||
| 325d898695 | |||
| 7a9e0af8ed | |||
| 6bf5b86227 | |||
| ffe7cc3b10 | |||
| c2d02cbc4c | |||
| 3dba5495a6 | |||
| 387ac6e930 | |||
| ea4335bb24 | |||
| 1e93297968 | |||
| f80372ded4 | |||
| bb667238f2 | |||
| be9c8fcab7 | |||
| 000c68dddd | |||
| 2e99a45dae | |||
| 5d115bf651 | |||
| 49737a2dda | |||
| 4df0f78af5 | |||
| 94b4a18f2d | |||
| 9f32e3a9bc | |||
| e416ace264 | |||
| dbc4fd5e4a | |||
| 0cb1fc3e52 | |||
| 898adbb833 | |||
| aaa1fb29cd | |||
| 92f64ddf7c | |||
| 1f94357498 | |||
| e6c2568f6b | |||
| 80f25c54c9 | |||
| 807c6eae15 | |||
| 28b4506395 | |||
| dd6b47fbbb | |||
| 4ca3e757bd | |||
| 3a3784329e | |||
| bedd554269 | |||
| e2be0fc093 | |||
| d787668911 | |||
| cae8b377b0 | |||
| ba20fa90f7 | |||
| d325eed4a3 | |||
| 48a6265465 | |||
| 1ac6279569 | |||
| 2095e0839d | |||
| 8bb177a693 | |||
| 01d3fefd5d | |||
| 3de21d13bd | |||
| 840e79ca16 | |||
| 941c1f954e | |||
| 12dd42c60d | |||
| 0642f97e12 | |||
| a9569a2a97 | |||
| e50b8bd8f1 | |||
| 09ffe40011 | |||
| c6611a6679 | |||
| 0fffa0c43b | |||
| d345fc80c7 | |||
| 7930a8bf85 | |||
| f828a6b122 | |||
| c48d479053 | |||
| 144e511672 | |||
| 4e66f4d237 | |||
| b44c895d12 | |||
| 28c7a959a6 | |||
| 51ab6a6156 | |||
| 378221f903 | |||
| 359e6b1c46 | |||
| e5724b32e1 | |||
| 45f0a5445e | |||
| 64bb62d814 | |||
| 74de8825f6 | |||
| 491d87872c | |||
| 27e475a122 | |||
| b61b7c9216 | |||
| e2f56443ea | |||
| e36560a630 | |||
| 8d698ce1c2 | |||
| ec38c8535d | |||
| 65b54c85a9 | |||
| 149fa3a4e3 | |||
| 9394ac658e | |||
| 6d7f8c68e5 | |||
| a5147ca564 | |||
| e6bf4da430 | |||
| 67c9553722 | |||
| 5b3e977665 | |||
| c19952d483 | |||
| 6772c25deb | |||
| 06047ae778 | |||
| 2b6f382c4a | |||
| 6f3d17b927 | |||
| e8ff01790b | |||
| 539e0fdfb6 | |||
| 2d41819008 | |||
| 3fbeb622a2 | |||
| c5a494f28b | |||
| e1f5b2afe0 | |||
| ce7ae6a9b9 | |||
| 86cf2f3263 | |||
| 06a1f9edef | |||
| 6394ad9227 | |||
| 5b76d9e853 | |||
| 18ae8f67d0 | |||
| 70d2f93a40 | |||
| d41b91c67f | |||
| 633f0ade3e | |||
| 21a68c353a | |||
| 66d8fafc8d | |||
| fe58c8459b | |||
| 79f4ef5b99 | |||
| 7947cfa08e | |||
| c7b3f6e94f | |||
| 42d78368e5 | |||
| 9b39428f26 | |||
| 220cd9fc09 | |||
| 3d5670bc96 | |||
| 909ed48b1e | |||
| c6595bee54 | |||
| 32e60fd250 | |||
| cd86f8b03f | |||
| c002967c9d | |||
| 61ea5b1912 | |||
| fdbc60eef1 | |||
| 0831593a45 | |||
| ea58e22f33 | |||
| 8c471955e3 | |||
| 2e74d0c22f | |||
| 68ff2b0cdb | |||
| 8f45b1d794 | |||
| 1496a23fdc | |||
| e39367049a | |||
| 76612469c6 | |||
| 7eadf9ef6e | |||
| 03be4a4494 | |||
| 7e0e779cbf | |||
| 8007488ee3 | |||
| 2e2980028d | |||
| 36cd78c3be | |||
| 5a8f2e8157 | |||
| 0e41f8621d | |||
| 472ab6cfad | |||
| 94abdbd664 | |||
| 0de951f065 | |||
| ad1fe42352 | |||
| 3d431abf30 | |||
| 14b2e3f4f0 | |||
| 74c94d39db | |||
| 103c231a1d | |||
| 47f94ada70 | |||
| 0ca55c088d | |||
| 40a0663f9f | |||
| ed71f4fb9a | |||
| 4d78ab0de3 | |||
| b9dc4d302e | |||
| e21982534e | |||
| 0ef4fbfa5a | |||
| 1a034cfc66 | |||
| 6ca3de6063 | |||
| d30efd7425 | |||
| db721ace5f | |||
| 01fedcf83f | |||
| 70e25f688e | |||
| 29bc6f17ce | |||
| 0d93480e39 | |||
| 097df11840 | |||
| 84609dd73a | |||
| b613a045d5 | |||
| c85bbe0488 | |||
| 4ca0212629 | |||
| 51c51a6668 | |||
| 2acb856021 | |||
| 7b9db69f87 | |||
| 97eec5cc48 | |||
| 84b36e8e1b | |||
| 46f36474f2 | |||
| dd532a6039 | |||
| 9ed2513e6c | |||
| fbaea5dba1 | |||
| cf5ed40bd7 | |||
| cd7bcc75b6 | |||
| 5af0932fa8 | |||
| 312d8cffc2 | |||
| 312d61abe2 | |||
| 30a3ce80d6 | |||
| 0092ec1871 | |||
| 2cf15e8893 | |||
| 796612d56e | |||
| e009aea244 | |||
| b8772ceb0f | |||
| 6c5190f10f | |||
| 2710db63a1 | |||
| 4a7026622e | |||
| 09fe19d97b | |||
| 7812a4bb58 | |||
| e7afb35b31 | |||
| a45e763fef | |||
| f42b9a6dfe | |||
| 465dbf09cd | |||
| 8c27ac3afc | |||
| e598d8ad79 | |||
| bb65c7293e | |||
| 2f23baa629 | |||
| 22ad94b336 | |||
| 5870e9f599 | |||
| 9af98618b4 | |||
| d09576f54d | |||
| fcabd1b1cf | |||
| 8aefd41cdd | |||
| ff1718fef5 | |||
| 6cc0fcf928 | |||
| ad74d39e02 | |||
| a248e0ffad | |||
| f31410c6b1 | |||
| d53d35c831 | |||
| 43eb2326d1 | |||
| 8246d0dd9f | |||
| bc12c74b85 | |||
| a047b4c5e6 | |||
| a39a3a9c0c | |||
| 103b0c3050 | |||
| 795f78655f | |||
| 1a6945f40b | |||
| ec2ff42080 | |||
| eabb095dba | |||
| b82c795b50 | |||
| fd30e5f469 | |||
| 95b9f0d4a3 | |||
| 7c3a3d7c7c | |||
| 59c7300bc8 | |||
| 610a66395a | |||
| b6d3623dd7 | |||
| 0f4b615aa3 | |||
| 8b616df1d5 | |||
| 7aba8d1250 | |||
| 7f05212771 | |||
| c82e35f55c | |||
| 3651292186 | |||
| e01c6799ac | |||
| d04133c042 | |||
| b82062ff54 | |||
| d914eb92d4 | |||
| 0a36ff7eec | |||
| 727e08f333 | |||
| 9c7165d121 | |||
| 9e3103cb90 | |||
| 5f513287ba | |||
| c4a5eb9cb3 | |||
| a5f79eae07 | |||
| bdb8642c12 | |||
| 5709238c2b | |||
| ae86caf39e | |||
| 5148f3fdb6 | |||
| eb0a8132d5 | |||
| ad94857351 | |||
| d3badd279a | |||
| d947ca0965 | |||
| 92b9df8541 | |||
| 92c2a420e9 | |||
| ade80af037 | |||
| b5456da3f3 | |||
| f23e904171 | |||
| 6cb8f01a74 | |||
| af8d412d1a | |||
| 4e5d180bfa | |||
| ae2342353f | |||
| d1985a6de8 | |||
| d8f751eb4f | |||
| d6200180d9 | |||
| f0a22e6a6c | |||
| fb018985c2 | |||
| 7f1b2bd59a | |||
| 4e51e4e79b | |||
| 6f6382eae2 | |||
| d275f6b4d4 | |||
| 1096dcd49e | |||
| 01adec6003 | |||
| e5d6107795 | |||
| 06c74de0a8 | |||
| 31ab45d246 | |||
| c458d59da5 | |||
| 5e5654f513 | |||
| cbba9bdeb3 | |||
| cf85ed2ffe | |||
| 3568c58574 | |||
| ba095cd196 | |||
| 0edd99825d | |||
| d7bae8573e | |||
| 5ada15a461 | |||
| 24e3196bf5 | |||
| 0211f568a0 | |||
| 5e60ba7f0d | |||
| 69b805a537 | |||
| 5c405a9f3f | |||
| ce22696760 | |||
| cf9a7a7cb7 | |||
| 3189937aca | |||
| 3ef9db0ebe | |||
| e6161ee410 | |||
| f824b824e0 | |||
| 14959b7d96 | |||
| 6dce8188dc | |||
| 8a869335ad | |||
| 3ecc50bc3d | |||
| cf8cc38e22 | |||
| 3cca12f0b7 | |||
| a05e5b6bca | |||
| b64f141f9a | |||
| 431472363d | |||
| e4eea8cb35 | |||
| 7ae19ad111 | |||
| 244d38b616 | |||
| 3df74a08fa | |||
| 2d6d5e707f | |||
| d98c9683e6 | |||
| a7c7b5ce58 | |||
| f9014afe94 | |||
| bbf3c2d981 | |||
| bbd3ebc9c9 | |||
| 6655a4135c | |||
| f3f014c170 | |||
| dec96cd429 | |||
| 315fc6024e | |||
| 8583dd017a | |||
| 036105ab47 | |||
| f71d9b95c1 | |||
| 9d2a2804ab | |||
| d5c338dee5 | |||
| 1536d7e259 | |||
| 1bdf743193 | |||
| b3f924c081 | |||
| 434f09c6d8 | |||
| d3e6d210ee | |||
| 5f5320e353 | |||
| c18b0ce26e | |||
| 6d1930d0d1 | |||
| a8cd3129e7 | |||
| b0d8fe5c3d | |||
| 5f9f1ab996 | |||
| cab0a46fb3 | |||
| 1cbd2eed9d | |||
| 389ea2c726 | |||
| e923cbd53e | |||
| e1eb18db13 | |||
| 2ee723c134 | |||
| 8de737f0b3 | |||
| 320aad203c | |||
| 2f3a731f3a | |||
| a6b1a35bea | |||
| a62d5b3897 | |||
| f7ab01be27 | |||
| 3da22fc1cc | |||
| 70a576123d | |||
| 0c7d6022ca | |||
| 3a04780aec | |||
| d52a9a9206 | |||
| 34cbbbd826 | |||
| 9ea6520092 | |||
| 5010060459 | |||
| 52869c9a39 | |||
| 12efe434ee | |||
| e0f3014c4e | |||
| ff81d7a6a5 | |||
| 830d3f9a28 | |||
| fe5b457f29 | |||
| cbf53e12cd | |||
| 3825653c49 | |||
| 4329cfc414 | |||
| d9aa410045 | |||
| 2f62db66cb | |||
| 05e378fe37 | |||
| ad5d32538c | |||
| 929c0415a1 | |||
| 866a41472d | |||
| 5df0598aea | |||
| 6515599986 | |||
| 3f313a40d2 | |||
| 448cdddc80 | |||
| 71ae2d1f01 | |||
| 68df4c86ee | |||
| 4609675a39 | |||
| dc3206dd3e | |||
| 2661f71671 | |||
| 57d2be140a | |||
| 7d9494ebb2 | |||
| 2d55e92d8c | |||
| 439110f95b | |||
| 54589814f8 | |||
| 13498a5f95 | |||
| 119aa4df02 | |||
| 6ce261c7f1 | |||
| c2a1134a53 | |||
| 9d63a09ec1 | |||
| 60f8c117c1 | |||
| c41fd248cc | |||
| 9594f6a2df | |||
| d6971f959e | |||
| 61f58bf465 | |||
| d990af7e71 | |||
| b9597a139b | |||
| 85b9a2cc39 | |||
| f002044db1 | |||
| 40494f605b | |||
| 1c36220c1f | |||
| 96f2eea111 | |||
| 7a5c8323df | |||
| 6e088f1eb8 | |||
| 29f9931a42 | |||
| f3fbe86ca4 | |||
| 89098f65d6 | |||
| 3c9afe5bcf | |||
| cb44e1678d | |||
| 26edb159d9 | |||
| 5013a2cd42 | |||
| f189bb83e5 | |||
| daec07b09e | |||
| 67da48a41a | |||
| c05a98dca6 | |||
| 9bacd07973 | |||
| 7e517b9ab9 | |||
| c2782a4bb6 | |||
| 0a2e4d2325 | |||
| 4e8b240dc6 | |||
| 87fed2bb0f | |||
| 0363bce110 | |||
| 2b60982327 | |||
| 4c5b4a38fc | |||
| a97eb7b7c9 | |||
| b4a8e9a2c4 | |||
| 60486f3b2e | |||
| f6e0fa378c | |||
| 73db052ab3 | |||
| c48e149ae6 | |||
| 3c9ca0b006 | |||
| e1ab1a00ae | |||
| 463d0a4ca7 | |||
| 1cc9a5a2ae | |||
| e377ac3b06 | |||
| aa54133ed5 | |||
| 6a94de9c84 | |||
| b02859bbfe | |||
| ce2830e9a1 | |||
| 7e28c27f2a | |||
| 9553b4056e | |||
| 381213ae75 | |||
| 10da5beb5a | |||
| 41af67be53 | |||
| 716d6accb7 | |||
| 965c8bd9a4 | |||
| fba3b25225 | |||
| c1dd36d09e | |||
| b998162a7e | |||
| 94b7ce2172 | |||
| 2a75b42e6a | |||
| 4c884ee078 | |||
| d9b5fc8be0 | |||
| c9a9eb7ec6 | |||
| 2843f8b03d | |||
| 29ca352766 | |||
| a40a9da324 | |||
| 6680833efb | |||
| 4a8ad389d8 | |||
| e444ba3fd0 | |||
| 103c0f88ee | |||
| 7ecd39acb7 | |||
| ccc34bcb0a | |||
| 1b87c322b3 | |||
| 384d39120d | |||
| cad360869e | |||
| 0390a34ee6 | |||
| ae9be873c5 | |||
| 5c26611886 | |||
| e56c8923a2 | |||
| c35d7d3e01 | |||
| 8ed629118e | |||
| bf42f0b907 | |||
| d5ffbf4d67 | |||
| 8511ea166b | |||
| d14e9c8430 | |||
| 6adef7b562 | |||
| 86a6ab1c47 | |||
| 7e38335f0c | |||
| daa716a083 | |||
| d8814ad09f | |||
| aee20ffe09 | |||
| 880901364f | |||
| a98950381e | |||
| eac4215f62 | |||
| bbf125b351 | |||
| 52461c09b5 | |||
| 7762d57609 | |||
| ac52b250e7 | |||
| 5070a72752 | |||
| 5326741b26 | |||
| aae7bb45ec | |||
| 51eec6ccaa | |||
| 56e26a31bb | |||
| bbbeaa0f0d | |||
| db93f7cba9 | |||
| d17559c528 | |||
| 2c2b5d5737 | |||
| 8708659761 | |||
| c0a9ddb760 | |||
| 4d2f3fa219 | |||
| c7e0a57b50 | |||
| e8670896b3 | |||
| d5167688b1 | |||
| 1fda2e5135 | |||
| d6dc839f34 | |||
| 1af6e628ff | |||
| fa7c6b6f52 | |||
| a35712f281 | |||
| 5e76a8b3a8 | |||
| 3345771bca | |||
| 37c668cc29 | |||
| db4d8976f8 | |||
| 7b2de29e30 | |||
| ae7e681bca | |||
| 61c102c794 | |||
| 8a1ddafec8 | |||
| c4d3f87bf1 | |||
| 270034204c | |||
| c65c1a0859 | |||
| b238ccbc29 | |||
| ebd3a2e84f | |||
| 81374ef98f | |||
| 831f074a99 | |||
| 0f38dc5c6b | |||
| 1a5f3c25c1 | |||
| 28a5ca824c | |||
| faee88a442 | |||
| 231ce47fd6 | |||
| 09f818f0f9 | |||
| a6bdc36318 | |||
| 2d107ec5af | |||
| 2eedba89d4 | |||
| e67fe4ca88 | |||
| b4caadc704 | |||
| f26170540f | |||
| e459295a72 | |||
| 58c717f75b | |||
| b8dae3b1c2 | |||
| b2f049827e | |||
| 8cf3977208 | |||
| 82b1dfea56 | |||
| 6c8e11caf0 | |||
| df6e8be6c4 | |||
| 2986328ed0 | |||
| 493d9dc7d8 | |||
| b037af820f | |||
| 9ea9dcfe92 | |||
| a83b5a6e35 | |||
| 8fcc851f8c | |||
| 76ee5be606 | |||
| 342ea0b767 | |||
| 8acf60a1ef | |||
| a5455feff4 | |||
| 143c0e022c | |||
| 01828b8635 | |||
| 78a78ab22a | |||
| e1eef33cf2 | |||
| f35ab2638f | |||
| 213ed54266 | |||
| 838fa4ff7b | |||
| cde6f1ee9b | |||
| 55be9da582 | |||
| aae978535b | |||
| ef91522813 | |||
| f887b50471 | |||
| 9a2102e96c | |||
| 7285bc7657 | |||
| 4c5766b7af | |||
| 57b70c0490 | |||
| 0b68ba5874 | |||
| 012b6d09f7 | |||
| 7c3b3431fe | |||
| d88036758b | |||
| 83b33771f4 | |||
| 50de2a7cc6 | |||
| 647d03fcca | |||
| f4d7457a57 | |||
| 8554f1e228 | |||
| 36c6a3b41b | |||
| 3debc27227 | |||
| e7c5e465d1 | |||
| e1ee0500ea | |||
| 41d94e2f40 | |||
| 82511322a2 | |||
| 4987f8b80c | |||
| a090ecb8ac | |||
| e6dd438a84 | |||
| 970786b755 | |||
| 4a2556653a | |||
| 7169113067 | |||
| 7c007e54a3 | |||
| a994ef5f67 | |||
| 925bdfa773 | |||
| 9b13aeafce | |||
| ee88c586cc | |||
| 9359399d07 | |||
| fe83cda881 | |||
| f0616a3052 | |||
| 46142aa670 | |||
| 1fae6a61d7 | |||
| 51891c632d | |||
| 29d81d5e8f | |||
| 8d93d5a780 | |||
| 67dcd24410 | |||
| 9b6446c95e | |||
| 9e593085c1 | |||
| 21a63b98ce | |||
| 830784463c | |||
| 102feb0e57 | |||
| 5572f90319 | |||
| f16b7d694b | |||
| ba8765aed0 | |||
| 11d120e387 | |||
| f4768df8ee | |||
| a5a3d039c6 | |||
| 6a1c0960e1 | |||
| 7964a6a7ce | |||
| 41212de95d | |||
| f0aa679b6d | |||
| 541dacd293 | |||
| 393eb6aecb | |||
| ece1dac81a | |||
| a525db7088 | |||
| 20000ac670 | |||
| 1f0f81c60d | |||
| 8a938c889b | |||
| 5601a33c17 | |||
| 1c8f0076ad | |||
| be3869ba2b | |||
| 2d57f742e2 | |||
| 066fae0b74 | |||
| 31d2527cfe | |||
| 6182ac4e23 | |||
| 537df93b17 | |||
| 53281eef3d | |||
| efcf466c7d | |||
| bf81b7a78b | |||
| 1ea38e6b20 | |||
| 81ec54d6e4 | |||
| 0122c4f9ce | |||
| 4adb409fc5 | |||
| b05565026a | |||
| 8a5bb7be35 | |||
| d3aa3dbf41 | |||
| dbf233d30b | |||
| 0392d9e900 | |||
| 06fe1f5b5a | |||
| 9d999c4067 | |||
| 35d4ea7cce | |||
| 5cfffc61a4 | |||
| 164a15cfd0 | |||
| 97303eebe4 | |||
| e73f5981c9 | |||
| a030d7181c | |||
| ec9474e96f | |||
| 5271d22174 | |||
| 581dbec117 | |||
| 9c19d2d81c | |||
| ee0a168414 | |||
| e1bb294fdb | |||
| f9d9f794de | |||
| 4f6f68b70f | |||
| aa73b78e84 | |||
| c9d7c20871 | |||
| d949ee0239 | |||
| f917eb19f1 | |||
| df2271ee9a | |||
| 6d499032fa |
@@ -306,7 +306,7 @@ content_security_policy = false
|
||||
# Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
|
||||
# $NONCE in the template includes a random nonce.
|
||||
# $ROOT_PATH is server.root_url without the protocol.
|
||||
content_security_policy_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
|
||||
content_security_policy_template = """scripts-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
|
||||
|
||||
# Controls if old angular plugins are supported or not. This will be disabled by default in future release
|
||||
angular_support_enabled = true
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default: false # disable the default status that measures entire project
|
||||
pkg: # declare a new status context "pkg"
|
||||
paths:
|
||||
- pkg/* # only include coverage in "pkg/" folder
|
||||
informational: true # Always pass check
|
||||
patch: off # disable the commit only checks
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41E Bug"
|
||||
about: File a bug/issue
|
||||
title: "[BUG] <title>"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Note: Please search to see if an issue already exists for the bug you encountered.
|
||||
-->
|
||||
|
||||
### Environment:
|
||||
<!-- linux? windows? or Mac?
|
||||
Example:
|
||||
- OS: Ubuntu 20.04 -->
|
||||
|
||||
### Physical Memory Capacity:
|
||||
<!-- 8G or above is better -->
|
||||
|
||||
### Docker Image:
|
||||
<!-- Did you pull the docker image before execute docker images -->
|
||||
|
||||
### Code Version:
|
||||
<!-- Did you pull code from github? Make sure the code is up to date-->
|
||||
|
||||
### Component installation:
|
||||
<!-- Has etcd, mysql, mongodb, redis or Kafka been installed on the server before Open-IM-Server deployment-->
|
||||
|
||||
|
||||
### Log File:
|
||||
<!-- view log file(logs/openIM.log) content. -->
|
||||
|
||||
|
||||
### screenshot:
|
||||
<!---->
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
name: Deployment issues
|
||||
about: Deployment issues
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
If you are deploying OpenIM for the first time
|
||||
|
||||
|
||||
|
||||
```
|
||||
git clone https://github.com/OpenIMSDK/Open-IM-Server.git --recursive
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
cd Open-IM-Server/script ; chmod +x *.sh ; ./env_check.sh
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
cd .. ; docker-compose up -d
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
cd script ; ./docker_check_service.sh
|
||||
```
|
||||
|
||||
screenshot here
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
name: 'update '
|
||||
about: update docker image
|
||||
title: update docker image
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
cd Open-IM-Server ; docker-compose down
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
git pull
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
docker-compose pull
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
chmod +x script/*.sh ; docker-compose up -d
|
||||
```
|
||||
|
||||
screenshot here
|
||||
|
||||
```
|
||||
cd script ; ./docker_check_service.sh
|
||||
```
|
||||
|
||||
screenshot here
|
||||
@@ -0,0 +1,29 @@
|
||||
# Refer to Kubernetes for size/* Settings
|
||||
# https://github.com/Kubernetes/Kubernetes
|
||||
XS:
|
||||
name: size/XS
|
||||
lines: 0
|
||||
color: 3CBF00
|
||||
S:
|
||||
name: size/S
|
||||
lines: 10
|
||||
color: 5D9801
|
||||
M:
|
||||
name: size/M
|
||||
lines: 30
|
||||
color: 7F7203
|
||||
L:
|
||||
name: size/L
|
||||
lines: 100
|
||||
color: A14C05
|
||||
XL:
|
||||
name: size/XL
|
||||
lines: 500
|
||||
color: C32607
|
||||
XXL:
|
||||
name: size/XXL
|
||||
lines: 1000
|
||||
color: E50009
|
||||
comment: |
|
||||
# Whoa! Easy there, Partner!
|
||||
This PR is too big. Please break it up into smaller PRs.
|
||||
@@ -0,0 +1,80 @@
|
||||
# https://github.com/BetaHuhn/repo-file-sync-action
|
||||
# Synchronization for the.github repository
|
||||
OpenIMSDK/.github:
|
||||
- source: LICENSE
|
||||
dest: LICENSE
|
||||
- source: scripts/LICENSE/
|
||||
dest: scripts/LICENSE/
|
||||
replace: false
|
||||
|
||||
OpenIMSDK/community:
|
||||
- source: LICENSE
|
||||
dest: LICENSE
|
||||
- source: scripts/LICENSE/
|
||||
dest: scripts/LICENSE/
|
||||
replace: false
|
||||
- source: .github/workflows/
|
||||
dest: .github/workflows/
|
||||
|
||||
OpenIMSDK/openim-sdk-core:
|
||||
- source: LICENSE
|
||||
dest: LICENSE
|
||||
- source: scripts/LICENSE/
|
||||
dest: scripts/LICENSE/
|
||||
replace: false
|
||||
- source: .github/workflows/issue-robot.yml
|
||||
dest: .github/workflows/issue-robot.yml
|
||||
replace: false
|
||||
- source: .github/workflows/stale.yml
|
||||
dest: .github/workflows/stale.yml
|
||||
replace: false
|
||||
|
||||
OpenIMSDK/OpenIM-Docs:
|
||||
- source: .github/workflows/
|
||||
dest: .github/workflows/
|
||||
exclude: |
|
||||
e2e-test.yml
|
||||
sync.yml
|
||||
- source: scripts/githooks/
|
||||
dest: scripts/githooks/
|
||||
replace: true
|
||||
|
||||
OpenIMSDK/OpenKF:
|
||||
- source: LICENSE
|
||||
dest: LICENSE
|
||||
- source: scripts/LICENSE/
|
||||
dest: scripts/LICENSE/
|
||||
replace: false
|
||||
- source: .github/workflows/issue-robot.yml
|
||||
dest: .github/workflows/issue-robot.yml
|
||||
replace: false
|
||||
- source: .github/workflows/stale.yml
|
||||
dest: .github/workflows/stale.yml
|
||||
replace: false
|
||||
|
||||
group:
|
||||
# first group:common to all warehouses
|
||||
# TODO: add the required warehouse here
|
||||
- repos: |
|
||||
OpenIMSDK/OpenKF@main
|
||||
OpenIMSDK/openim-miniprogram-demo@main
|
||||
OpenIMSDK/openim-sdk-cpp@main
|
||||
files:
|
||||
- source: LICENSE
|
||||
dest: LICENSE
|
||||
replace: false
|
||||
- source: .github/workflows/issue-robot.yml
|
||||
dest: .github/workflows/issue-robot.yml
|
||||
replace: false
|
||||
- source: .github/workflows/stale.yml
|
||||
dest: .github/workflows/stale.yml
|
||||
replace: false
|
||||
- source: .github/workflows/project-progress.yml
|
||||
dest: .github/workflows/project-progress.yml
|
||||
replace: false
|
||||
- source: .github/workflows/help-comment-issue.yml
|
||||
dest: .github/workflows/help-comment-issue.yml
|
||||
replace: false
|
||||
- source: ./scripts/githooks/
|
||||
dest: ./scripts/githooks/
|
||||
replace: true
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Invite users to join our group
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
jobs:
|
||||
issue_comment:
|
||||
name: Invite users to join our group
|
||||
if: ${{ github.event.comment.body == '/invite' || github.event.comment.body == '/close' || github.event.comment.body == '/comment' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
|
||||
- name: Invite user to join our group
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
We value close connections with our users, developers, and contributors here at Open-IM-Server. With a large community and maintainer team, we're always here to help and support you. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us.
|
||||
|
||||
Our most recommended way to get in touch is through [Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg). Even if you're in China, Slack is usually not blocked by firewalls, making it an easy way to connect with us. Our Slack community is the ideal place to discuss and share ideas and suggestions with other users and developers of Open-IM-Server. You can ask technical questions, seek help, or share your experiences with other users of Open-IM-Server.
|
||||
|
||||
In addition to Slack, we also offer the following ways to get in touch:
|
||||
|
||||
+ <a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg" target="_blank"><img src="https://img.shields.io/badge/Slack-OpenIM%2B-blueviolet?logo=slack&logoColor=white"></a> We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [👀 Open-IM-Server slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel.
|
||||
+ <a href="https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com" target="_blank"><img src="https://img.shields.io/badge/gmail-%40OOpenIMSDKCore?style=social&logo=gmail"></a> Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email.
|
||||
+ <a href="https://doc.rentsoft.cn/" target="_blank"><img src="https://img.shields.io/badge/%E5%8D%9A%E5%AE%A2-%40OpenIMSDKCore-blue?style=social&logo=Octopus%20Deploy"></a> Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with Open-IM-Server projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information.
|
||||
+ <a href="https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg" target="_blank"><img src="https://img.shields.io/badge/%E5%BE%AE%E4%BF%A1-OpenIMSDKCore-brightgreen?logo=wechat&style=flat-square"></a> Add [Wechat](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible.
|
||||
|
||||
- name: Close Issue
|
||||
uses: peter-evans/close-issue@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
comment: 🤖 Auto-closing issue, if you still need help please reopen the issue or ask for help in the community above
|
||||
labels: |
|
||||
triage/accepted
|
||||
@@ -0,0 +1,45 @@
|
||||
# name: Check-Coverage
|
||||
|
||||
# on:
|
||||
# workflow_dispatch:
|
||||
# push:
|
||||
# branches: [ "main" ]
|
||||
# paths-ignore:
|
||||
# - "docs/**"
|
||||
# - "**/*.md"
|
||||
# - "**/*.yaml"
|
||||
# - "CONTRIBUTORS"
|
||||
# - "CHANGELOG/**"
|
||||
# pull_request:
|
||||
# branches: [ "*" ]
|
||||
# paths-ignore:
|
||||
# - "docs/**"
|
||||
# - "**/*.md"
|
||||
# - "**/*.yaml"
|
||||
# - "CONTRIBUTORS"
|
||||
# - "CHANGELOG/**"
|
||||
# env:
|
||||
# # Common versions
|
||||
# GO_VERSION: "1.20"
|
||||
|
||||
# jobs:
|
||||
# coverage:
|
||||
# runs-on: ubuntu-20.04
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v3
|
||||
|
||||
# - name: Setup Golang with cache
|
||||
# uses: magnetikonline/action-golang-cache@v3
|
||||
# with:
|
||||
# go-version: ${{ env.GO_VERSION }}
|
||||
# token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
|
||||
# - name: Install Dependencies
|
||||
# run: sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev
|
||||
|
||||
# - name: Run Cover
|
||||
# run: make cover
|
||||
|
||||
# - name: Upload Coverage to Codecov
|
||||
# uses: codecov/codecov-action@v3
|
||||
@@ -16,9 +16,9 @@ on:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '23 2 * * 2'
|
||||
branches: "*"
|
||||
# schedule:
|
||||
# - cron: '23 2 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# name: Run gosec
|
||||
|
||||
# # gosec is a source code security audit tool for the Go language. It performs a static
|
||||
# # analysis of the Go code, looking for potential security problems. The main functions of gosec are:
|
||||
# # 1. Find common security vulnerabilities, such as SQL injection, command injection, and cross-site scripting (XSS).
|
||||
# # 2. Audit codes according to common security standards and find non-standard codes.
|
||||
# # 3. Assist the Go language engineer to write safe and reliable code.
|
||||
|
||||
# on:
|
||||
# push:
|
||||
# branches: "*"
|
||||
# pull_request:
|
||||
# branches: "*"
|
||||
# paths-ignore:
|
||||
# - '*.md'
|
||||
# - '*.yml'
|
||||
# - '.github'
|
||||
|
||||
# jobs:
|
||||
# golang-security-action:
|
||||
# runs-on: ubuntu-latest
|
||||
# env:
|
||||
# GO111MODULE: on
|
||||
# steps:
|
||||
# - name: Check out code
|
||||
# uses: actions/checkout@v3
|
||||
# - name: Run Gosec Security Scanner
|
||||
# uses: securego/gosec@master
|
||||
# with:
|
||||
# args: ./...
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Good frist issue add comment
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
jobs:
|
||||
add-comment:
|
||||
if: github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Add comment
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
body: |
|
||||
This issue is available for anyone to work on. **Make sure to reference this issue in your pull request.** :sparkles: Thank you for your contribution! :sparkles:
|
||||
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers.
|
||||
If you wish to accept this assignment, please leave a comment in the comments section: `/accept`.🎯
|
||||
@@ -0,0 +1,17 @@
|
||||
name: 'issue translator'
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: usthe/issues-translate-action@v2.7
|
||||
with:
|
||||
# it is not necessary to decide whether you need to modify the issue header content
|
||||
IS_MODIFY_TITLE: true
|
||||
BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
# Required, input your bot github token
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Github Rebot for Link check error
|
||||
|
||||
# Every Monday at 12:30 p.m
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 12 * * 1'
|
||||
|
||||
jobs:
|
||||
linkChecker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Link Checker
|
||||
id: lychee
|
||||
uses: lycheeverse/lychee-action@v1.7.0
|
||||
with:
|
||||
# For parameter description, see https://github.com/lycheeverse/lychee#commandline-parameters
|
||||
# Actions Link address -> https://github.com/lycheeverse/lychee-action
|
||||
# -E, --exclude-all-private Exclude all private IPs from checking.
|
||||
# -i, --insecure Proceed for server connections considered insecure (invalid TLS)
|
||||
# -n, --no-progress Do not show progress bar.
|
||||
# -t, --timeout <timeout> Website timeout in seconds from connect to response finished [default:20]
|
||||
# --max-concurrency <max-concurrency> Maximum number of concurrent network requests [default: 128]
|
||||
# -a --accept <accept> Comma-separated list of accepted status codes for valid links
|
||||
# docs/.vitepress/dist the site directory to check
|
||||
# ./*.md all markdown files in the root directory
|
||||
args: --verbose -E -i --no-progress --exclude-path './CHANGELOG' './**/*.md'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GH_PAT}}
|
||||
|
||||
- name: Create Issue From File
|
||||
if: env.lychee_exit_code != 0
|
||||
uses: peter-evans/create-issue-from-file@v4
|
||||
with:
|
||||
title: Bug reports for links in OpenIM docs
|
||||
content-filepath: ./lychee/out.md
|
||||
labels: kind/documentation, triage/unresolved, report
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,38 @@
|
||||
name: 'OpenCommit Action'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
opencommit:
|
||||
timeout-minutes: 10
|
||||
name: OpenCommit
|
||||
runs-on: ubuntu-latest
|
||||
permissions: write-all
|
||||
steps:
|
||||
- name: Setup Node.js Environment
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: di-sukharev/opencommit@github-action-v1.0.4
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
env:
|
||||
# set openAI api key in repo actions secrets,
|
||||
# for openAI keys go to: https://platform.openai.com/account/api-keys
|
||||
# for repo secret go to: https://github.com/kuebcub/settings/secrets/actions
|
||||
OCO_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
|
||||
# customization
|
||||
OCO_OPENAI_MAX_TOKENS: 500
|
||||
OCO_OPENAI_BASE_PATH: ''
|
||||
OCO_DESCRIPTION: false
|
||||
OCO_EMOJI: false
|
||||
OCO_MODEL: gpt-3.5-turbo
|
||||
OCO_LANGUAGE: en
|
||||
@@ -0,0 +1,22 @@
|
||||
# GitHub recommends pinning actions to a commit SHA.
|
||||
# To get a newer version, you will need to update the SHA.
|
||||
# You can also reference a tag or branch, but the action may change without warning.
|
||||
|
||||
name: Move assigned card
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- assigned
|
||||
pull_request:
|
||||
types:
|
||||
- assigned
|
||||
|
||||
jobs:
|
||||
move-assigned-card:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@v0.8.3
|
||||
with:
|
||||
project: OpenIM 2023 Sprint 🔥
|
||||
column: In Progress
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,34 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
days-before-stale: 60
|
||||
days-before-close: 7
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
stale-pr-message: 'This issue is stale because it has been open 60 days with no activity.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity. You can reopen it if you want.'
|
||||
stale-pr-label: lifecycle/stale
|
||||
stale-issue-label: lifecycle/stale
|
||||
exempt-issue-labels: 'openim'
|
||||
exempt-pr-labels: 'openim'
|
||||
exempt-draft-pr: true
|
||||
@@ -0,0 +1,43 @@
|
||||
# Copyright © 2023 KubeCub open source community. All rights reserved.
|
||||
# Licensed under the MIT License (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
# https://github.com/BetaHuhn/repo-file-sync-action
|
||||
name: Synchronize kubecub public code to other repositories
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run GitHub File Sync
|
||||
uses: BetaHuhn/repo-file-sync-action@latest
|
||||
with:
|
||||
GH_INSTALLATION_TOKEN: "${{ secrets.BOT_GITHUB_TOKEN }}"
|
||||
CONFIG_PATH: .github/sync.yml
|
||||
GH_PAT: "${{ secrets.BOT_GITHUB_TOKEN }}"
|
||||
ORIGINAL_MESSAGE: true
|
||||
SKIP_PR: true
|
||||
COMMIT_EACH_FILE: false
|
||||
COMMIT_BODY: "🤖 kubbot to synchronize the warehouse"
|
||||
GIT_EMAIL: "3293172751ysy@gmail.com"
|
||||
GIT_USERNAME: "kubbot"
|
||||
PR_BODY: 👌 kubecub provides automated community services
|
||||
REVIEWERS: |
|
||||
kubbot
|
||||
cubxxw
|
||||
PR_LABELS: |
|
||||
file-sync
|
||||
automerge
|
||||
ASSIGNEES: |
|
||||
kubbot
|
||||
+377
-4
@@ -1,20 +1,393 @@
|
||||
bin
|
||||
# Copyright © 2023 OpenIMSDK.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ==============================================================================
|
||||
# For the entire design of.gitignore, ignore git commits and ignore files
|
||||
#===============================================================================
|
||||
#
|
||||
|
||||
### OpenIM developer supplement ###
|
||||
logs
|
||||
.devcontainer
|
||||
components
|
||||
out-test
|
||||
.github
|
||||
.idea
|
||||
.exe
|
||||
|
||||
### Makefile ###
|
||||
tmp/
|
||||
bin/
|
||||
output/
|
||||
_output/
|
||||
|
||||
### OpenIM deploy ###
|
||||
deploy/open_im_demo
|
||||
deploy/open_im_api
|
||||
deploy/open_im_msg_gateway
|
||||
deploy/open_im_msg_transfer
|
||||
deploy/open_im_push
|
||||
deploy/open_im_timer_task
|
||||
deploy/open_im_rpc_user
|
||||
deploy/open_im_rpc_friend
|
||||
deploy/open_im_rpc_group
|
||||
deploy/open_im_rpc_msg
|
||||
deploy/open_im_rpc_auth
|
||||
deploy/Open-IM-SDK-Core
|
||||
|
||||
# files used by the developer
|
||||
.idea.md
|
||||
.todo.md
|
||||
.note.md
|
||||
|
||||
# ==============================================================================
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=go,git,vim,tags,test,emacs,backup,jetbrains
|
||||
|
||||
### Backup ###
|
||||
*.bak
|
||||
*.gho
|
||||
*.ori
|
||||
*.orig
|
||||
*.tmp
|
||||
|
||||
### Emacs ###
|
||||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
dist/
|
||||
|
||||
# Flycheck
|
||||
flycheck_*.el
|
||||
|
||||
# server auth directory
|
||||
/server/
|
||||
|
||||
# projectiles files
|
||||
.projectile
|
||||
|
||||
# directory configuration
|
||||
.dir-locals.el
|
||||
|
||||
# network security
|
||||
/network-security.data
|
||||
|
||||
### vscode ###
|
||||
.vscode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim,jetbrains,vscode,git,go,tags,backup,test
|
||||
|
||||
### Git ###
|
||||
# Created by git for backups. To disable backups in Git:
|
||||
# $ git config --global mergetool.keepBackup false
|
||||
|
||||
# Created by git when using merge tools for conflicts
|
||||
*.BACKUP.*
|
||||
*.BASE.*
|
||||
*.LOCAL.*
|
||||
*.REMOTE.*
|
||||
*_BACKUP_*.txt
|
||||
*_BASE_*.txt
|
||||
*_LOCAL_*.txt
|
||||
*_REMOTE_*.txt
|
||||
|
||||
### Go ###
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
### JetBrains ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/
|
||||
.idea
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### JetBrains Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||
.idea/**/sonarlint/
|
||||
|
||||
# SonarQube Plugin
|
||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||
.idea/**/sonarIssues.xml
|
||||
|
||||
# Markdown Navigator plugin
|
||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||
.idea/**/markdown-navigator.xml
|
||||
.idea/**/markdown-navigator-enh.xml
|
||||
.idea/**/markdown-navigator/
|
||||
|
||||
# Cache file creation bug
|
||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||
.idea/$CACHE_FILE$
|
||||
|
||||
# CodeStream plugin
|
||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||
.idea/codestream.xml
|
||||
|
||||
# Azure Toolkit for IntelliJ plugin
|
||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||
.idea/**/azureSettings.xml
|
||||
|
||||
### Tags ###
|
||||
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
|
||||
TAGS
|
||||
.TAGS
|
||||
!TAGS/
|
||||
tags
|
||||
.tags
|
||||
!tags/
|
||||
gtags.files
|
||||
GTAGS
|
||||
GRTAGS
|
||||
GPATH
|
||||
GSYMS
|
||||
cscope.files
|
||||
cscope.out
|
||||
cscope.in.out
|
||||
cscope.po.out
|
||||
|
||||
|
||||
### Test ###
|
||||
### Ignore all files that could be used to test your code and
|
||||
### you wouldn't want to push
|
||||
|
||||
# Reference https://en.wikipedia.org/wiki/Metasyntactic_variable
|
||||
|
||||
# Most common
|
||||
*foo
|
||||
*bar
|
||||
*fubar
|
||||
*foobar
|
||||
*baz
|
||||
|
||||
# Less common
|
||||
*qux
|
||||
*quux
|
||||
*bongo
|
||||
*bazola
|
||||
*ztesch
|
||||
|
||||
# UK, Australia
|
||||
*wibble
|
||||
*wobble
|
||||
*wubble
|
||||
*flob
|
||||
*blep
|
||||
*blah
|
||||
*boop
|
||||
*beep
|
||||
|
||||
# Japanese
|
||||
*hoge
|
||||
*piyo
|
||||
*fuga
|
||||
*hogera
|
||||
*hogehoge
|
||||
|
||||
# Portugal, Spain
|
||||
*fulano
|
||||
*sicrano
|
||||
*beltrano
|
||||
*mengano
|
||||
*perengano
|
||||
*zutano
|
||||
|
||||
# France, Italy, the Netherlands
|
||||
*toto
|
||||
*titi
|
||||
*tata
|
||||
*tutu
|
||||
*pipppo
|
||||
*pluto
|
||||
*paperino
|
||||
*aap
|
||||
*noot
|
||||
*mies
|
||||
|
||||
# Other names that would make sense
|
||||
*tests
|
||||
*testsdir
|
||||
*testsfile
|
||||
*testsfiles
|
||||
*test
|
||||
*testdir
|
||||
*testfile
|
||||
*testfiles
|
||||
*testing
|
||||
*testingdir
|
||||
*testingfile
|
||||
*testingfiles
|
||||
*temp
|
||||
*tempdir
|
||||
*tempfile
|
||||
*tempfiles
|
||||
*tmp
|
||||
*tmpdir
|
||||
*tmpfile
|
||||
*tmpfiles
|
||||
*lol
|
||||
|
||||
### Vim ###
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
# Auto-generated tag files
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains
|
||||
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 1m
|
||||
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
|
||||
# include test files or not, default is true
|
||||
tests: true
|
||||
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
#modules-download-mode: release|readonly|vendor
|
||||
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false (default) - golangci-lint acquires file lock on start.
|
||||
allow-parallel-runners: true
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
dogsled:
|
||||
# checks assignments with too many blank identifiers; default is 2
|
||||
max-blank-identifiers: 2
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
threshold: 100
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
#exclude: errcheck.txt
|
||||
exhaustive:
|
||||
# indicates that switch statements are to be considered exhaustive if a
|
||||
# 'default' case is present, even if all enum members aren't listed in the
|
||||
# switch
|
||||
default-signifies-exhaustive: false
|
||||
funlen:
|
||||
lines: 150
|
||||
statements: 40
|
||||
gocognit:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 30
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 5
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 5
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 30
|
||||
godot:
|
||||
# check all top-level comments, not only declarations
|
||||
check-all: false
|
||||
godox:
|
||||
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
|
||||
# might be left in the code accidentally and should be resolved before merging
|
||||
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
|
||||
- OPTIMIZE # marks code that should be optimized before merging
|
||||
- HACK # marks hack-arounds that should be removed before merging
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/org/project
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.9
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
|
||||
checks: argument,case,condition,operation,return,assign
|
||||
gomodguard:
|
||||
allowed:
|
||||
modules: # List of allowed modules
|
||||
# - gopkg.in/yaml.v2
|
||||
domains: # List of allowed module domains
|
||||
# - golang.org
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
|
||||
# enable or disable analyzers by name
|
||||
enable:
|
||||
- atomicalign
|
||||
enable-all: false
|
||||
disable:
|
||||
- shadow
|
||||
disable-all: false
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
include-go-root: false
|
||||
packages:
|
||||
packages-with-error-message:
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 120
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||
locale: US
|
||||
ignore-words:
|
||||
- someword
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
prealloc:
|
||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||
# For most programs usage of prealloc will be a premature optimization.
|
||||
|
||||
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||
# True by default.
|
||||
simple: true
|
||||
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||
for-loops: false # Report preallocation suggestions on for loops, false by default
|
||||
nolintlint:
|
||||
# Enable to ensure that nolint directives are all used. Default is true.
|
||||
allow-unused: false
|
||||
# Disable to ensure that nolint directives don't have a leading space. Default is true.
|
||||
allow-leading-space: true
|
||||
# Exclude following linters from requiring an explanation. Default is [].
|
||||
allow-no-explanation: []
|
||||
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
|
||||
require-explanation: true
|
||||
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
|
||||
require-specific: true
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
wsl:
|
||||
# If true append is only allowed to be cuddled if appending value is
|
||||
# matching variables, fields or types on line above. Default is true.
|
||||
strict-append: true
|
||||
# Allow calls and assignments to be cuddled as long as the lines have any
|
||||
# matching variables, fields or types. Default is true.
|
||||
allow-assign-and-call: true
|
||||
# Allow multiline assignments to be cuddled. Default is true.
|
||||
allow-multiline-assign: true
|
||||
# Allow declarations (var) to be cuddled.
|
||||
allow-cuddle-declarations: false
|
||||
# Allow trailing comments in ending of blocks
|
||||
allow-trailing-comment: false
|
||||
# Force newlines in end of case at this limit (0 = never).
|
||||
force-case-trailing-whitespace: 0
|
||||
# Force cuddling of err checks with err var assignment
|
||||
force-err-cuddling: false
|
||||
# Allow leading comments to be separated with empty liens
|
||||
allow-separated-leading-comment: false
|
||||
|
||||
linters:
|
||||
# please, do not use `enable-all`: it's deprecated and will be removed soon.
|
||||
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
|
||||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- errcheck
|
||||
- funlen
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- interfacer
|
||||
- lll
|
||||
- misspell
|
||||
- nakedret
|
||||
- nolintlint
|
||||
- rowserrcheck
|
||||
- scopelint
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
- asciicheck
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- maligned
|
||||
- nestif
|
||||
- prealloc
|
||||
- gomodguard
|
||||
# don't enable:
|
||||
#- goerr113
|
||||
#- wsl
|
||||
#- testpackage
|
||||
#- exhaustive (TODO: enable after next release; current release at time of writing is v1.27)
|
||||
#- gochecknoglobals
|
||||
#- gomnd
|
||||
|
||||
issues:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: true
|
||||
|
||||
# The default value is false. If set to true exclude and exclude-rules
|
||||
# regular expressions become case sensitive.
|
||||
exclude-case-sensitive: false
|
||||
|
||||
# The list of ids of default excludes to include or disable. By default it's empty.
|
||||
include:
|
||||
- EXC0002 # disable excluding of issues about comments from golint
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
|
||||
# Show only new issues created after git revision `REV`
|
||||
# new-from-rev: REV
|
||||
|
||||
# Show only new issues created in git patch with set file path.
|
||||
#new-from-patch: path/to/patch/file
|
||||
|
||||
severity:
|
||||
# Default value is empty string.
|
||||
# Set the default severity for issues. If severity rules are defined and the issues
|
||||
# do not match or no severity is provided to the rule this will be the default
|
||||
# severity applied. Severities should match the supported severity names of the
|
||||
# selected out format.
|
||||
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
|
||||
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
||||
default-severity: error
|
||||
|
||||
# The default value is false.
|
||||
# If set to true severity-rules regular expressions become case sensitive.
|
||||
case-sensitive: false
|
||||
|
||||
# Default value is empty list.
|
||||
# When a list of severity rules are provided, severity information will be added to lint
|
||||
# issues. Severity rules have the same filtering capability as exclude rules except you
|
||||
# are allowed to specify one matcher per severity rule.
|
||||
# Only affects out formats that support setting severity information.
|
||||
rules:
|
||||
- linters:
|
||||
- dupl
|
||||
severity: info
|
||||
Generated
+9
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
+14
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="grafana" uuid="95aae14a-3593-4ff7-ab49-5e4316cbecd1">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:C:\Users\Administrator\Desktop\Open-IM-Server\docker-compose_cfg\grafana.db</jdbc-url>
|
||||
<driver-properties>
|
||||
<property name="enable_load_extension" value="true" />
|
||||
</driver-properties>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Open-IM-Server.iml" filepath="$PROJECT_DIR$/.idea/Open-IM-Server.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,40 @@
|
||||
{{ range .Versions }}
|
||||
<a name="{{ .Tag.Name }}"></a>
|
||||
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }}
|
||||
|
||||
> {{ datetime "2006-01-02" .Tag.Date }}
|
||||
|
||||
{{ range .CommitGroups -}}
|
||||
### {{ .Title }}
|
||||
|
||||
{{ range .Commits -}}
|
||||
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .RevertCommits -}}
|
||||
### Reverts
|
||||
|
||||
{{ range .RevertCommits -}}
|
||||
* {{ .Revert.Header }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .MergeCommits -}}
|
||||
### Pull Requests
|
||||
|
||||
{{ range .MergeCommits -}}
|
||||
* {{ .Header }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .NoteGroups -}}
|
||||
{{ range .NoteGroups -}}
|
||||
### {{ .Title }}
|
||||
|
||||
{{ range .Notes }}
|
||||
{{ .Body }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
@@ -0,0 +1,28 @@
|
||||
style: github
|
||||
template: CHANGELOG.tpl.md
|
||||
info:
|
||||
title: CHANGELOG
|
||||
repository_url: https://github.com/OpenIMSDK/Open-IM-Server
|
||||
options:
|
||||
commits:
|
||||
# filters:
|
||||
# Type:
|
||||
# - feat
|
||||
# - fix
|
||||
# - perf
|
||||
# - refactor
|
||||
commit_groups:
|
||||
# title_maps:
|
||||
# feat: Features
|
||||
# fix: Bug Fixes
|
||||
# perf: Performance Improvements
|
||||
# refactor: Code Refactoring
|
||||
header:
|
||||
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
|
||||
pattern_maps:
|
||||
- Type
|
||||
- Scope
|
||||
- Subject
|
||||
notes:
|
||||
keywords:
|
||||
- BREAKING CHANGE
|
||||
@@ -0,0 +1,228 @@
|
||||
|
||||
<a name="v2.3.3"></a>
|
||||
## [v2.3.3](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.2...v2.3.3)
|
||||
|
||||
> 2022-09-18
|
||||
|
||||
|
||||
<a name="v2.3.2"></a>
|
||||
## [v2.3.2](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc2...v2.3.2)
|
||||
|
||||
> 2022-09-09
|
||||
|
||||
### GetSelfUserInfo
|
||||
|
||||
* Handle the case where the user does not exist
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* Merge pull request [#267](https://github.com/OpenIMSDK/Open-IM-Server/issues/267) from ouyangshi/del
|
||||
* Merge pull request [#265](https://github.com/OpenIMSDK/Open-IM-Server/issues/265) from ouyangshi/del
|
||||
* Merge pull request [#252](https://github.com/OpenIMSDK/Open-IM-Server/issues/252) from x-shadow-man/config-perf
|
||||
* Merge pull request [#263](https://github.com/OpenIMSDK/Open-IM-Server/issues/263) from ouyangshi/main
|
||||
* Merge pull request [#258](https://github.com/OpenIMSDK/Open-IM-Server/issues/258) from ouyangshi/main
|
||||
* Merge pull request [#261](https://github.com/OpenIMSDK/Open-IM-Server/issues/261) from ouyangshi/v2.3.0release
|
||||
|
||||
|
||||
<a name="v2.3.0-rc2"></a>
|
||||
## [v2.3.0-rc2](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc1...v2.3.0-rc2)
|
||||
|
||||
> 2022-07-29
|
||||
|
||||
|
||||
<a name="v2.3.0-rc1"></a>
|
||||
## [v2.3.0-rc1](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.3.0-rc0...v2.3.0-rc1)
|
||||
|
||||
> 2022-07-25
|
||||
|
||||
|
||||
<a name="v2.3.0-rc0"></a>
|
||||
## [v2.3.0-rc0](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.2.0...v2.3.0-rc0)
|
||||
|
||||
> 2022-07-15
|
||||
|
||||
|
||||
<a name="v2.2.0"></a>
|
||||
## [v2.2.0](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.1.0...v2.2.0)
|
||||
|
||||
> 2022-07-01
|
||||
|
||||
|
||||
<a name="v2.1.0"></a>
|
||||
## [v2.1.0](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.10...v2.1.0)
|
||||
|
||||
> 2022-06-17
|
||||
|
||||
|
||||
<a name="v2.0.10"></a>
|
||||
## [v2.0.10](https://github.com/OpenIMSDK/Open-IM-Server/compare/list...v2.0.10)
|
||||
|
||||
> 2022-05-13
|
||||
|
||||
|
||||
<a name="list"></a>
|
||||
## [list](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.9...list)
|
||||
|
||||
> 2022-04-29
|
||||
|
||||
|
||||
<a name="v2.0.9"></a>
|
||||
## [v2.0.9](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.7...v2.0.9)
|
||||
|
||||
> 2022-04-29
|
||||
|
||||
### Reverts
|
||||
|
||||
* update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206))
|
||||
|
||||
|
||||
<a name="v2.0.7"></a>
|
||||
## [v2.0.7](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.6...v2.0.7)
|
||||
|
||||
> 2022-04-08
|
||||
|
||||
|
||||
<a name="v2.0.6"></a>
|
||||
## [v2.0.6](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.5...v2.0.6)
|
||||
|
||||
> 2022-04-01
|
||||
|
||||
### Fix
|
||||
|
||||
* json tag value of UserIDResult.UserID ([#178](https://github.com/OpenIMSDK/Open-IM-Server/issues/178))
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* Merge pull request [#173](https://github.com/OpenIMSDK/Open-IM-Server/issues/173) from OpenIMSDK/tuoyun
|
||||
|
||||
|
||||
<a name="v2.0.5"></a>
|
||||
## [v2.0.5](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.04...v2.0.5)
|
||||
|
||||
> 2022-03-24
|
||||
|
||||
|
||||
<a name="v2.04"></a>
|
||||
## [v2.04](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.3...v2.04)
|
||||
|
||||
> 2022-03-18
|
||||
|
||||
|
||||
<a name="v2.0.3"></a>
|
||||
## [v2.0.3](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.2...v2.0.3)
|
||||
|
||||
> 2022-03-11
|
||||
|
||||
|
||||
<a name="v2.0.2"></a>
|
||||
## [v2.0.2](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.1...v2.0.2)
|
||||
|
||||
> 2022-03-04
|
||||
|
||||
### Version
|
||||
|
||||
* "3"
|
||||
* "2"
|
||||
|
||||
|
||||
<a name="v2.0.1"></a>
|
||||
## [v2.0.1](https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.0.0...v2.0.1)
|
||||
|
||||
> 2022-02-25
|
||||
|
||||
### DbMysqlDatabaseName
|
||||
|
||||
* openIM_v2
|
||||
|
||||
|
||||
<a name="v2.0.0"></a>
|
||||
## [v2.0.0](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.7...v2.0.0)
|
||||
|
||||
> 2022-02-23
|
||||
|
||||
### Pb
|
||||
|
||||
* open_im_sdk.OfflinePushInfo
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* Merge pull request [#131](https://github.com/OpenIMSDK/Open-IM-Server/issues/131) from OpenIMSDK/cms-dev
|
||||
|
||||
|
||||
<a name="v1.0.7"></a>
|
||||
## [v1.0.7](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.6...v1.0.7)
|
||||
|
||||
> 2021-12-17
|
||||
|
||||
|
||||
<a name="v1.0.6"></a>
|
||||
## [v1.0.6](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.5...v1.0.6)
|
||||
|
||||
> 2021-12-10
|
||||
|
||||
### Pb
|
||||
|
||||
* open_im_sdk.OfflinePushInfo
|
||||
|
||||
|
||||
<a name="v1.0.5"></a>
|
||||
## [v1.0.5](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.4...v1.0.5)
|
||||
|
||||
> 2021-12-03
|
||||
|
||||
|
||||
<a name="v1.0.4"></a>
|
||||
## [v1.0.4](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.3...v1.0.4)
|
||||
|
||||
> 2021-11-25
|
||||
|
||||
|
||||
<a name="v1.0.3"></a>
|
||||
## [v1.0.3](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.1...v1.0.3)
|
||||
|
||||
> 2021-11-12
|
||||
|
||||
### Feat
|
||||
|
||||
* test utils ([#26](https://github.com/OpenIMSDK/Open-IM-Server/issues/26))
|
||||
|
||||
### Fix
|
||||
|
||||
* Startup error ([#11](https://github.com/OpenIMSDK/Open-IM-Server/issues/11))
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* Merge pull request [#12](https://github.com/OpenIMSDK/Open-IM-Server/issues/12) from njulk/main
|
||||
* Merge pull request [#9](https://github.com/OpenIMSDK/Open-IM-Server/issues/9) from xmcy0011/dev
|
||||
* Merge pull request [#6](https://github.com/OpenIMSDK/Open-IM-Server/issues/6) from Bloomingg/int
|
||||
|
||||
|
||||
<a name="v1.0.1"></a>
|
||||
## [v1.0.1](https://github.com/OpenIMSDK/Open-IM-Server/compare/v1.0.0...v1.0.1)
|
||||
|
||||
> 2021-11-04
|
||||
|
||||
|
||||
<a name="v1.0.0"></a>
|
||||
## v1.0.0
|
||||
|
||||
> 2021-10-28
|
||||
|
||||
### Ci
|
||||
|
||||
* ignore files created by docker-compose ([#19](https://github.com/OpenIMSDK/Open-IM-Server/issues/19))
|
||||
|
||||
### Feat
|
||||
|
||||
* optimise get server ip ([#20](https://github.com/OpenIMSDK/Open-IM-Server/issues/20))
|
||||
|
||||
### Reverts
|
||||
|
||||
* friend modify
|
||||
* update
|
||||
|
||||
### Pull Requests
|
||||
|
||||
* Merge pull request [#7](https://github.com/OpenIMSDK/Open-IM-Server/issues/7) from memory-qianxiao/docker-compose_update
|
||||
* Merge pull request [#4](https://github.com/OpenIMSDK/Open-IM-Server/issues/4) from wujingke/patch-1
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
# Contributing to Open-IM-Server
|
||||
|
||||
So, you want to hack on Open-IM-Server? Yay!
|
||||
|
||||
First of all, thank you for considering contributing to our project! We appreciate your time and effort, and we value any contribution, whether it's reporting a bug, suggesting a new feature, or submitting a pull request.
|
||||
|
||||
This document provides guidelines and best practices to help you contribute effectively.
|
||||
|
||||
## 📇Topics
|
||||
|
||||
- [What we expect of you](#What-we-expect-of-you)
|
||||
- [Code of Conduct](#Code-of-Conduct)
|
||||
- [Getting Started](#Getting-Started)
|
||||
- [Style and Specification](#Style-and-Specification)
|
||||
- [Engage to help anything](#Engage-to-help-anything)
|
||||
- [Release version](#Release-version)
|
||||
- [Contact Us](#Contact-Us)
|
||||
|
||||
## What we expect of you
|
||||
|
||||
We hope that anyone can join Open-IM-Server , even if you are a student, writer, translator
|
||||
|
||||
Please meet the minimum version of the Go language published in [go.mod](./go.mod). If you want to manage the Go language version, we provide tools to install [gvm](https://github.com/moovweb/gvm) in our [Makefile](./Makefile)
|
||||
|
||||
You'd better use Linux OR WSL as the development environment, Linux with [Makefile](./Makefile) can help you quickly build and test Open-IM-Server project.
|
||||
|
||||
If you are familiar with [Makefile](./Makefile) , you can easily see the clever design of the Open-IM-Server Makefile. Storing the necessary tools such as golangci in the `/tools` directory can avoid some tool version issues.
|
||||
|
||||
The [Makefile](./Makefile) is for every developer, even if you don't know how to use the Makefile tool, don't worry, we provide two great commands to get you up to speed with the Makefile architecture, `make help` and `make help-all`, it can reduce problems of the developing environment.
|
||||
|
||||
## Code of ConductCode of Conduct
|
||||
|
||||
#### Code and doc contribution
|
||||
|
||||
Every action to make project Open-IM-Server better is encouraged. On GitHub, every improvement for Open-IM-Server could be via a [PR](https://github.com/Open-IM-Server/pulls) (short for pull request).
|
||||
|
||||
+ If you find a typo, try to fix it!
|
||||
+ If you find a bug, try to fix it!
|
||||
+ If you find some redundant codes, try to remove them!
|
||||
+ If you find some test cases missing, try to add them!
|
||||
+ If you could enhance a feature, please **DO NOT** hesitate!
|
||||
+ If you find code implicit, try to add comments to make it clear!
|
||||
+ If you find code ugly, try to refactor that!
|
||||
+ If you can help to improve documents, it could not be better!
|
||||
+ If you find document incorrect, just do it and fix that!
|
||||
+ ...
|
||||
|
||||
#### Where should I start?
|
||||
|
||||
+ If you are new to the project, don't know how to contribute Open-IM-Server, please check out the [good first issue](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aopen+label%3A"good+first+issue"+sort%3Aupdated-desc) label.
|
||||
+ You should be good at filtering the Open-IM-Server issue tags and finding the ones you like, such as [RFC](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) for big initiatives, features for [feature](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+label%3Afeature) proposals, and [bug](https://github.com/{github/issues?q=is%3Aissue+label%3Abug+) fixes.
|
||||
+ If you are looking for something to work on, check out our [open issues](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
+ If you have an idea for a new feature, please [open an issue](https://github.com/OpenIMSDK/Open-IM-Server/issues/new/choose), and we can discuss it.
|
||||
|
||||
#### Design documents
|
||||
|
||||
For any substantial design, there should be a well-crafted design document. This document is not just a simple record, but also a detailed description and manifestation, which can help team members better understand the design thinking and grasp the design direction. In the process of writing the design document, we can choose to use tools such as `Google Docs` or `Notion`, and even mark RFC in [issues](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) or [discussions](https://github.com/OpenIMSDK/Open-IM-Server/discussions) for better collaboration. Of course, after completing the design document, we should also add it to our [Shared Drive](https://drive.google.com/drive/) and notify the appropriate working group to let everyone know of its existence. Only by doing so can we maximize the effectiveness of the design document and provide strong support for the smooth progress of the project.
|
||||
|
||||
Anybody can access the shared Drive for reading. To get access to comment. Once you've done that, head to the [shared Drive](https://drive.google.com/) and behold all the docs.
|
||||
|
||||
In addition to that, we'd love to invite you to [join our Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) where you can play with your imagination, tell us what you're working on, and get a quick response.
|
||||
|
||||
When documenting a new design, we recommend a 2-step approach:
|
||||
|
||||
1. Use the short-form RFC template to outline your ideas and get early feedback.
|
||||
2. Once you have received sufficient feedback and consensus, you may use the longer-form design doc template to specify and discuss your design in more details.
|
||||
|
||||
In order to contribute a feature to Open-IM-Server you'll need to go through the following steps:
|
||||
|
||||
+ Discuss your idea with the appropriate [working groups](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) on the working group's Slack channel.
|
||||
+ Once there is general agreement that the feature is useful, create a GitHub issue to track the discussion. The issue should include information about the requirements and use cases that it is trying to address.
|
||||
+ Include a discussion of the proposed design and technical details of the implementation in the issue.
|
||||
|
||||
But keep in mind that there is no guarantee of it being accepted and so it is usually best to get agreement on the idea/design before time is spent coding it. However, sometimes seeing the exact code change can help focus discussions, so the choice is up to you.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To propose PR for the Open-IM-Server item, we assume you have registered a GitHub ID. Then you could finish the preparation in the following steps:
|
||||
|
||||
1. Fork the repository(Open-IM-Server)
|
||||
|
||||
2. **CLONE** your own repository to master locally. Use `git clone https://github.com/<your-username>/Open-IM-Server.git` to clone repository to your local machine. Then you can create new branches to finish the change you wish to make.
|
||||
|
||||
3. **Set Remote** upstream to be `https://github.com/OpenIMSDK/Open-IM-Server.git` using the following two commands:
|
||||
|
||||
```bash
|
||||
❯ git remote add upstream https://github.com/OpenIMSDK/Open-IM-Server.git
|
||||
❯ git remote set-url --push upstream no-pushing
|
||||
```
|
||||
|
||||
With this remote setting, you can check your git remote configuration like this:
|
||||
|
||||
```bash
|
||||
❯ git remote -v
|
||||
origin https://github.com/<your-username>/Open-IM-Server.git (fetch)
|
||||
origin https://github.com/<your-username>/Open-IM-Server.git (push)
|
||||
upstream https://github.com/OpenIMSDK/Open-IM-Server.git (fetch)
|
||||
upstream no-pushing (push)
|
||||
```
|
||||
|
||||
Adding this, we can easily synchronize local branches with upstream branches.
|
||||
|
||||
4. Create a new branch for your changes (use a descriptive name, such as `fix-bug-123` or `add-new-feature`).
|
||||
|
||||
```bash
|
||||
❯ cd Open-IM-Server
|
||||
❯ git fetch upstream
|
||||
❯ git checkout upstream/main
|
||||
```
|
||||
|
||||
Create a new branch:
|
||||
|
||||
```bash
|
||||
❯ git checkout -b <new-branch>
|
||||
```
|
||||
|
||||
Make any change on the `new-branch` then use [Makefile](./Makefile) build and test your codes.
|
||||
|
||||
5. **Commit your changes** to your local branch, lint before committing and commit with sign-off
|
||||
|
||||
```bash
|
||||
❯ git rebase upstream/main
|
||||
❯ make link # golangci-lint run -c .golangci.yml
|
||||
❯ git add -A # add changes to staging
|
||||
❯ git commit -a -s -m "message for your changes" # -s adds a Signed-off-by trailer
|
||||
```
|
||||
|
||||
6. **Push your branch** to your forked repository, it is recommended to have only one commit for a PR.
|
||||
|
||||
```bash
|
||||
# sync up with upstream
|
||||
❯ git fetch upstream main
|
||||
❯ git rebase upstream/main
|
||||
❯
|
||||
❯ git rebase -i <commit-id> # rebase with interactive mode to squash your commits into a single one
|
||||
❯ git push # push to the remote repository, if it's a first time push, run git push --set-upstream origin <new-branch># sync up with upstream
|
||||
❯ git fetch upstream main
|
||||
git rebase upstream/main
|
||||
|
||||
❯ git rebase -i <commit-id> # rebase with interactive mode to squash your commits into a single one
|
||||
❯ git push # push to the remote repository, if it's a first time push, run git push --set-upstream origin <new-branch>
|
||||
```
|
||||
|
||||
You can also use `git commit -s --amend && git push -f` to update modifications on the previous commit.
|
||||
|
||||
If you have developed multiple features in the same branch, you should create PR separately by rebasing to the main branch between each push:
|
||||
|
||||
```bash
|
||||
# create new branch, for example git checkout -b feature/infra
|
||||
❯ git checkout -b <new branch>
|
||||
# update some code, feature1
|
||||
❯ git add -A
|
||||
❯ git commit -m -s "feat: feature one"
|
||||
❯ git push # if it's first time push, run git push --set-upstream origin <new-branch>
|
||||
# then create pull request, and merge
|
||||
# update some new feature, feature2, rebase main branch first.
|
||||
❯ git rebase upstream/main # rebase the current branch to upstream/main branch
|
||||
❯ git add -A
|
||||
❯ git commit -m -s "feat: feature two"
|
||||
# then create pull request, and merge
|
||||
```
|
||||
|
||||
7. **Open a pull request** to `OpenIMSDK/Open-IM-Server:main`
|
||||
|
||||
It is recommended to review your changes before filing a pull request. Check if your code doesn't conflict with the main branch and no redundant code is included.
|
||||
|
||||
## Style and Specification
|
||||
|
||||
We divide the problem into security and general problems:
|
||||
|
||||
#### Reporting security issues
|
||||
|
||||
Security issues are always treated seriously. As our usual principle, we discourage anyone to spread security issues. If you find a security issue of Open-IM-Server, please do not discuss it in public and even do not open a public issue.
|
||||
|
||||
Instead we encourage you to send us a private email to winxu81@gmail.com to report this.
|
||||
|
||||
#### Reporting general issues
|
||||
|
||||
To be honest, we regard every user of Open-IM-Serveras a very kind contributor. After experiencing Open-IM-Server, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/OpenIMSDK/Open-IM-Server/issues/new/choose).
|
||||
|
||||
Since we collaborate project Open-IM-Server in a distributed way, we appreciate **WELL-WRITTEN**, **DETAILED**, **EXPLICIT** issue reports. To make the communication more efficient, we wish everyone could search if your issue is an existing one in the searching list. If you find it existing, please add your details in comments under the existing issue instead of opening a brand new one.
|
||||
|
||||
To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/.github/ISSUE_TEMPLATE) for issue reporters. You can find three kinds of issue templates there: question, bug report and feature request. Please **BE SURE** to follow the instructions to fill fields in template.
|
||||
|
||||
**There are a lot of cases when you could open an issue:**
|
||||
|
||||
+ bug report
|
||||
+ feature request
|
||||
+ Open-IM-Server performance issues
|
||||
+ feature proposal
|
||||
+ feature design
|
||||
+ help wanted
|
||||
+ doc incomplete
|
||||
+ test improvement
|
||||
+ any questions on Open-IM-Server project
|
||||
+ and so on
|
||||
|
||||
Also, we must be reminded when submitting a new question about Open-IM-Server, please remember to remove the sensitive data from your post. Sensitive data could be password, secret key, network locations, private business data and so on.
|
||||
|
||||
#### Commit Rules
|
||||
|
||||
Actually in Open-IM-Server, we take two rules serious when committing:
|
||||
|
||||
**🥇 Commit Message:**
|
||||
|
||||
Commit message could help reviewers better understand what the purpose of submitted PR is. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than ambiguous message. In general, we advocate the following commit message type:
|
||||
|
||||
We use [Semantic Commits](https://www.conventionalcommits.org/en/v1.0.0/) to make it easier to understand what a commit does and to build pretty changelogs. Please use the following prefixes for your commits:
|
||||
|
||||
+ `docs: xxxx`. For example, "docs: add docs about storage installation".
|
||||
+ `feature: xxxx`.For example, "feature: make result show in sorted order".
|
||||
+ `bugfix: xxxx`. For example, "bugfix: fix panic when input nil parameter".
|
||||
+ `style: xxxx`. For example, "style: format the code style of Constants.java".
|
||||
+ `refactor: xxxx.` For example, "refactor: simplify to make codes more readable".
|
||||
+ `test: xxx`. For example, "test: add unit test case for func InsertIntoArray".
|
||||
+ `chore: xxx.` For example, "chore: integrate travis-ci". It's the type of mantainance change.
|
||||
+ other readable and explicit expression ways.
|
||||
|
||||
On the other side, we discourage contributors from committing message like the following ways:
|
||||
|
||||
+ ~~fix bug~~
|
||||
+ ~~update~~
|
||||
+ ~~add doc~~
|
||||
|
||||
**🥈 Commit Content:**
|
||||
|
||||
Commit content represents all content changes included in one commit. We had better include things in one single commit which could support reviewer's complete review without any other commits' help.
|
||||
|
||||
In another word, contents in one single commit can pass the CI to avoid code mess. In brief, there are two minor rules for us to keep in mind:
|
||||
|
||||
1. avoid very large change in a commit.
|
||||
2. complete and reviewable for each commit.
|
||||
3. words are written in lowercase English, not uppercase English or other languages such as Chinese.
|
||||
|
||||
No matter what the commit message, or commit content is, we do take more emphasis on code review.
|
||||
|
||||
An example for this could be:
|
||||
|
||||
```bash
|
||||
❯ git commit -a -s -m "docs: add a new section to the README"
|
||||
```
|
||||
|
||||
#### PR Description
|
||||
|
||||
PR is the only way to make change to Open-IM-Server project files. To help reviewers better get your purpose, PR description could not be too detailed. We encourage contributors to follow the [PR template](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request.
|
||||
|
||||
You can find some very formal PR in [RFC](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) issues and learn about them.
|
||||
|
||||
**📖 Opening PRs:**
|
||||
|
||||
+ As long as you are working on your PR, please mark it as a draft
|
||||
+ Please make sure that your PR is up-to-date with the latest changes in `main`
|
||||
+ Mention the issue that your PR is addressing (Fix: #{ID_1}, #{ID_2})
|
||||
+ Make sure that your PR passes all checks
|
||||
|
||||
**🈴 Reviewing PRs:**
|
||||
|
||||
+ Be respectful and constructive
|
||||
+ Assign yourself to the PR
|
||||
+ Check if all checks are passing
|
||||
+ Suggest changes instead of simply commenting on found issues
|
||||
+ If you are unsure about something, ask the author
|
||||
+ If you are not sure if the changes work, try them out
|
||||
+ Reach out to other reviewers if you are unsure about something
|
||||
+ If you are happy with the changes, approve the PR
|
||||
+ Merge the PR once it has all approvals and the checks are passing
|
||||
|
||||
**⚠️ DCO check:**
|
||||
|
||||
We have a DCO check that runs on every pull request to ensure code quality and maintainability. This check verifies that the commit has been signed off, indicating that you have read and agreed to the provisions of the Developer Certificate of Origin. If you have not yet signed off on the commit, you can use the following command to sign off on the last commit you made:
|
||||
|
||||
```bash
|
||||
❯ git commit --amend --signoff
|
||||
```
|
||||
|
||||
Please note that signing off on a commit is a commitment that you have read and agreed to the provisions of the Developer Certificate of Origin. If you have not yet read this document, we strongly recommend that you take some time to read it carefully. If you have any questions about the content of this document, or if you need further assistance, please contact an administrator or relevant personnel.
|
||||
|
||||
You can also automate signing off your commits by adding the following to your `.zshrc` or `.bashrc`:
|
||||
|
||||
```go
|
||||
git() {
|
||||
if [ $# -gt 0 ] && [[ "$1" == "commit" ]] ; then
|
||||
shift
|
||||
command git commit --signoff "$@"
|
||||
else
|
||||
command git "$@"
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Docs Contribution
|
||||
|
||||
The documentation for Open-IM-Server includes:
|
||||
|
||||
+ [README.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/README.md): This file includes the basic information and instructions for getting started with Open-IM-Server.
|
||||
+ [CONTRIBUTING.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md): This file contains guidelines for contributing to Open-IM-Server's codebase, such as how to submit issues, pull requests, and code reviews.
|
||||
+ [DEVELOPGUIDE.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/DEVELOPGUIDE.md): This file provides a more in-depth guide to developing Open-IM-Server, including information on the project's architecture, coding conventions, and testing practices.
|
||||
+ [Official Documentation](https://doc.rentsoft.cn/): This is the official documentation for Open-IM-Server, which includes comprehensive information on all of its features, configuration options, and troubleshooting tips.
|
||||
|
||||
Please obey the following rules to better format the docs, which would greatly improve the reading experience.
|
||||
|
||||
1. Please do not use Chinese punctuations in English docs, and vice versa.
|
||||
2. Please use upper case letters where applicable, like the first letter of sentences / headings, etc.
|
||||
3. Please specify a language for each Markdown code blocks, unless there's no associated languages.
|
||||
4. Please insert a whitespace between Chinese and English words.
|
||||
5. Please use the correct case for technical terms, such as using `HTTP` instead of http, `MySQL` rather than mysql, `Kubernetes` instead of kubernetes, etc.
|
||||
6. Please check if there's any typos in the docs before submitting PRs.
|
||||
|
||||
## Engage to help anything
|
||||
|
||||
We choose GitHub as the primary place for Open-IM-Server to collaborate. So the latest updates of Open-IM-Server are always here. Although contributions via PR is an explicit way to help, we still call for any other ways.
|
||||
|
||||
+ reply to other's [issues](https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) if you could;
|
||||
+ help solve other user's problems;
|
||||
+ help review other's [PR](https://github.com/OpenIMSDK/Open-IM-Server/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc) design;
|
||||
+ discuss about Open-IM-Server to make things clearer;
|
||||
+ advocate [Open-IM-Server](google.com/search?q=Open-IM-Server) technology beyond GitHub;
|
||||
+ write blogs on Open-IM-Server and so on.
|
||||
|
||||
In a word, **ANY HELP IS CONTRIBUTION.**
|
||||
|
||||
## Release version
|
||||
|
||||
Releases of Open-IM-Server are done using [Release Please](https://github.com/googleapis/release-please) and [GoReleaser](https://goreleaser.com/). The workflow looks like this:
|
||||
|
||||
🎯 A PR is merged to the `main` branch:
|
||||
|
||||
+ Release please is triggered, creates or updates a new release PR
|
||||
+ This is done with every merge to main, the current release PR is updated every time
|
||||
|
||||
🎯 Merging the 'release please' PR to `main`:
|
||||
|
||||
+ Release please is triggered, creates a new release and updates the changelog based on the commit messages
|
||||
+ GoReleaser is triggered, builds the binaries and attaches them to the release
|
||||
+ Containers are created and pushed to the container registry
|
||||
|
||||
With the next relevant merge, a new release PR will be created and the process starts again
|
||||
|
||||
**👀 Manually setting the version:**
|
||||
|
||||
If you want to manually set the version, you can create a PR with an empty commit message that contains the version number in the commit message. For example:
|
||||
|
||||
Such a commit can get produced as follows:
|
||||
|
||||
````bash
|
||||
❯ git commit --allow-empty -m "chore: release 0.0.3" -m "Release-As: 0.0.3
|
||||
````
|
||||
|
||||
## Contact Us
|
||||
|
||||
We value close connections with our users, developers, and contributors here at Open-IM-Server. With a large community and maintainer team, we're always here to help and support you. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us.
|
||||
|
||||
Our most recommended way to get in touch is through [Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg). Even if you're in China, Slack is usually not blocked by firewalls, making it an easy way to connect with us. Our Slack community is the ideal place to discuss and share ideas and suggestions with other users and developers of Open-IM-Server. You can ask technical questions, seek help, or share your experiences with other users of Open-IM-Server.
|
||||
|
||||
In addition to Slack, we also offer the following ways to get in touch:
|
||||
|
||||
+ <a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg" target="_blank"><img src="https://img.shields.io/badge/slack-%40OpenIMSDKCore-informational?logo=slack&style=flat-square"></a>: We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [👀 Open-IM-Server slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel.
|
||||
+ <a href="https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=4closetool3@gmail.com" target="_blank"><img src="https://img.shields.io/badge/gmail-%40OOpenIMSDKCore?style=social&logo=gmail"></a>: Get in touch with us on [Gmail](winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email.
|
||||
+ <a href="https://doc.rentsoft.cn/" target="_blank"><img src="https://img.shields.io/badge/%E5%8D%9A%E5%AE%A2-%40OpenIMSDKCore-blue?style=social&logo=Octopus%20Deploy"></a>: Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with Open-IM-Server projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information.
|
||||
+ <a href="https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg" target="_blank"><img src="https://img.shields.io/badge/%E5%BE%AE%E4%BF%A1-OpenIMSDKCore-brightgreen?logo=wechat&style=flat-square"></a>: Add [Wechat](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible.
|
||||
|
||||
Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us.
|
||||
@@ -9,7 +9,7 @@ WORKDIR /Open-IM-Server
|
||||
# add all files to the container
|
||||
COPY . .
|
||||
|
||||
WORKDIR /Open-IM-Server/script
|
||||
WORKDIR /Open-IM-Server/scripts
|
||||
RUN chmod +x *.sh
|
||||
|
||||
RUN /bin/sh -c ./build_all_service.sh
|
||||
@@ -27,13 +27,13 @@ RUN apt-get install -y vim curl tzdata gawk
|
||||
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dpkg-reconfigure -f noninteractive tzdata
|
||||
|
||||
|
||||
#set directory to map logs,config file,script file.
|
||||
VOLUME ["/Open-IM-Server/logs","/Open-IM-Server/config","/Open-IM-Server/script","/Open-IM-Server/db/sdk"]
|
||||
#set directory to map logs,config file,scripts file.
|
||||
VOLUME ["/Open-IM-Server/logs","/Open-IM-Server/config","/Open-IM-Server/scripts","/Open-IM-Server/db/sdk"]
|
||||
|
||||
#Copy scripts files and binary files to the blank image
|
||||
COPY --from=build /Open-IM-Server/script /Open-IM-Server/script
|
||||
COPY --from=build /Open-IM-Server/scripts /Open-IM-Server/scripts
|
||||
COPY --from=build /Open-IM-Server/bin /Open-IM-Server/bin
|
||||
|
||||
WORKDIR /Open-IM-Server/script
|
||||
WORKDIR /Open-IM-Server/scripts
|
||||
|
||||
CMD ["./docker_start_all.sh"]
|
||||
@@ -0,0 +1,168 @@
|
||||
# ==============================================================================
|
||||
# define the default goal
|
||||
#
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
.PHONY: all
|
||||
all: tidy gen add-copyright format lint cover build
|
||||
|
||||
# ==============================================================================
|
||||
# Build set
|
||||
|
||||
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
||||
# TODO: This is version control for the future
|
||||
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
||||
|
||||
# ==============================================================================
|
||||
# Includes
|
||||
|
||||
include scripts/make-rules/common.mk # make sure include common.mk at the first include line
|
||||
include scripts/make-rules/golang.mk
|
||||
include scripts/make-rules/image.mk
|
||||
include scripts/make-rules/copyright.mk
|
||||
include scripts/make-rules/gen.mk
|
||||
include scripts/make-rules/dependencies.mk
|
||||
include scripts/make-rules/tools.mk
|
||||
|
||||
# ==============================================================================
|
||||
# Usage
|
||||
|
||||
define USAGE_OPTIONS
|
||||
|
||||
Options:
|
||||
|
||||
DEBUG Whether or not to generate debug symbols. Default is 0.
|
||||
|
||||
BINS Binaries to build. Default is all binaries under cmd.
|
||||
This option is available when using: make {build}(.multiarch)
|
||||
Example: make build BINS="open_im_api open_im_cms_api".
|
||||
|
||||
PLATFORMS Platform to build for. Default is linux_arm64 and linux_amd64.
|
||||
This option is available when using: make {build}.multiarch
|
||||
Example: make build.multiarch PLATFORMS="linux_arm64 linux_amd64".
|
||||
|
||||
V Set to 1 enable verbose build. Default is 0.
|
||||
endef
|
||||
export USAGE_OPTIONS
|
||||
|
||||
# ==============================================================================
|
||||
# Targets
|
||||
|
||||
## build: Build binaries by default
|
||||
.PHONY: build
|
||||
build:
|
||||
@$(MAKE) go.build
|
||||
|
||||
## build-multiarch: Build binaries for multiple platforms. See option PLATFORMS.
|
||||
.PHONY: build-multiarch
|
||||
build-multiarch:
|
||||
@$(MAKE) go.build.multiarch
|
||||
|
||||
## tidy: tidy go.mod
|
||||
.PHONY: tidy
|
||||
tidy:
|
||||
@$(GO) mod tidy
|
||||
|
||||
## vendor: vendor go.mod
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
@$(GO) mod vendor
|
||||
|
||||
## style: code style -> fmt,vet,lint
|
||||
.PHONY: style
|
||||
style: fmt vet lint
|
||||
|
||||
## fmt: Run go fmt against code.
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@$(GO) fmt ./...
|
||||
|
||||
## vet: Run go vet against code.
|
||||
.PHONY: vet
|
||||
vet:
|
||||
@$(GO) vet ./...
|
||||
|
||||
## lint: Check syntax and styling of go sources.
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@$(MAKE) go.lint
|
||||
|
||||
## format: Gofmt (reformat) package sources (exclude vendor dir if existed).
|
||||
.PHONY: format
|
||||
format:
|
||||
@$(MAKE) go.format
|
||||
|
||||
## test: Run unit test.
|
||||
.PHONY: test
|
||||
test:
|
||||
@$(MAKE) go.test
|
||||
|
||||
## cover: Run unit test and get test coverage.
|
||||
.PHONY: cover
|
||||
cover:
|
||||
@$(MAKE) go.test.cover
|
||||
|
||||
## updates: Check for updates to go.mod dependencies
|
||||
.PHONY: updates
|
||||
@$(MAKE) go.updates
|
||||
|
||||
## imports: task to automatically handle import packages in Go files using goimports tool
|
||||
.PHONY: imports
|
||||
imports:
|
||||
@$(MAKE) go.imports
|
||||
|
||||
## clean: Remove all files that are created by building.
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(MAKE) go.clean
|
||||
|
||||
## image: Build docker images for host arch.
|
||||
.PHONY: image
|
||||
image:
|
||||
@$(MAKE) image.build
|
||||
|
||||
## image.multiarch: Build docker images for multiple platforms. See option PLATFORMS.
|
||||
.PHONY: image.multiarch
|
||||
image.multiarch:
|
||||
@$(MAKE) image.build.multiarch
|
||||
|
||||
## push: Build docker images for host arch and push images to registry.
|
||||
.PHONY: push
|
||||
push:
|
||||
@$(MAKE) image.push
|
||||
|
||||
## push.multiarch: Build docker images for multiple platforms and push images to registry.
|
||||
.PHONY: push.multiarch
|
||||
push.multiarch:
|
||||
@$(MAKE) image.push.multiarch
|
||||
|
||||
## tools: Install dependent tools.
|
||||
.PHONY: tools
|
||||
tools:
|
||||
@$(MAKE) tools.install
|
||||
|
||||
## gen: Generate all necessary files.
|
||||
.PHONY: gen
|
||||
gen:
|
||||
@$(MAKE) gen.run
|
||||
|
||||
## verify-copyright: Verify the license headers for all files.
|
||||
.PHONY: verify-copyright
|
||||
verify-copyright:
|
||||
@$(MAKE) copyright.verify
|
||||
|
||||
## add-copyright: Add copyright ensure source code files have license headers.
|
||||
.PHONY: add-copyright
|
||||
add-copyright:
|
||||
@$(MAKE) copyright.add
|
||||
|
||||
## help: Show this help info.
|
||||
.PHONY: help
|
||||
help: Makefile
|
||||
$(call makehelp)
|
||||
|
||||
## help-all: Show all help details info.
|
||||
.PHONY: help-all
|
||||
help-all: go.help copyright.help tools.help image.help help
|
||||
$(call makeallhelp)
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
<h1 align="center" style="border-bottom: none">
|
||||
<b>
|
||||
<a href="https://doc.rentsoft.cn/">Open IM Server</a><br>
|
||||
</b>
|
||||
⭐️ Open source Instant Messaging Server ⭐️ <br>
|
||||
</h1>
|
||||
|
||||
|
||||
<p align=center>
|
||||
<a href="https://goreportcard.com/report/github.com/OpenIMSDK/Open-IM-Server"><img src="https://goreportcard.com/badge/github.com/OpenIMSDK/Open-IM-Server" alt="A+"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22"><img src="https://img.shields.io/github/issues/OpenIMSDK/Open-IM-Server/good%20first%20issue?logo=%22github%22" alt="good first"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server"><img src="https://img.shields.io/github/stars/OpenIMSDK/Open-IM-Server.svg?style=flat&logo=github&colorB=deeppink&label=stars"></a>
|
||||
<a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg"><img src="https://img.shields.io/badge/Slack-100%2B-blueviolet?logo=slack&logoColor=white"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a>
|
||||
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Language-Go-blue.svg"></a>
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="./README.md"><b>English</b></a> •
|
||||
<a href="./README_zh.md"><b>中文</b></a>
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
## Open-IM-Server 是什么
|
||||
|
||||
Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在客户端服务器上部署 Open-IM-Server,开发人员可以免费快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。
|
||||
|
||||
## 特点
|
||||
|
||||
+ 免费
|
||||
+ 可扩展架构
|
||||
+ 易于集成
|
||||
+ 良好的可扩展性
|
||||
+ 高性能
|
||||
+ 轻量级
|
||||
+ 支持多种协议
|
||||
|
||||
## 社区
|
||||
|
||||
+ 访问中文官方网站:[Open-IM中文开发文档](https://doc.rentsoft.cn/)
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装Open-IM-Server
|
||||
|
||||
> Open-IM 依赖于五个开源高性能组件:ETCD、MySQL、MongoDB、Redis 和 Kafka。在部署 Open-IM-Server 之前,请确保已安装上述五个组件。如果您的服务器没有上述组件,则必须首先安装缺失组件。如果您已经拥有上述组件,则建议直接使用它们。如果没有,则建议使用 Docker-compose,无需安装依赖项,一键部署,更快更方便。
|
||||
|
||||
### 使用 Docker 部署
|
||||
|
||||
1. 安装 [Go 环境](https://golang.org/doc/install)。确保 Go 版本至少为 1.17。
|
||||
|
||||
2. 克隆 Open-IM 项目到您的服务器
|
||||
|
||||
`git clone <https://github.com/OpenIMSDK/Open-IM-Server.git> --recursive`
|
||||
|
||||
3. 部署
|
||||
|
||||
1. 修改 env
|
||||
|
||||
```
|
||||
#cd Open-IM-server
|
||||
USER=root
|
||||
PASSWORD=openIM123 #密码至少8位数字,不包括特殊字符
|
||||
ENDPOINT=http://127.0.0.1:10005 #请用互联网IP替换127.0.0.1
|
||||
DATA_DIR=./
|
||||
```
|
||||
|
||||
2. 部署和启动
|
||||
|
||||
```
|
||||
chmod +x install_im_server.sh;
|
||||
./install_im_server.sh;
|
||||
```
|
||||
|
||||
3. 检查服务
|
||||
|
||||
```
|
||||
cd scripts;
|
||||
./docker_check_service.sh
|
||||
./check_all.sh
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 使用源代码部署
|
||||
|
||||
1. Go 1.17 或更高版本。
|
||||
|
||||
2. 克隆
|
||||
|
||||
```
|
||||
git clone <https://github.com/OpenIMSDK/Open-IM-Server.git> --recursive
|
||||
cd cmd/openim-sdk-core
|
||||
git checkout main
|
||||
```
|
||||
|
||||
3. 设置可执行权限
|
||||
|
||||
```
|
||||
cd ../../scripts/
|
||||
chmod +x *.sh
|
||||
```
|
||||
|
||||
4. 构建
|
||||
|
||||
```
|
||||
./batch_build_all_service.sh
|
||||
```
|
||||
|
||||
所有服务已成功构建
|
||||
|
||||
### 配置说明
|
||||
|
||||
> Open-IM 配置分为基本组件配置和业务内部服务配置。当使用产品时,开发人员需要将每个组件的地址填写为其服务器组件的地址,并确保业务内部服务端口未被占用。
|
||||
|
||||
### 基本组件配置说明
|
||||
|
||||
+ ETCD
|
||||
+ Etcd 用于 RPC 服务的发现和注册,Etcd Schema 是注册名称的前缀,建议将其修改为公司名称,Etcd 地址(ip+port)支持集群部署,可以填写多个 ETCD 地址,也可以只有一个 etcd 地址。
|
||||
+ MySQL
|
||||
+ MySQL 用于消息和用户关系的全存储,暂时不支持集群部署。修改地址、用户、密码和数据库名称。
|
||||
+ Mongo
|
||||
+ Mongo 用于消息的离线存储,默认存储 7 天。暂时不支持集群部署。只需修改地址和数据库名称即可。
|
||||
+ Redis
|
||||
+ Redis 目前主要用于消息序列号存储和用户令牌信息存储。暂时不支持集群部署。只需修改相应的 Redis 地址和密码即可。
|
||||
+ Kafka
|
||||
+ Kafka 用作消息传输存储队列,支持集群部署,只需修改相应的地址。
|
||||
|
||||
### 内部服务配置说明
|
||||
|
||||
+ credential&&push
|
||||
+ Open-IM 需要使用三方离线推送功能。目前使用的是腾讯的三方推送,支持 IOS、Android 和 OSX 推送。这些信息是腾讯推送的一些注册信息,开发人员需要去腾讯云移动推送注册相应的信息。如果您没有填写相应的信息,则无法使用离线消息推送功能。
|
||||
+ api&&rpcport&&longconnsvr&&rpcregistername
|
||||
+ API 端口是 HTTP 接口,longconnsvr 是 WebSocket 监听端口,rpcport 是内部服务启动端口。两者都支持集群部署。请确保这些端口未被使用。如果要为单个服务打开多个服务,请填写多个以逗号分隔的端口。rpcregistername 是每个服务在注册表 Etcd 中注册的服务名称,无需修改。
|
||||
+ log&&modulename
|
||||
+ 日志配置包括日志文件的存储路径,日志发送到 Elasticsearch 进行日志查看。目前不支持将日志发送到 Elasticsearch。暂时不需要修改配置。modulename 用于根据服务模块的名称拆分日志。默认配置可以。
|
||||
|
||||
### 脚本说明
|
||||
|
||||
> Open-IM 脚本提供服务编译、启动和停止脚本。有四个 Open-IM 脚本启动模块,一个是 http+rpc 服务启动模块,第二个是 WebSocket 服务启动模块,然后是 msg_transfer 模块,最后是 push 模块。
|
||||
|
||||
+ path_info.cfg&&style_info.cfg&&
|
||||
|
||||
functions.sh
|
||||
|
||||
+ 包含每个模块的路径信息,包括源代码所在的路径、服务启动名称、shell 打印字体样式以及一些用于处理 shell 字符串的函数。
|
||||
|
||||
+ build_all_service.sh
|
||||
|
||||
+ 编译模块,将 Open-IM 的所有源代码编译为二进制文件并放入 bin 目录。
|
||||
|
||||
+ start_rpc_api_service.sh&&msg_gateway_start.sh&&msg_transfer_start.sh&&push_start.sh
|
||||
|
||||
+ 独立脚本启动模块,后跟 API 和 RPC 模块、消息网关模块、消息传输模块和推送模块。
|
||||
|
||||
+ start_all.sh&&stop_all.sh
|
||||
|
||||
+ 总脚本,启动所有服务和关闭所有服务。
|
||||
|
||||
## 认证流程图
|
||||
|
||||

|
||||
|
||||
## 架构
|
||||
|
||||

|
||||
|
||||
## 开始开发 OpenIM
|
||||
|
||||
[社区存储库](https://github.com/OpenIMSDK/community)包含有关从源代码构建 Kubernetes、如何贡献代码和文档、有关什么的联系人等所有信息。
|
||||
|
||||
## 贡献
|
||||
|
||||
欢迎对该项目进行贡献!请参见 [CONTRIBUTING.md](http://CONTRIBUTING.md) 了解详细信息。
|
||||
|
||||
## 社区会议
|
||||
|
||||
我们希望任何人都能参与我们的社区,我们提供礼品和奖励,并欢迎您每周四晚上加入我们。
|
||||
|
||||
我们在 [GitHub 讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting) 中记录每个 [两周会议](https://github.com/OpenIMSDK/Open-IM-Server/issues/381),我们的记录写在 [Google 文档](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing) 中。
|
||||
|
||||
## 谁在使用 Open-IM-Server
|
||||
|
||||
[用户案例研究](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) 页面包括该项目的用户列表。您可以留下 [📝评论](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) 让我们知道您的用例。
|
||||
|
||||

|
||||
|
||||
## 许可证
|
||||
|
||||
Open-IM-Server 使用 Apache 2.0 许可证。有关详情,请参阅 LICENSE 文件。
|
||||
@@ -1,18 +1,34 @@
|
||||
# Open-IM-Server
|
||||

|
||||
<h1 align="center" style="border-bottom: none">
|
||||
<b>
|
||||
<a href="https://doc.rentsoft.cn/">Open IM Server</a><br>
|
||||
</b>
|
||||
⭐️ Open source Instant Messaging Server ⭐️ <br>
|
||||
</h1>
|
||||
|
||||

|
||||
|
||||
[](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE) [](https://golang.org/)
|
||||
<p align=center>
|
||||
<a href="https://goreportcard.com/report/github.com/OpenIMSDK/Open-IM-Server"><img src="https://goreportcard.com/badge/github.com/OpenIMSDK/Open-IM-Server" alt="A+"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22"><img src="https://img.shields.io/github/issues/OpenIMSDK/Open-IM-Server/good%20first%20issue?logo=%22github%22" alt="good first"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server"><img src="https://img.shields.io/github/stars/OpenIMSDK/Open-IM-Server.svg?style=flat&logo=github&colorB=deeppink&label=stars"></a>
|
||||
<a href="https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg"><img src="https://img.shields.io/badge/Slack-100%2B-blueviolet?logo=slack&logoColor=white"></a>
|
||||
<a href="https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a>
|
||||
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Language-Go-blue.svg"></a>
|
||||
</p>
|
||||
|
||||
## Open-IM-Server: Open source Instant Messaging Server
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="./README.md"><b> English </b></a> •
|
||||
<a href="./README-zh_CN.md"><b> 中文 </b></a>
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
## What is Open-IM-Server
|
||||
|
||||
Instant messaging server. Backend in pure Golang, wire transport protocol is JSON over websocket.
|
||||
|
||||
Everything is a message in Open-IM-Server, so you can extend custom messages easily, there is no need to modify the server code.
|
||||
|
||||
Using microservice architectures, Open-IM-Server can be deployed using clusters.
|
||||
|
||||
By deployment of the Open-IM-Server on the customer's server, developers can integrate instant messaging and real-time network capabilities into their own applications free of charge and quickly, and ensure the security and privacy of business data.
|
||||
|
||||
## Features
|
||||
@@ -26,8 +42,7 @@ By deployment of the Open-IM-Server on the customer's server, developers can int
|
||||
- Supports multiple protocols
|
||||
|
||||
## Community
|
||||
|
||||
- 中文官网访问这里:[Open-IM中文开发文档](https://doc.rentsoft.cn/)
|
||||
- Visit the Chinese official website here: [📚 Open-IM docs](https://www.openim.online/zh)
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -67,7 +82,7 @@ By deployment of the Open-IM-Server on the customer's server, developers can int
|
||||
4. Check service
|
||||
|
||||
```
|
||||
cd script;
|
||||
cd scripts;
|
||||
./docker_check_service.sh./check_all.sh
|
||||
```
|
||||
|
||||
@@ -75,19 +90,19 @@ By deployment of the Open-IM-Server on the customer's server, developers can int
|
||||
|
||||
#### Deploy using source code
|
||||
|
||||
1. Go 1.17 or above。
|
||||
1. Go 1.17 or above.
|
||||
2. Clone
|
||||
|
||||
```shell
|
||||
git clone https://github.com/OpenIMSDK/Open-IM-Server.git --recursive
|
||||
cd cmd/Open-IM-SDK-Core
|
||||
cd cmd/openim-sdk-core
|
||||
git checkout main
|
||||
```
|
||||
|
||||
1. Set executable permissions
|
||||
|
||||
```shell
|
||||
cd ../../script/
|
||||
cd ../../scripts/
|
||||
chmod +x *.sh
|
||||
```
|
||||
|
||||
@@ -127,18 +142,18 @@ all services build success
|
||||
- multiloginpolicy&&tokenpolicy
|
||||
- Open-IM supports multi-terminal login. Currently, there are three multi-terminal login policies. The PC terminal and the mobile terminal are online at the same time by default. When multiple policies are configured to be true, the first policy with true is used by default, and the token policy is the generated token policy. , The developer can customize the expiration time of the token
|
||||
|
||||
### SCRIPT DESCRIPTION
|
||||
### scripts DESCRIPTION
|
||||
|
||||
> Open-IM script provides service compilation, start, and stop scripts. There are four Open-IM script start modules, one is the http+rpc service start module, the second is the websocket service start module, then the msg_transfer module, and the last is the push module
|
||||
> Open-IM scripts provides service compilation, start, and stop scripts. There are four Open-IM scripts start modules, one is the http+rpc service start module, the second is the websocket service start module, then the msg_transfer module, and the last is the push module
|
||||
|
||||
- path_info.cfg&&style_info.cfg&&functions.sh
|
||||
- Contains the path information of each module, including the path where the source code is located, the name of the service startup, the shell print font style, and some functions for processing shell strings
|
||||
- build_all_service.sh
|
||||
- Compile the module, compile all the source code of Open-IM into a binary file and put it into the bin directory
|
||||
- start_rpc_api_service.sh&&msg_gateway_start.sh&&msg_transfer_start.sh&&push_start.sh
|
||||
- Independent script startup module, followed by api and rpc modules, message gateway module, message transfer module, and push module
|
||||
- Independent scripts startup module, followed by api and rpc modules, message gateway module, message transfer module, and push module
|
||||
- start_all.sh&&stop_all.sh
|
||||
- Total script, start all services and close all services
|
||||
- Total scripts, start all services and close all services
|
||||
|
||||
## Authentication Clow Chart
|
||||
|
||||
@@ -148,6 +163,25 @@ all services build success
|
||||
|
||||

|
||||
|
||||
## To start developing OpenIM
|
||||
The [community repository](https://github.com/OpenIMSDK/community) hosts all information about building Kubernetes from source, how to contribute code and documentation, who to contact about what, etc.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to this project are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
|
||||
|
||||
## Community Meetings
|
||||
We want anyone to get involved in our community, we offer gifts and rewards, and we welcome you to join us every Thursday night.
|
||||
|
||||
We take notes of each [biweekly meeting](https://github.com/OpenIMSDK/Open-IM-Server/issues/381) in [GitHub discussions](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting), and our minutes are written in [Google Docs](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing).
|
||||
|
||||
|
||||
## Who are using Open-IM-Server
|
||||
The [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page includes the user list of the project. You can leave a [📝comment](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) to let us know your use case.
|
||||
|
||||

|
||||
|
||||
## License
|
||||
|
||||
Open-IM-Server is under the Apache 2.0 license. See the [LICENSE](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/LICENSE) file for details
|
||||
Open-IM-Server is under the Apache 2.0 license. See the [LICENSE](./LICENSE) file for details
|
||||
|
||||
Submodule cmd/Open-IM-SDK-Core deleted from 373b6c00d4
+5
-10
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -10,8 +9,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
|
||||
@@ -46,9 +43,8 @@ func startPprof() {
|
||||
|
||||
func run(port int) error {
|
||||
if port == 0 {
|
||||
port = config.Config.Api.GinPort[0]
|
||||
return fmt.Errorf("port is empty")
|
||||
}
|
||||
var err error
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -56,18 +52,17 @@ func run(port int) error {
|
||||
fmt.Println("api start init discov client")
|
||||
var client discoveryregistry.SvcDiscoveryRegistry
|
||||
client, err = openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
openKeeper.WithFreq(time.Hour), openKeeper.WithUserNameAndPassword(config.Config.Zookeeper.UserName,
|
||||
openKeeper.WithFreq(time.Hour), openKeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), openKeeper.WithRoundRobin(), openKeeper.WithTimeout(10), openKeeper.WithLogger(log.NewZkLogger()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("api init discov client success")
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err := yaml.NewEncoder(buf).Encode(config.Config); err != nil {
|
||||
if err := client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("api init discov client success")
|
||||
fmt.Println("api register public config to discov")
|
||||
if err := client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, buf.Bytes()); err != nil {
|
||||
if err := client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.EncodeConfig()); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("api register public config to discov success")
|
||||
|
||||
+157
-228
@@ -1,137 +1,86 @@
|
||||
# The class cannot be named by Pascal or camel case.
|
||||
# If it is not used, the corresponding structure will not be set,
|
||||
# and it will not be read naturally.
|
||||
serverversion: 2.3.7
|
||||
#OpenIM config
|
||||
|
||||
|
||||
#---------------Infrastructure configuration---------------------#
|
||||
zookeeper:
|
||||
schema: openim #默认即可
|
||||
zkAddr: [ 127.0.0.1:2181 ] #单机部署时,默认即可
|
||||
userName:
|
||||
password:
|
||||
schema: openim #不建议修改
|
||||
address: [ 127.0.0.1:2181 ] #
|
||||
username: #用户名
|
||||
password: #密码
|
||||
|
||||
mysql:
|
||||
dbMysqlAddress: [ 127.0.0.1:13306 ] #mysql地址 目前仅支持单机,默认即可
|
||||
dbMysqlUserName: root #mysql用户名,建议修改
|
||||
dbMysqlPassword: openIM123 # mysql密码,建议修改
|
||||
dbMysqlDatabaseName: openIM_v2 #默认即可
|
||||
dbTableName: eMsg #默认即可
|
||||
dbMsgTableNum: 1
|
||||
dbMaxOpenConns: 100
|
||||
dbMaxIdleConns: 10
|
||||
dbMaxLifeTime: 5
|
||||
logLevel: 4 #1=slient 2=error 3=warn 4=info
|
||||
slowThreshold: 500
|
||||
address: [ 127.0.0.1:13306 ] #目前仅支持单机
|
||||
username: root #用户名
|
||||
password: openIM123 #密码
|
||||
database: openIM_v3 #不建议修改
|
||||
maxOpenConn: 1000 #最大连接数
|
||||
maxIdleConn: 100 #最大空闲连接数
|
||||
maxLifeTime: 60 #连接可以重复使用的最长时间(秒)
|
||||
logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info
|
||||
slowThreshold: 500 #慢语句阈值 (毫秒)
|
||||
|
||||
mongo:
|
||||
dbUri: ""#当dbUri值不为空则直接使用该值
|
||||
dbAddress: [ 127.0.0.1:37017 ] #单机时为mongo地址,使用分片集群时,为mongos地址 默认即可
|
||||
dbDirect: false
|
||||
dbTimeout: 60
|
||||
dbDatabase: openIM #mongo db 默认即可
|
||||
dbSource: admin
|
||||
dbUserName: root #mongo用户名,建议先不设置
|
||||
dbPassword: openIM123 #mongo密码,建议先不设置
|
||||
dbMaxPoolSize: 100
|
||||
dbRetainChatRecords: 3650 #mongo保存离线消息时间(天),根据需求修改
|
||||
chatRecordsClearTime: "0 2 * * 3" # 每周三凌晨2点清除消息,该配置和linux定时任务一样, 清理操作建议设置在用户活跃少的时候 # 0 3 * * *
|
||||
uri: #不为空则直接使用该值
|
||||
address: [ 127.0.0.1:37017 ] #单机时为mongo地址,使用分片集群时,为mongos地址
|
||||
database: openIM_v3 #mongo db 默认即可
|
||||
username: root #用户名
|
||||
password: openIM123 #密码
|
||||
maxPoolSize: 100
|
||||
|
||||
redis:
|
||||
dbAddress: [ 127.0.0.1:16379 ] #redis地址 单机时,填写一个地址即可,使用redis集群时候,填写集群中多个节点地址(主从地址都可以填写,增加容灾能力),默认即可
|
||||
dbMaxIdle: 128
|
||||
dbMaxActive: 0
|
||||
dbIdleTimeout: 120
|
||||
dbUserName: #only redis version 6.0+ need username
|
||||
dbPassWord: openIM123 #redis密码 建议修改
|
||||
enableCluster: false #如果外部redis以集群方式启动,需要打开此开关
|
||||
address: [ 127.0.0.1:16379 ] #
|
||||
username: #only redis version 6.0+ need username
|
||||
password: openIM123 #密码
|
||||
|
||||
kafka:
|
||||
SASLUserName:
|
||||
SASLPassword:
|
||||
ws2mschat:
|
||||
addr: [ 127.0.0.1:9092 ] #kafka配置,默认即可
|
||||
topic: "ws2ms_chat" #用于mongo和mysql保存消息
|
||||
msgtomongo:
|
||||
addr: [ 127.0.0.1:9092 ] #kafka配置,默认即可
|
||||
topic: "msg_to_mongo"
|
||||
ms2pschat:
|
||||
addr: [ 127.0.0.1:9092 ] #kafka配置,默认即可
|
||||
topic: "ms2ps_chat" #消息push
|
||||
msgtomodify:
|
||||
addr: [ 127.0.0.1:9092 ] #kafka配置,默认即可
|
||||
topic: "msg_to_modify"
|
||||
consumergroupid:
|
||||
msgToTransfer: mongo
|
||||
msgToMongo: mongo_ex
|
||||
msgToMySql: mysql
|
||||
msgToPush: push
|
||||
msgToModify: modify
|
||||
username: #用户名
|
||||
password: #密码
|
||||
addr: [ 127.0.0.1:9092 ] #
|
||||
latestMsgToRedis:
|
||||
topic: "latestMsgToRedis" #不建议修改
|
||||
offlineMsgToMongo:
|
||||
topic: "offlineMsgToMongoMysql" #不建议修改
|
||||
msgToPush:
|
||||
topic: "msgToPush" #不建议修改
|
||||
consumerGroupID: #消费者组,不建议修改
|
||||
msgToRedis: redis #
|
||||
msgToMongo: mongo #
|
||||
msgToMySql: mysql #
|
||||
msgToPush: push #
|
||||
|
||||
|
||||
#---------------Internal service configuration---------------------#
|
||||
|
||||
# The service ip default is empty,
|
||||
# automatically obtain the machine's valid network card ip as the service ip,
|
||||
# otherwise the configuration ip is preferred
|
||||
#如果是单机模式,用0.0.0.0或者不填,默认即可
|
||||
|
||||
#作为rpc时,注册到etcd的地址,单机默认即可,如果是集群部署,需要修改(具体使用内网地址还是外网地址,要依情况而定,目的是api/gateway能访问到)
|
||||
rpcRegisterIP:
|
||||
#默认即可
|
||||
listenIP: 0.0.0.0
|
||||
rpc:
|
||||
registerIP: #作为rpc启动时,注册到zookeeper的IP,api/gateway能访问到此ip和对应的rpcPort中的端口
|
||||
listenIP: #默认为0.0.0.0
|
||||
|
||||
|
||||
api:
|
||||
openImApiPort: [ 10002 ] #api服务端口,默认即可,需要开放此端口或做nginx转发
|
||||
listenIP: 0.0.0.0
|
||||
|
||||
sdk:
|
||||
openImSdkWsPort: [ 10003 ] #jssdk服务端口,默认即可,项目中使用jssdk才需开放此端口或做nginx转发
|
||||
dataDir: [ ../db/sdk/ ]
|
||||
openImWsAddress: ws://127.0.0.1:10001
|
||||
openImApiAddress: http://127.0.0.1:10002
|
||||
|
||||
#对象存储服务,以下配置二选一,目前支持两种,腾讯云和minio,二者配置好其中一种即可(如果使用minio参考https://doc.rentsoft.cn/#/qa/minio搭建minio服务器)
|
||||
credential: #腾讯cos,发送图片、视频、文件时需要,请自行申请后替换,必须修改
|
||||
|
||||
openImApiPort: [ 10002 ] #api服务端口
|
||||
listenIP: #默认为0.0.0.0
|
||||
|
||||
object:
|
||||
enable: minio
|
||||
apiURL: http://127.0.0.1:10002/third/object
|
||||
minio: #MinIO 发送图片、视频、文件时需要,请自行申请后替换,必须修改。 客户端初始化InitSDK,中 object_storage参数为minio
|
||||
tempBucket: "openim"
|
||||
dataBucket: "openim"
|
||||
location: us-east-1
|
||||
endpoint: http://127.0.0.1:10005 #minio外网ip 这个ip是给客户端访问的
|
||||
accessKeyID: root
|
||||
secretAccessKey: openIM123
|
||||
isDistributedMod: false # 是否分布式多硬盘部署 默认docker-compose中为false,如果是多硬盘部署,需要修改为true
|
||||
tencent:
|
||||
appID:
|
||||
region:
|
||||
bucket:
|
||||
secretID:
|
||||
secretKey:
|
||||
ali: # ali oss
|
||||
regionID:
|
||||
accessKeyID:
|
||||
accessKeySecret:
|
||||
stsEndpoint:
|
||||
ossEndpoint:
|
||||
bucket:
|
||||
finalHost:
|
||||
stsDurationSeconds:
|
||||
OssRoleArn:
|
||||
aws:
|
||||
accessKeyID: #AssumeRole用户关联的accessKeyID
|
||||
accessKeySecret: #AssumeRole用户关联的accessKeySecrect
|
||||
region: #分区
|
||||
bucket: #桶
|
||||
finalHost: #对外Host
|
||||
roleArn: #RoleArn
|
||||
externalId: #角色扩展Id
|
||||
roleSessionName: #角色SESSION名称
|
||||
enable: "minio" #使用minio
|
||||
apiURL: "http://127.0.0.1:10002/object/"
|
||||
minio:
|
||||
bucket: "openim" #不建议修改
|
||||
endpoint: "http://127.0.0.1:10005" #minio对外服务的ip和端口,app要能访问此ip和端口
|
||||
accessKeyID: "root" #ID
|
||||
secretAccessKey: "openIM123" #秘钥
|
||||
sessionToken: "" #token
|
||||
cos: #tencent cos
|
||||
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
|
||||
secretID: ""
|
||||
secretKey: ""
|
||||
sessionToken: ""
|
||||
oss: #ali oss
|
||||
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||
bucket: "demo-9999999"
|
||||
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
||||
accessKeyID: ""
|
||||
accessKeySecret: ""
|
||||
sessionToken: ""
|
||||
|
||||
rpcport: #rpc服务端口 默认即可
|
||||
rpcPort: #rpc服务端口,不建议修改,端口由脚本读取后传入程序,如启动多个程序,只需要填入多个端口,用逗号隔开,如 [10110, 10111]
|
||||
openImUserPort: [ 10110 ]
|
||||
openImFriendPort: [ 10120 ]
|
||||
openImMessagePort: [ 10130 ]
|
||||
@@ -140,10 +89,9 @@ rpcport: #rpc服务端口 默认即可
|
||||
openImAuthPort: [ 10160 ]
|
||||
openImPushPort: [ 10170 ]
|
||||
openImConversationPort: [ 10180 ]
|
||||
openImRtcPort: [ 10190 ]
|
||||
openImThirdPort: [ 10200 ]
|
||||
openImThirdPort: [ 10190 ]
|
||||
|
||||
rpcregistername: #rpc注册服务名,默认即可
|
||||
rpcRegisterName: #rpc注册服务名,不建议修改
|
||||
openImUserName: User
|
||||
openImFriendName: Friend
|
||||
openImMsgName: Msg
|
||||
@@ -152,158 +100,138 @@ rpcregistername: #rpc注册服务名,默认即可
|
||||
openImGroupName: Group
|
||||
openImAuthName: Auth
|
||||
openImConversationName: Conversation
|
||||
openImRtcName: Rtc
|
||||
openImThirdName: Third
|
||||
|
||||
log:
|
||||
storageLocation: ../logs/
|
||||
rotationTime: 24
|
||||
remainRotationCount: 2 #日志数量
|
||||
#日志级别 6表示全都打印,测试阶段建议设置为6
|
||||
remainLogLevel: 6
|
||||
storageLocation: ../logs/ #存放目录
|
||||
rotationTime: 24 #日志旋转时间
|
||||
remainRotationCount: 2 #日志数量
|
||||
remainLogLevel: 6 #日志级别 6表示全都打印,
|
||||
isStdout: false
|
||||
isJson: false
|
||||
withStack: false
|
||||
|
||||
modulename: #日志文件按模块命名,默认即可
|
||||
longConnSvrName: msg_gateway
|
||||
msgTransferName: msg_transfer
|
||||
pushName: push
|
||||
longConnSvr:
|
||||
openImWsPort: [ 10001 ] #msg_gateway的websocket端口
|
||||
websocketMaxConnNum: 100000 #websocket最大连接数
|
||||
websocketMaxMsgLen: 4096 #websocket请求包最大长度
|
||||
websocketTimeout: 10 #websocket连接握手超时时间
|
||||
|
||||
longconnsvr:
|
||||
openImWsPort: [ 10001 ] # ws服务端口,默认即可,要开放此端口或做nginx转发
|
||||
websocketMaxConnNum: 10000
|
||||
websocketMaxMsgLen: 4096
|
||||
websocketTimeOut: 10
|
||||
|
||||
## 推送只能开启一个 enable代表开启
|
||||
push:
|
||||
tpns: #腾讯推送,暂未测试 暂不要使用
|
||||
ios:
|
||||
accessID: 1600018281
|
||||
secretKey: 3cd68a77a95b89e5089a1aca523f318f
|
||||
android:
|
||||
accessID: 111
|
||||
secretKey: 111
|
||||
enable: false # true or false (bool)
|
||||
jpns: #极光推送 在极光后台申请后,修改以下四项,必须修改
|
||||
appKey:
|
||||
masterSecret:
|
||||
pushUrl:
|
||||
pushIntent:
|
||||
enable: false # true or false (bool)
|
||||
getui: #个推推送
|
||||
enable: getui
|
||||
geTui: #个推离线推送
|
||||
pushUrl: "https://restapi.getui.com/v2/$appId"
|
||||
masterSecret: ""
|
||||
appKey: ""
|
||||
intent: ""
|
||||
enable: false # true or false (bool)
|
||||
channelID: ""
|
||||
channelName: ""
|
||||
fcm: #firebase cloud message 消息推送
|
||||
serviceAccount: "openim-5c6c0-firebase-adminsdk-ppwol-8765884a78.json" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
||||
enable: false
|
||||
fcm: #fcm离线推送
|
||||
serviceAccount: "x.json" #帐号文件,并放在 config目录下
|
||||
jpns: #极光推送 在极光后台申请后,修改以下四项
|
||||
appKey:
|
||||
masterSecret:
|
||||
pushUrl:
|
||||
pushIntent:
|
||||
|
||||
manager:
|
||||
#app管理员userID和对应的secret 建议修改。 用于管理后台登录,也可以用户管理后台对应的api
|
||||
appManagerUid: [ "openIM123456","openIM654321", "openIM333", "openIMAdmin" ]
|
||||
nickname: [ "系统通知","openIM654321", "openIM333", "openIMAdmin" ]
|
||||
userID: [ "openIM123456","openIM654321","openIMAdmin" ] #内置的app管理员userID
|
||||
nickname: [ "system1","system2", "system3" ] #内置的app管理员nickname
|
||||
|
||||
|
||||
secret: tuoyun
|
||||
# 多端互踢策略
|
||||
# 1:多平台登录:Android、iOS、Windows、Mac 每种平台只能一个在线,web端可以多个同时在线
|
||||
multiloginpolicy: 1
|
||||
|
||||
#msg log insert to db
|
||||
chatpersistencemysql: true
|
||||
#消息缓存时间
|
||||
msgCacheTimeout: 86400
|
||||
#群聊已读开启
|
||||
groupMessageHasReadReceiptEnable: true
|
||||
#单聊已读开启
|
||||
singleMessageHasReadReceiptEnable: true
|
||||
|
||||
#token config
|
||||
tokenpolicy:
|
||||
accessSecret: "OpenIM_server" #token生成相关,默认即可
|
||||
# Token effective time day as a unit
|
||||
accessExpire: 90 #token过期时间(天) 默认即可
|
||||
messageverify:
|
||||
friendVerify: false
|
||||
multiLoginPolicy: 1 #多平台登录:Android、iOS、Windows、Mac、web 每种平台只能有一个在线
|
||||
|
||||
|
||||
chatPersistenceMysql: true #消息是否存入mysql,mysql中的消息仅用于管理后台使用
|
||||
msgCacheTimeout: 86400 #信消息缓存时间秒,不建议修改
|
||||
groupMessageHasReadReceiptEnable: true #群聊已读是否开启
|
||||
singleMessageHasReadReceiptEnable: true #单聊已读是否开启
|
||||
|
||||
retainChatRecords: 365 #mongo保存离线消息时间(天)
|
||||
chatRecordsClearTime: "0 2 * * 3" #每周三凌晨2点清理mongo中的过期(超过retainChatRecords时间)消息,这个删除是为了清理满足上个配置retainChatRecords的过期消息,不会发送通知,仅仅作为清理磁盘使用
|
||||
msgDestructTime: "0 2 * * *" #消息自动删除时间,每天凌晨2点删除过期消息,这个删除是为了删除保留时间超过超过会话字段msg_destruct_time(秒)的消息。
|
||||
|
||||
secret: tuoyun #秘钥,获取token时校验
|
||||
|
||||
tokenPolicy:
|
||||
expire: 90 #过期时间(天)
|
||||
|
||||
messageVerify:
|
||||
friendVerify: false #发送消息时是否验证好友关系
|
||||
|
||||
#ios系统推送声音以及标记计数
|
||||
iospush:
|
||||
iosPush:
|
||||
pushSound: "xxx"
|
||||
badgeCount: true
|
||||
production: false
|
||||
|
||||
callback:
|
||||
# callback url 需要自行更换callback url
|
||||
callbackUrl: "http://127.0.0.1:10008/callback/open_im"
|
||||
# 开启关闭操作前后回调的配置
|
||||
callbackBeforeSendSingleMsg:
|
||||
enable: false # 回调是否启用
|
||||
callbackTimeOut: 2 # 回调超时时间
|
||||
callbackFailedContinue: true # 回调超时是否继续执行代码
|
||||
callbackAfterSendSingleMsg:
|
||||
# 回调callback
|
||||
url:
|
||||
beforeSendSingleMsg:
|
||||
enable: false #是否启用此回调事件
|
||||
timeout: 5 #超时时间(秒)
|
||||
failedContinue: true #如回调失败是否继续往后执行
|
||||
afterSendSingleMsg:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackBeforeSendGroupMsg:
|
||||
timeout: 5
|
||||
beforeSendGroupMsg:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true
|
||||
callbackAfterSendGroupMsg:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
afterSendGroupMsg:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackMsgModify:
|
||||
timeout: 5
|
||||
msgModify:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true
|
||||
callbackUserOnline:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
userOnline:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackUserOffline:
|
||||
timeout: 5
|
||||
userOffline:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackUserKickOff:
|
||||
timeout: 5
|
||||
userKickOff:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackOfflinePush:
|
||||
timeout: 5
|
||||
offlinePush:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续离线推送
|
||||
callbackOnlinePush:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
onlinePush:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续离线推送
|
||||
callbackSuperGroupOnlinePush:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
superGroupOnlinePush:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续离线推送
|
||||
callbackBeforeAddFriend:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeAddFriend:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续
|
||||
callbackBeforeCreateGroup:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeCreateGroup:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续
|
||||
callbackBeforeMemberJoinGroup:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeMemberJoinGroup:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续
|
||||
callbackBeforeSetGroupMemberInfo:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
beforeSetGroupMemberInfo:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续
|
||||
callbackSetMessageReactionExtensions:
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
setMessageReactionExtensions:
|
||||
enable: false
|
||||
callbackTimeOut: 2
|
||||
callbackFailedContinue: true # 回调超时是否继续
|
||||
timeout: 5
|
||||
failedContinue: true
|
||||
|
||||
# prometheus每个服务监听的端口数量需要和rpc port保持一致
|
||||
prometheus:
|
||||
|
||||
prometheus: #prometheus每个服务的端口数量需要和rpcPort保持对应
|
||||
enable: false
|
||||
userPrometheusPort: [ 20110 ]
|
||||
friendPrometheusPort: [ 20120 ]
|
||||
@@ -314,5 +242,6 @@ prometheus:
|
||||
pushPrometheusPort: [ 20170 ]
|
||||
conversationPrometheusPort: [ 20230 ]
|
||||
rtcPrometheusPort: [ 21300 ]
|
||||
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] # 端口数量和 script/path_info.cfg msg_transfer_service_num保持一致
|
||||
thirdPrometheusPort: [ 21301 ]
|
||||
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] #端口数量需要和script/path_info.cfg中的msg_transfer_service_num保持一致
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
version: "3"
|
||||
#fixme Clone openIM Server project before using docker-compose,project address:https://github.com/OpenIMSDK/Open-IM-Server.git
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- 13306:3306
|
||||
- 23306:33060
|
||||
container_name: mysql
|
||||
volumes:
|
||||
- ./components/mysql/data:/var/lib/mysql
|
||||
- /etc/localtime:/etc/localtime
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: openIM
|
||||
restart: always
|
||||
|
||||
mongos:
|
||||
image: mongo:latest
|
||||
ports:
|
||||
- 37017:27017
|
||||
container_name: mongos
|
||||
command: mongos --configdb config/103.116.45.174:27019 --bind_ip_all
|
||||
volumes:
|
||||
- ./components/mongos_mongodb/data/db:/data/db
|
||||
- ./components/mongos_mongodb/data/logs:/data/logs
|
||||
- ./components/mongos_mongodb/data/conf:/etc/mongo
|
||||
- ./components/mongos_mongodb/data/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=openIM
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=openIM
|
||||
|
||||
|
||||
#TZ: Asia/Shanghai
|
||||
restart: always
|
||||
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 16379:6379
|
||||
container_name: redis
|
||||
volumes:
|
||||
- ./components/redis/data:/data
|
||||
#redis config file
|
||||
- ./components/redis/config/redis.conf:/usr/local/redis/config/redis.conf
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
sysctls:
|
||||
net.core.somaxconn: 1024
|
||||
command: redis-server --requirepass openIM --appendonly yes
|
||||
|
||||
|
||||
zookeeper:
|
||||
image: wurstmeister/zookeeper
|
||||
ports:
|
||||
- 2181:2181
|
||||
container_name: zookeeper
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
|
||||
|
||||
kafka:
|
||||
image: wurstmeister/kafka
|
||||
container_name: kafka
|
||||
restart: always
|
||||
ports:
|
||||
- 9092:9092
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
KAFKA_BROKER_ID: 0
|
||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||
KAFKA_CREATE_TOPICS: "ws2ms_chat:8:1,ms2ps_chat:8:1,msg_to_mongo:8:1"
|
||||
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
||||
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT"
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
|
||||
depends_on:
|
||||
- zookeeper
|
||||
|
||||
etcd:
|
||||
image: quay.io/coreos/etcd
|
||||
ports:
|
||||
- 2379:2379
|
||||
- 2380:2380
|
||||
container_name: etcd
|
||||
volumes:
|
||||
- /etc/timezone:/etc/timezone
|
||||
- /etc/localtime:/etc/localtime
|
||||
environment:
|
||||
ETCDCTL_API: 3
|
||||
restart: always
|
||||
command: /usr/local/bin/etcd --name etcd0 --data-dir /etcd-data --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379 --listen-peer-urls http://0.0.0.0:2380 --initial-advertise-peer-urls http://0.0.0.0:2380 --initial-cluster etcd0=http://0.0.0.0:2380 --initial-cluster-token tkn --initial-cluster-state new
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
ports:
|
||||
- 10005:9000
|
||||
- 9090:9090
|
||||
container_name: minio
|
||||
volumes:
|
||||
- /mnt/data:/data
|
||||
- /mnt/config:/root/.minio
|
||||
environment:
|
||||
MINIO_ROOT_USER: user12345
|
||||
MINIO_ROOT_PASSWORD: key12345
|
||||
restart: always
|
||||
command: minio server /data --console-address ':9090'
|
||||
|
||||
open_im_server:
|
||||
image: openim/open_im_server:v2.3.0-rc1
|
||||
container_name: open_im_server
|
||||
volumes:
|
||||
- ./logs:/Open-IM-Server/logs
|
||||
- ./config/config.yaml:/Open-IM-Server/config/config.yaml
|
||||
- ./db/sdk:/Open-IM-Server/db/sdk
|
||||
- ./script:/Open-IM-Server/script
|
||||
restart: always
|
||||
depends_on:
|
||||
- kafka
|
||||
- mysql
|
||||
- mongos
|
||||
- redis
|
||||
- etcd
|
||||
- minio
|
||||
network_mode: "host"
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "1g"
|
||||
max-file: "2"
|
||||
@@ -1,113 +0,0 @@
|
||||
version: '3'
|
||||
networks:
|
||||
mongo-network:
|
||||
external: false
|
||||
services:
|
||||
# 配置服务器configsvr
|
||||
config:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: config
|
||||
restart: always
|
||||
ports:
|
||||
- 27019:27019
|
||||
command: --configsvr --replSet "config" --bind_ip_all
|
||||
volumes:
|
||||
- ./components/config_mongodb/data/db:/data/db
|
||||
- ./components/config_mongodb/data/logs:/data/logs
|
||||
- ./components/config_mongodb/data/conf:/etc/mongo
|
||||
- ./components/config_mongodb/data/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
|
||||
# shard分片1
|
||||
shard1:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: shard1
|
||||
restart: always
|
||||
ports:
|
||||
- 27118:27018
|
||||
command: --shardsvr --replSet "shard1" --bind_ip_all
|
||||
volumes:
|
||||
- /data01/mongo/shard1/db:/data/db
|
||||
- /data01/mongo/shard1/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
|
||||
# shard分片2
|
||||
shard2:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: shard2
|
||||
restart: always
|
||||
ports:
|
||||
- 27218:27018
|
||||
command: --shardsvr --replSet "shard2" --bind_ip_all
|
||||
volumes:
|
||||
- /data02/mongo/shard2/db:/data/db
|
||||
- /data02/mongo/shard2/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
# - ${PWD}/key.file:/data/mongodb/key.file
|
||||
|
||||
# shard分片3
|
||||
shard3:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: shard3
|
||||
restart: always
|
||||
ports:
|
||||
- 27318:27018
|
||||
command: --shardsvr --replSet "shard3" --bind_ip_all
|
||||
volumes:
|
||||
- /data03/mongo/shard3/db:/data/db
|
||||
- /data03/mongo/shard3/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
# shard分片4
|
||||
shard4:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: shard4
|
||||
restart: always
|
||||
ports:
|
||||
- 27418:27018
|
||||
command: --shardsvr --replSet "shard4" --bind_ip_all
|
||||
volumes:
|
||||
- /data04/mongo/shard4/db:/data/db
|
||||
- /data04/mongo/shard4/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
# shard分片5
|
||||
shard5:
|
||||
image: mongo:latest
|
||||
networks:
|
||||
- mongo-network
|
||||
container_name: shard5
|
||||
restart: always
|
||||
ports:
|
||||
- 27518:27018
|
||||
command: --shardsvr --replSet "shard5" --bind_ip_all
|
||||
volumes:
|
||||
- /data05/mongo/shard5/db:/data/db
|
||||
- /data05/mongo/shard5/configdb:/data/configdb
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
- wiredTigerCacheSizeGB=1
|
||||
+9
-14
@@ -15,7 +15,7 @@ services:
|
||||
restart: always
|
||||
|
||||
mongodb:
|
||||
image: mongo:4.0
|
||||
image: mongo:6.0
|
||||
ports:
|
||||
- 37017:27017
|
||||
container_name: mongo
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- ${DATA_DIR}/components/mongodb/data/db:/data/db
|
||||
- ${DATA_DIR}/components/mongodb/data/logs:/data/logs
|
||||
- ${DATA_DIR}/components/mongodb/data/conf:/etc/mongo
|
||||
- ./script/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro
|
||||
- ./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# cache
|
||||
@@ -37,7 +37,7 @@ services:
|
||||
restart: always
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
image: redis:6.2.5
|
||||
ports:
|
||||
- 16379:6379
|
||||
container_name: redis
|
||||
@@ -75,7 +75,7 @@ services:
|
||||
TZ: Asia/Shanghai
|
||||
KAFKA_BROKER_ID: 0
|
||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||
KAFKA_CREATE_TOPICS: "ws2ms_chat:8:1,ms2ps_chat:8:1,msg_to_mongo:8:1"
|
||||
KAFKA_CREATE_TOPICS: "latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1"
|
||||
KAFKA_ADVERTISED_LISTENERS: INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092
|
||||
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT"
|
||||
@@ -100,14 +100,14 @@ services:
|
||||
|
||||
|
||||
open_im_server:
|
||||
image: openim/open_im_server:v3.0.0
|
||||
image: openim/open_im_server:v3.0.1
|
||||
container_name: open_im_server
|
||||
volumes:
|
||||
- ./logs:/Open-IM-Server/logs
|
||||
- ./config/config.yaml:/Open-IM-Server/config/config.yaml
|
||||
- ./config/notification.yaml:/Open-IM-Server/config/notification.yaml
|
||||
- ${DATA_DIR}/db/sdk:/Open-IM-Server/db/sdk
|
||||
- ./script:/Open-IM-Server/script
|
||||
- ./scripts:/Open-IM-Server/scripts
|
||||
restart: always
|
||||
depends_on:
|
||||
- kafka
|
||||
@@ -122,12 +122,9 @@ services:
|
||||
max-size: "1g"
|
||||
max-file: "2"
|
||||
|
||||
open_im_enterprise:
|
||||
image: openim/open_im_enterprise:v1.0.2
|
||||
container_name: open_im_enterprise
|
||||
volumes:
|
||||
- ./logs:/Open-IM-Enterprise/logs
|
||||
- ./.docker-compose_cfg/config.yaml:/Open-IM-Enterprise/config/config.yaml
|
||||
openim_chat:
|
||||
image: openim/openim_chat:v1.1.0
|
||||
container_name: openim_chat
|
||||
restart: always
|
||||
depends_on:
|
||||
- mysql
|
||||
@@ -141,8 +138,6 @@ services:
|
||||
options:
|
||||
max-size: "1g"
|
||||
max-file: "2"
|
||||
environment:
|
||||
CONFIG_NAME: "/Open-IM-Enterprise"
|
||||
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
|
||||
@@ -17,20 +17,20 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/jinzhu/copier v0.3.5
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||
github.com/minio/minio-go/v7 v7.0.22
|
||||
github.com/mitchellh/mapstructure v1.4.2
|
||||
github.com/minio/minio-go/v7 v7.0.59
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.2 // indirect
|
||||
github.com/stretchr/testify v1.8.3
|
||||
github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca
|
||||
go.mongodb.org/mongo-driver v1.8.3
|
||||
golang.org/x/image v0.3.0
|
||||
google.golang.org/api v0.114.0
|
||||
google.golang.org/grpc v1.55.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
google.golang.org/grpc v1.54.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.3.5
|
||||
gorm.io/gorm v1.23.8
|
||||
@@ -39,15 +39,17 @@ require (
|
||||
require github.com/google/uuid v1.3.0
|
||||
|
||||
require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-zookeeper/zk v1.0.3
|
||||
github.com/redis/go-redis/v9 v9.0.5
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.41
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.0 // indirect
|
||||
cloud.google.com/go/compute v1.19.0 // indirect
|
||||
cloud.google.com/go/compute v1.19.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/firestore v1.9.0 // indirect
|
||||
cloud.google.com/go/iam v0.13.0 // indirect
|
||||
@@ -57,9 +59,10 @@ require (
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/eapache/go-resiliency v1.2.0 // indirect
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
|
||||
github.com/eapache/queue v1.1.0 // indirect
|
||||
@@ -70,6 +73,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
@@ -82,17 +86,16 @@ require (
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/cpuid v1.3.1 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.0 // indirect
|
||||
github.com/minio/sha256-simd v0.1.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.4.0 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.18.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
@@ -102,7 +105,7 @@ require (
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rs/xid v1.2.1 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
@@ -113,14 +116,16 @@ require (
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.6.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230626202813-9b080da550b3 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -132,9 +137,9 @@ require (
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/Shopify/sarama => github.com/Shopify/sarama v1.29.0
|
||||
|
||||
@@ -21,8 +21,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
|
||||
cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
|
||||
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
|
||||
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
@@ -51,6 +51,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/OpenIMSDK/open_utils v1.0.8 h1:IopxWgJwEF5ZAPsRuiZZOfcxNOQOCt/p8VDENcHN9r4=
|
||||
github.com/OpenIMSDK/open_utils v1.0.8/go.mod h1:FLoaQblWUVKQgqt2LrNzfSZLT6D3DICBn1kcOMDLUOI=
|
||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||
github.com/Shopify/sarama v1.29.0 h1:ARid8o8oieau9XrHI55f/L3EoRAhm9px6sonbD7yuUE=
|
||||
github.com/Shopify/sarama v1.29.0/go.mod h1:2QpgD79wpdAESqNQMxNc0KYMkycd4slxGdV3TWSVqrU=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
|
||||
@@ -60,6 +61,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible h1:KpbJFXwhVeuxNtBJ74MCGbIoaBok2uZvkD7QXp2+Wis=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -83,6 +86,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583j
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
|
||||
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
@@ -94,8 +99,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dtm-labs/rockscache v0.1.1 h1:6S1vgaHvGqrLd8Ka4hRTKeKPV7v+tT0MSkTIX81LRyA=
|
||||
github.com/dtm-labs/rockscache v0.1.1/go.mod h1:c76WX0kyIibmQ2ACxUXvDvaLykoPakivMqIxt+UzE7A=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
|
||||
@@ -202,6 +207,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
@@ -216,6 +224,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -274,11 +283,10 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
@@ -306,16 +314,15 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v7 v7.0.22 h1:iXhsiRyYh1ozm/+jN2qGgEIahYjEkvcpuu6NcdpSxcA=
|
||||
github.com/minio/minio-go/v7 v7.0.22/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do=
|
||||
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
|
||||
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.59 h1:lxIXwsTIcQkYoEG25rUJbzpmSB/oWeVDmxFo/uWUUsw=
|
||||
github.com/minio/minio-go/v7 v7.0.59/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -324,6 +331,9 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
||||
github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
|
||||
github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
@@ -384,14 +394,14 @@ github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDO
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
|
||||
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -412,6 +422,10 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.41 h1:iU0Li/Np78H4SBna0ECQoF3mpgi6ImLXU+doGzPFXGc=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.41/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw=
|
||||
github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca h1:G/aIr3WiUesWHL2YGYgEqjM5tCAJ43Ml+0C18wDkWWs=
|
||||
github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca/go.mod h1:b18KQa4IxHbxeseW1GcZox53d7J0z39VNONTxvvlkXw=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
@@ -464,8 +478,8 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -538,8 +552,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -547,8 +561,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -612,8 +626,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -626,8 +640,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -739,8 +753,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 h1:x1vNwUhVOcsYoKyEGCZBH694SBmmBjA2EfauFVEI2+M=
|
||||
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a h1:HiYVD+FGJkTo+9zj1gqz0anapsa1JxjiSrN+BJKyUmE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230626202813-9b080da550b3 h1:QJuqz7YzNTyKDspkp2lrzqtq4lf2AhUSpXTsGP5SbLw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230626202813-9b080da550b3/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -754,8 +772,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
|
||||
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -768,8 +786,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -778,8 +796,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
+933
@@ -0,0 +1,933 @@
|
||||
# Copyright © 2023 OpenIMSDK open source community. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 5m
|
||||
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
|
||||
# include test files or not, default is true
|
||||
tests: true
|
||||
|
||||
# list of build tags, all linters use it. Default is empty list.
|
||||
build-tags:
|
||||
- mytag
|
||||
|
||||
# which dirs to skip: issues from them won't be reported;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but default dirs are skipped independently
|
||||
# from this option's value (see skip-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-dirs:
|
||||
- util
|
||||
- .*~
|
||||
- api/swagger/docs
|
||||
- server/docs
|
||||
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
# no need to include all autogenerated files, we confidently recognize
|
||||
# autogenerated files. If it's not please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-files:
|
||||
- ".*\\.my\\.go$"
|
||||
- _test.go
|
||||
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
#modules-download-mode: release|readonly|vendor
|
||||
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false (default) - golangci-lint acquires file lock on start.
|
||||
allow-parallel-runners: true
|
||||
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
|
||||
# add a prefix to the output file references; default is no prefix
|
||||
path-prefix: ""
|
||||
|
||||
# sorts results by: filepath, line and column
|
||||
sort-results: true
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
bidichk:
|
||||
# The following configurations check for all mentioned invisible unicode
|
||||
# runes. It can be omitted because all runes are enabled by default.
|
||||
left-to-right-embedding: true
|
||||
right-to-left-embedding: true
|
||||
pop-directional-formatting: true
|
||||
left-to-right-override: true
|
||||
right-to-left-override: true
|
||||
left-to-right-isolate: true
|
||||
right-to-left-isolate: true
|
||||
first-strong-isolate: true
|
||||
pop-directional-isolate: true
|
||||
dogsled:
|
||||
# checks assignments with too many blank identifiers; default is 2
|
||||
max-blank-identifiers: 2
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
threshold: 100
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
#ignore: GenMarkdownTree,os:.*,BindPFlags,WriteTo,Help
|
||||
#ignore: (os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv
|
||||
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
#exclude: errcheck.txt
|
||||
|
||||
errorlint:
|
||||
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
|
||||
errorf: true
|
||||
# Check for plain type assertions and type switches
|
||||
asserts: true
|
||||
# Check for plain error comparisons
|
||||
comparison: true
|
||||
|
||||
exhaustive:
|
||||
# check switch statements in generated files also
|
||||
check-generated: false
|
||||
# indicates that switch statements are to be considered exhaustive if a
|
||||
# 'default' case is present, even if all enum members aren't listed in the
|
||||
# switch
|
||||
default-signifies-exhaustive: false
|
||||
# enum members matching the supplied regex do not have to be listed in
|
||||
# switch statements to satisfy exhaustiveness
|
||||
ignore-enum-members: ""
|
||||
# consider enums only in package scopes, not in inner scopes
|
||||
package-scope-only: false
|
||||
exhaustivestruct:
|
||||
struct-patterns:
|
||||
- '*.Test'
|
||||
- '*.Test2'
|
||||
- '*.Embedded'
|
||||
- '*.External'
|
||||
|
||||
# forbidigo:
|
||||
# # Forbid the following identifiers (identifiers are written using regexp):
|
||||
# forbid:
|
||||
# - ^print.*$
|
||||
# - 'fmt\.Print.*'
|
||||
# - fmt.Println.* # too much log noise
|
||||
# - ginkgo\\.F.* # these are used just for local development
|
||||
# # Exclude godoc examples from forbidigo checks. Default is true.
|
||||
# exclude_godoc_examples: false
|
||||
funlen:
|
||||
lines: 150
|
||||
statements: 50
|
||||
gci:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# only support one prefix
|
||||
# if not set, use goimports.local-prefixes
|
||||
prefix: github.com/OpenIMSDK/OpenKF
|
||||
gocognit:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 30
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 3
|
||||
# ignore test files, false by default
|
||||
ignore-tests: false
|
||||
# look for existing constants matching the values, true by default
|
||||
match-constant: true
|
||||
# search also for duplicated numbers, false by default
|
||||
numbers: false
|
||||
# minimum value, only works with goconst.numbers, 3 by default
|
||||
min: 3
|
||||
# maximum value, only works with goconst.numbers, 3 by default
|
||||
max: 3
|
||||
# ignore when constant is not used as function argument, true by default
|
||||
ignore-calls: true
|
||||
|
||||
gocritic:
|
||||
# Which checks should be enabled; can't be combined with 'disabled-checks';
|
||||
# See https://go-critic.github.io/overview#checks-overview
|
||||
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
|
||||
# By default list of stable checks is used.
|
||||
enabled-checks:
|
||||
#- rangeValCopy
|
||||
- nestingreduce
|
||||
- truncatecmp
|
||||
- unnamedresult
|
||||
- ruleguard
|
||||
|
||||
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
|
||||
disabled-checks:
|
||||
- regexpMust
|
||||
- ifElseChain
|
||||
#- exitAfterDefer
|
||||
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
enabled-tags:
|
||||
- performance
|
||||
disabled-tags:
|
||||
- experimental
|
||||
|
||||
# Settings passed to gocritic.
|
||||
# The settings key is the name of a supported gocritic checker.
|
||||
# The list of supported checkers can be find in https://go-critic.github.io/overview.
|
||||
settings:
|
||||
captLocal: # must be valid enabled check name
|
||||
# whether to restrict checker to params only (default true)
|
||||
paramsOnly: true
|
||||
elseif:
|
||||
# whether to skip balanced if-else pairs (default true)
|
||||
skipBalanced: true
|
||||
hugeParam:
|
||||
# size in bytes that makes the warning trigger (default 80)
|
||||
sizeThreshold: 80
|
||||
nestingReduce:
|
||||
# min number of statements inside a branch to trigger a warning (default 5)
|
||||
bodyWidth: 5
|
||||
rangeExprCopy:
|
||||
# size in bytes that makes the warning trigger (default 512)
|
||||
sizeThreshold: 512
|
||||
# whether to check test functions (default true)
|
||||
skipTestFuncs: true
|
||||
rangeValCopy:
|
||||
# size in bytes that makes the warning trigger (default 128)
|
||||
sizeThreshold: 32
|
||||
# whether to check test functions (default true)
|
||||
skipTestFuncs: true
|
||||
ruleguard:
|
||||
# path to a gorules file for the ruleguard checker
|
||||
rules: ''
|
||||
truncateCmp:
|
||||
# whether to skip int/uint/uintptr types (default true)
|
||||
skipArchDependent: true
|
||||
underef:
|
||||
# whether to skip (*x).method() calls where x is a pointer receiver (default true)
|
||||
skipRecvDeref: true
|
||||
unnamedResult:
|
||||
# whether to check exported functions
|
||||
checkExported: true
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 30
|
||||
cyclop:
|
||||
# the maximal code complexity to report
|
||||
max-complexity: 50
|
||||
# the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0)
|
||||
package-average: 0.0
|
||||
# should ignore tests (default false)
|
||||
skip-tests: false
|
||||
godot:
|
||||
# comments to be checked: `declarations`, `toplevel`, or `all`
|
||||
scope: declarations
|
||||
# list of regexps for excluding particular comment lines from check
|
||||
exclude:
|
||||
# example: exclude comments which contain numbers
|
||||
# - '[0-9]+'
|
||||
# check that each sentence starts with a capital letter
|
||||
capital: false
|
||||
godox:
|
||||
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
|
||||
# might be left in the code accidentally and should be resolved before merging
|
||||
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
|
||||
#- TODO
|
||||
- BUG
|
||||
- FIXME
|
||||
#- NOTE
|
||||
- OPTIMIZE # marks code that should be optimized before merging
|
||||
- HACK # marks hack-arounds that should be removed before merging
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
|
||||
gofumpt:
|
||||
# Select the Go version to target. The default is `1.18`.
|
||||
lang-version: "1.20"
|
||||
|
||||
# Choose whether or not to use the extra rules that are disabled
|
||||
# by default
|
||||
extra-rules: false
|
||||
|
||||
goheader:
|
||||
values:
|
||||
const:
|
||||
# define here const type values in format k:v, for example:
|
||||
# COMPANY: MY COMPANY
|
||||
regexp:
|
||||
# define here regexp type values, for example
|
||||
# AUTHOR: .*@mycompany\.com
|
||||
template: # |-
|
||||
# put here copyright header template for source code files, for example:
|
||||
# Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
|
||||
#
|
||||
# {{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
template-path:
|
||||
# also as alternative of directive 'template' you may put the path to file with the template source
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/OpenIMSDK/OpenKF
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.9
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
|
||||
checks: argument,case,condition,operation,return,assign
|
||||
# ignored-numbers: 1000
|
||||
# ignored-files: magic_.*.go
|
||||
# ignored-functions: math.*
|
||||
gomoddirectives:
|
||||
# Allow local `replace` directives. Default is false.
|
||||
replace-local: true
|
||||
# List of allowed `replace` directives. Default is empty.
|
||||
replace-allow-list:
|
||||
- google.golang.org/grpc
|
||||
|
||||
# Allow to not explain why the version has been retracted in the `retract` directives. Default is false.
|
||||
retract-allow-no-explanation: false
|
||||
# Forbid the use of the `exclude` directives. Default is false.
|
||||
exclude-forbidden: false
|
||||
gomodguard:
|
||||
allowed:
|
||||
modules: # List of allowed modules
|
||||
- gorm.io/gorm
|
||||
- gorm.io/driver/mysql
|
||||
- k8s.io/klog
|
||||
# - gopkg.in/yaml.v2
|
||||
domains: # List of allowed module domains
|
||||
- google.golang.org
|
||||
- gopkg.in
|
||||
- golang.org
|
||||
- github.com
|
||||
- go.uber.org
|
||||
- go.etcd.io
|
||||
blocked:
|
||||
versions:
|
||||
- github.com/MakeNowJust/heredoc:
|
||||
version: "> 2.0.9"
|
||||
reason: "use the latest version"
|
||||
local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive
|
||||
|
||||
gosec:
|
||||
# To select a subset of rules to run.
|
||||
# Available rules: https://github.com/securego/gosec#available-rules
|
||||
includes:
|
||||
- G401
|
||||
- G306
|
||||
- G101
|
||||
# To specify a set of rules to explicitly exclude.
|
||||
# Available rules: https://github.com/securego/gosec#available-rules
|
||||
excludes:
|
||||
- G204
|
||||
# Exclude generated files
|
||||
exclude-generated: true
|
||||
# Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high.
|
||||
severity: "low"
|
||||
# Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high.
|
||||
confidence: "low"
|
||||
# To specify the configuration of rules.
|
||||
# The configuration of rules is not fully documented by gosec:
|
||||
# https://github.com/securego/gosec#configuration
|
||||
# https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102
|
||||
config:
|
||||
G306: "0600"
|
||||
G101:
|
||||
pattern: "(?i)example"
|
||||
ignore_entropy: false
|
||||
entropy_threshold: "80.0"
|
||||
per_char_threshold: "3.0"
|
||||
truncate: "32"
|
||||
|
||||
gosimple:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.20"
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all" ]
|
||||
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
|
||||
# settings per analyzer
|
||||
settings:
|
||||
printf: # analyzer name, run `go tool vet help` to see all analyzers
|
||||
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
|
||||
|
||||
# enable or disable analyzers by name
|
||||
enable:
|
||||
- atomicalign
|
||||
enable-all: false
|
||||
disable:
|
||||
- shadow
|
||||
disable-all: false
|
||||
# depguard:
|
||||
# list-type: blacklist
|
||||
# include-go-root: false
|
||||
# packages:
|
||||
# - github.com/Sirupsen/logrus
|
||||
# packages-with-error-message:
|
||||
# # specify an error message to output when a blacklisted package is used
|
||||
# - github.com/Sirupsen/logrus: "logging is allowed only by logutils.Log"
|
||||
ifshort:
|
||||
# Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax.
|
||||
# Has higher priority than max-decl-chars.
|
||||
max-decl-lines: 1
|
||||
# Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.
|
||||
max-decl-chars: 30
|
||||
|
||||
importas:
|
||||
# if set to `true`, force to use alias.
|
||||
no-unaliased: true
|
||||
# List of aliases
|
||||
alias:
|
||||
# using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package
|
||||
- pkg: knative.dev/serving/pkg/apis/serving/v1
|
||||
alias: servingv1
|
||||
# using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package
|
||||
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
|
||||
alias: autoscalingv1alpha1
|
||||
# You can specify the package path by regular expression,
|
||||
# and alias by regular expression expansion syntax like below.
|
||||
# see https://github.com/julz/importas#use-regular-expression for details
|
||||
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
|
||||
alias: $1$2
|
||||
# using `jwt` alias for `github.com/appleboy/gin-jwt/v2` package
|
||||
jwt: github.com/appleboy/gin-jwt/v2
|
||||
|
||||
ireturn:
|
||||
# ireturn allows using `allow` and `reject` settings at the same time.
|
||||
# Both settings are lists of the keywords and regular expressions matched to interface or package names.
|
||||
# keywords:
|
||||
# - `empty` for `interface{}`
|
||||
# - `error` for errors
|
||||
# - `stdlib` for standard library
|
||||
# - `anon` for anonymous interfaces
|
||||
|
||||
# By default, it allows using errors, empty interfaces, anonymous interfaces,
|
||||
# and interfaces provided by the standard library.
|
||||
allow:
|
||||
- anon
|
||||
- error
|
||||
- empty
|
||||
- stdlib
|
||||
# You can specify idiomatic endings for interface
|
||||
- (or|er)$
|
||||
|
||||
# Reject patterns
|
||||
reject:
|
||||
- github.com\/user\/package\/v4\.Type
|
||||
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 240
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 4
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||
locale: US
|
||||
ignore-words:
|
||||
- someword
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
|
||||
nilnil:
|
||||
# By default, nilnil checks all returned types below.
|
||||
checked-types:
|
||||
- ptr
|
||||
- func
|
||||
- iface
|
||||
- map
|
||||
- chan
|
||||
|
||||
nlreturn:
|
||||
# size of the block (including return statement that is still "OK")
|
||||
# so no return split required.
|
||||
block-size: 1
|
||||
|
||||
nolintlint:
|
||||
# Disable to ensure that all nolint directives actually have an effect. Default is true.
|
||||
allow-unused: false
|
||||
# Disable to ensure that nolint directives don't have a leading space. Default is true.
|
||||
allow-leading-space: true
|
||||
# Exclude following linters from requiring an explanation. Default is [].
|
||||
allow-no-explanation: [ ]
|
||||
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
|
||||
require-explanation: false
|
||||
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
|
||||
require-specific: true
|
||||
|
||||
prealloc:
|
||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||
# For most programs usage of prealloc will be a premature optimization.
|
||||
|
||||
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||
# True by default.
|
||||
simple: true
|
||||
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||
for-loops: false # Report preallocation suggestions on for loops, false by default
|
||||
|
||||
promlinter:
|
||||
# Promlinter cannot infer all metrics name in static analysis.
|
||||
# Enable strict mode will also include the errors caused by failing to parse the args.
|
||||
strict: false
|
||||
# Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
|
||||
disabled-linters:
|
||||
# - "Help"
|
||||
# - "MetricUnits"
|
||||
# - "Counter"
|
||||
# - "HistogramSummaryReserved"
|
||||
# - "MetricTypeInName"
|
||||
# - "ReservedChars"
|
||||
# - "CamelCase"
|
||||
# - "lintUnitAbbreviations"
|
||||
|
||||
predeclared:
|
||||
# comma-separated list of predeclared identifiers to not report on
|
||||
ignore: ""
|
||||
# include method names and field names (i.e., qualified names) in checks
|
||||
q: false
|
||||
rowserrcheck:
|
||||
packages:
|
||||
- github.com/jmoiron/sqlx
|
||||
revive:
|
||||
# see https://github.com/mgechev/revive#available-rules for details.
|
||||
ignore-generated-header: true
|
||||
severity: warning
|
||||
rules:
|
||||
- name: indent-error-flow
|
||||
severity: warning
|
||||
staticcheck:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.16"
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all" ]
|
||||
|
||||
stylecheck:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.16"
|
||||
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
|
||||
# https://staticcheck.io/docs/options#dot_import_whitelist
|
||||
dot-import-whitelist:
|
||||
- fmt
|
||||
# https://staticcheck.io/docs/options#initialisms
|
||||
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
|
||||
# https://staticcheck.io/docs/options#http_status_code_whitelist
|
||||
http-status-code-whitelist: [ "200", "400", "404", "500" ]
|
||||
|
||||
|
||||
tagliatelle:
|
||||
# check the struck tag name case
|
||||
case:
|
||||
# use the struct field name to check the name of the struct tag
|
||||
use-field-name: true
|
||||
rules:
|
||||
# any struct tag type can be used.
|
||||
# support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`
|
||||
json: camel
|
||||
yaml: camel
|
||||
xml: camel
|
||||
bson: camel
|
||||
avro: snake
|
||||
mapstructure: kebab
|
||||
|
||||
testpackage:
|
||||
# regexp pattern to skip files
|
||||
skip-regexp: (id|export|internal)_test\.go
|
||||
thelper:
|
||||
# The following configurations enable all checks. It can be omitted because all checks are enabled by default.
|
||||
# You can enable only required checks deleting unnecessary checks.
|
||||
test:
|
||||
first: true
|
||||
name: true
|
||||
begin: true
|
||||
benchmark:
|
||||
first: true
|
||||
name: true
|
||||
begin: true
|
||||
tb:
|
||||
first: true
|
||||
name: true
|
||||
begin: true
|
||||
|
||||
tenv:
|
||||
# The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
|
||||
# By default, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
|
||||
all: false
|
||||
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
|
||||
wrapcheck:
|
||||
# An array of strings that specify substrings of signatures to ignore.
|
||||
# If this set, it will override the default set of ignored signatures.
|
||||
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
|
||||
ignoreSigs:
|
||||
- .Errorf(
|
||||
- errors.New(
|
||||
- errors.Unwrap(
|
||||
- .Wrap(
|
||||
- .Wrapf(
|
||||
- .WithMessage(
|
||||
- .WithMessagef(
|
||||
- .WithStack(
|
||||
ignorePackageGlobs:
|
||||
- encoding/*
|
||||
- github.com/pkg/*
|
||||
|
||||
wsl:
|
||||
# If true append is only allowed to be cuddled if appending value is
|
||||
# matching variables, fields or types on line above. Default is true.
|
||||
strict-append: true
|
||||
# Allow calls and assignments to be cuddled as long as the lines have any
|
||||
# matching variables, fields or types. Default is true.
|
||||
allow-assign-and-call: true
|
||||
# Allow assignments to be cuddled with anything. Default is false.
|
||||
allow-assign-and-anything: false
|
||||
# Allow multiline assignments to be cuddled. Default is true.
|
||||
allow-multiline-assign: true
|
||||
# Allow declarations (var) to be cuddled.
|
||||
allow-cuddle-declarations: false
|
||||
# Allow trailing comments in ending of blocks
|
||||
allow-trailing-comment: false
|
||||
# Force newlines in end of case at this limit (0 = never).
|
||||
force-case-trailing-whitespace: 0
|
||||
# Force cuddling of err checks with err var assignment
|
||||
force-err-cuddling: false
|
||||
# Allow leading comments to be separated with empty liens
|
||||
allow-separated-leading-comment: false
|
||||
makezero:
|
||||
# Allow only slices initialized with a length of zero. Default is false.
|
||||
always: false
|
||||
|
||||
|
||||
# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
|
||||
# for more info.
|
||||
#custom:
|
||||
# Each custom linter should have a unique name.
|
||||
#example:
|
||||
# The path to the plugin *.so. Can be absolute or local. Required for each custom linter
|
||||
#path: /path/to/example.so
|
||||
# The description of the linter. Optional, just for documentation purposes.
|
||||
#description: This is an example usage of a plugin linter.
|
||||
# Intended to point to the repo location of the linter. Optional, just for documentation purposes.
|
||||
#original-url: github.com/golangci/example-linter
|
||||
|
||||
linters:
|
||||
# please, do not use `enable-all`: it's deprecated and will be removed soon.
|
||||
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
|
||||
# enable-all: true
|
||||
disable-all: true
|
||||
enable:
|
||||
- typecheck
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
- cyclop
|
||||
- deadcode
|
||||
# - depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errorlint
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
# - forbidigo
|
||||
- funlen
|
||||
# - gci
|
||||
# - gochecknoinits
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocyclo
|
||||
- godot
|
||||
- godox
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goheader
|
||||
- goimports
|
||||
- gomoddirectives
|
||||
- gomodguard
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ifshort
|
||||
- importas
|
||||
- ineffassign
|
||||
- lll
|
||||
- makezero
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- nlreturn
|
||||
- noctx
|
||||
- nolintlint
|
||||
- paralleltest
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- thelper
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- wastedassign
|
||||
- whitespace
|
||||
- bidichk
|
||||
- wastedassign
|
||||
- golint
|
||||
- execinquery
|
||||
- nosprintfhostport
|
||||
- grouper
|
||||
- decorder
|
||||
- errchkjson
|
||||
- maintidx
|
||||
#- containedctx
|
||||
#- tagliatelle
|
||||
#- nonamedreturns
|
||||
#- nilnil
|
||||
#- tenv
|
||||
#- varnamelen
|
||||
#- contextcheck
|
||||
#- errname
|
||||
#- ForceTypeAssert
|
||||
#- nilassign
|
||||
fast: false
|
||||
|
||||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
exclude:
|
||||
- tools/.*
|
||||
- test/.*
|
||||
- third_party/.*
|
||||
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- golint
|
||||
path: (internal/api/.*)\.go # exclude golint for internal/api/... files
|
||||
|
||||
- linters:
|
||||
- revive
|
||||
path: (log/.*)\.go
|
||||
|
||||
- linters:
|
||||
- wrapcheck
|
||||
path: (cmd/.*|pkg/.*)\.go
|
||||
|
||||
- linters:
|
||||
- typecheck
|
||||
#path: (pkg/storage/.*)\.go
|
||||
path: (internal/.*|pkg/.*)\.go
|
||||
|
||||
- path: (cmd/.*|test/.*|tools/.*|internal/pump/pumps/.*)\.go
|
||||
linters:
|
||||
- forbidigo
|
||||
|
||||
- path: (cmd/[a-z]*/.*|store/.*)\.go
|
||||
linters:
|
||||
- dupl
|
||||
|
||||
- linters:
|
||||
- gocritic
|
||||
text: (hugeParam:|rangeValCopy:)
|
||||
|
||||
- path: (cmd/[a-z]*/.*)\.go
|
||||
linters:
|
||||
- lll
|
||||
|
||||
- path: (validator/.*|code/.*|validator/.*|watcher/watcher/.*)
|
||||
linters:
|
||||
- gochecknoinits
|
||||
|
||||
- path: (internal/.*/options|internal/pump|pkg/log/options.go|internal/authzserver|tools/)
|
||||
linters:
|
||||
- tagliatelle
|
||||
|
||||
- path: (pkg/app/.*)\.go
|
||||
linters:
|
||||
- deadcode
|
||||
- unused
|
||||
- varcheck
|
||||
- forbidigo
|
||||
|
||||
# Exclude some staticcheck messages
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA9003:"
|
||||
|
||||
# Exclude lll issues for long lines with go:generate
|
||||
- linters:
|
||||
- lll
|
||||
source: "^//go:generate "
|
||||
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: true
|
||||
|
||||
# The default value is false. If set to true exclude and exclude-rules
|
||||
# regular expressions become case sensitive.
|
||||
exclude-case-sensitive: false
|
||||
|
||||
# The list of ids of default excludes to include or disable. By default it's empty.
|
||||
include:
|
||||
- EXC0002 # disable excluding of issues about comments from golint
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
|
||||
# Show only new issues created after git revision `REV`
|
||||
# new-from-rev: REV
|
||||
|
||||
# Show only new issues created in git patch with set file path.
|
||||
#new-from-patch: path/to/patch/file
|
||||
|
||||
# Fix found issues (if it's supported by the linter)
|
||||
fix: true
|
||||
|
||||
severity:
|
||||
# Default value is empty string.
|
||||
# Set the default severity for issues. If severity rules are defined and the issues
|
||||
# do not match or no severity is provided to the rule this will be the default
|
||||
# severity applied. Severities should match the supported severity names of the
|
||||
# selected out format.
|
||||
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
|
||||
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
||||
default-severity: error
|
||||
|
||||
# The default value is false.
|
||||
# If set to true severity-rules regular expressions become case sensitive.
|
||||
case-sensitive: false
|
||||
|
||||
# Default value is empty list.
|
||||
# When a list of severity rules are provided, severity information will be added to lint
|
||||
# issues. Severity rules have the same filtering capability as exclude rules except you
|
||||
# are allowed to specify one matcher per severity rule.
|
||||
# Only affects out formats that support setting severity information.
|
||||
rules:
|
||||
- linters:
|
||||
- dupl
|
||||
severity: info
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd script ;
|
||||
cd scripts ;
|
||||
chmod +x *.sh ;
|
||||
./env_check.sh;
|
||||
cd .. ;
|
||||
docker-compose up -d;
|
||||
cd script ;
|
||||
cd scripts ;
|
||||
./docker_check_service.sh
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Welcome to the Open-IM-Server installation script."
|
||||
echo "Welcome to the Open-IM-Server installation scripts."
|
||||
echo "Please select an deploy option:"
|
||||
echo "1. docker-compose install"
|
||||
echo "2. exit"
|
||||
@@ -145,13 +145,13 @@ EOF
|
||||
edit_config
|
||||
edit_enterprise_config
|
||||
|
||||
cd script;
|
||||
cd scripts;
|
||||
chmod +x *.sh;
|
||||
./init_pwd.sh;
|
||||
./env_check.sh;
|
||||
cd ..;
|
||||
docker-compose up -d;
|
||||
cd script;
|
||||
cd scripts;
|
||||
./docker_check_service.sh;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ case $choice in
|
||||
3)
|
||||
;;
|
||||
4)
|
||||
echo "Exiting installation script..."
|
||||
echo "Exiting installation scripts..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -9,7 +9,7 @@ if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then
|
||||
|
||||
fi
|
||||
|
||||
cd script ;
|
||||
cd scripts ;
|
||||
chmod +x *.sh ;
|
||||
./init_pwd.sh
|
||||
./env_check.sh;
|
||||
|
||||
+11
-3
@@ -9,11 +9,19 @@ if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then
|
||||
|
||||
fi
|
||||
|
||||
cd script ;
|
||||
cd scripts ;
|
||||
chmod +x *.sh ;
|
||||
./init_pwd.sh
|
||||
./env_check.sh;
|
||||
cd .. ;
|
||||
docker-compose up -d;
|
||||
cd script ;
|
||||
|
||||
if command -v docker-compose &> /dev/null
|
||||
then
|
||||
docker-compose up -d ;
|
||||
else
|
||||
docker compose up -d ;
|
||||
fi
|
||||
|
||||
|
||||
cd scripts ;
|
||||
./docker_check_service.sh
|
||||
|
||||
@@ -26,24 +26,6 @@ func (o *ConversationApi) GetConversations(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.GetConversations, o.Client, c)
|
||||
}
|
||||
|
||||
// deprecated
|
||||
func (o *ConversationApi) SetConversation(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.SetConversation, o.Client, c)
|
||||
}
|
||||
|
||||
// deprecated
|
||||
func (o *ConversationApi) BatchSetConversations(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.BatchSetConversations, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ConversationApi) SetRecvMsgOpt(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.SetRecvMsgOpt, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ConversationApi) ModifyConversationField(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.ModifyConversationField, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ConversationApi) SetConversations(c *gin.Context) {
|
||||
a2r.Call(conversation.ConversationClient.SetConversations, o.Client, c)
|
||||
}
|
||||
|
||||
@@ -114,3 +114,7 @@ func (o *GroupApi) GetJoinedSuperGroupList(c *gin.Context) {
|
||||
func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) {
|
||||
a2r.Call(group.GroupClient.GetSuperGroupsInfo, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *GroupApi) GroupCreateCount(c *gin.Context) {
|
||||
a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c)
|
||||
}
|
||||
|
||||
+13
-21
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
@@ -147,33 +148,16 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.DeleteMsgPhysical, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) SetMessageReactionExtensions(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.SetMessageReactionExtensions, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) GetMessageListReactionExtensions(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetMessagesReactionExtensions, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) AddMessageReactionExtensions(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.AddMessageReactionExtensions, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) DeleteMessageReactionExtensions(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.DeleteMessageReactionExtensions, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) SendMessage(c *gin.Context) {
|
||||
params := apistruct.ManagementSendMsgReq{}
|
||||
if err := c.BindJSON(¶ms); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
// todo
|
||||
//if !tokenverify.IsAppManagerUid(c) {
|
||||
// apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||
// return
|
||||
//}
|
||||
if !tokenverify.IsAppManagerUid(c) {
|
||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||
return
|
||||
}
|
||||
|
||||
var data interface{}
|
||||
switch params.ContentType {
|
||||
@@ -238,3 +222,11 @@ func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
|
||||
func (m *MessageApi) GetUsersOnlineStatus(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetSendMsgStatus, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) GetActiveUser(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetActiveUser, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) GetActiveGroup(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetActiveGroup, m.Client, c)
|
||||
}
|
||||
|
||||
+64
-85
@@ -19,15 +19,14 @@ import (
|
||||
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
|
||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) // 默认RPC中间件
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
//f, _ := os.Create("../logs/api.log")
|
||||
//gin.DefaultWriter = io.MultiWriter(f)
|
||||
//gin.SetMode(gin.DebugMode)
|
||||
r := gin.New()
|
||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||
_ = v.RegisterValidation("required_if", RequiredIf)
|
||||
}
|
||||
log.ZInfo(context.Background(), "load config", "config", config.Config)
|
||||
r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
|
||||
u := NewUserApi(discov)
|
||||
m := NewMessageApi(discov)
|
||||
if config.Config.Prometheus.Enable {
|
||||
prome.NewApiRequestCounter()
|
||||
prome.NewApiRequestFailedCounter()
|
||||
@@ -35,105 +34,94 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
||||
r.Use(prome.PrometheusMiddleware)
|
||||
r.GET("/metrics", prome.PrometheusHandler())
|
||||
}
|
||||
ParseToken := mw.GinParseToken(rdb)
|
||||
userRouterGroup := r.Group("/user")
|
||||
{
|
||||
u := NewUserApi(discov)
|
||||
userRouterGroupChild := mw.NewRouterGroup(userRouterGroup, "")
|
||||
userRouterGroupChildToken := mw.NewRouterGroup(userRouterGroup, "", mw.WithGinParseToken(rdb))
|
||||
userRouterGroupChild.POST("/user_register", u.UserRegister)
|
||||
userRouterGroupChildToken.POST("/update_user_info", u.UpdateUserInfo) //1
|
||||
userRouterGroupChildToken.POST("/set_global_msg_recv_opt", u.SetGlobalRecvMessageOpt)
|
||||
userRouterGroupChildToken.POST("/get_users_info", u.GetUsersPublicInfo) //1
|
||||
userRouterGroupChildToken.POST("/get_all_users_uid", u.GetAllUsersID) // todo
|
||||
userRouterGroupChildToken.POST("/account_check", u.AccountCheck) // todo
|
||||
userRouterGroupChildToken.POST("/get_users", u.GetUsers)
|
||||
userRouterGroupChildToken.POST("/get_users_online_status", u.GetUsersOnlineStatus)
|
||||
userRouterGroup.POST("/user_register", u.UserRegister)
|
||||
userRouterGroup.POST("/update_user_info", ParseToken, u.UpdateUserInfo)
|
||||
userRouterGroup.POST("/set_global_msg_recv_opt", ParseToken, u.SetGlobalRecvMessageOpt)
|
||||
userRouterGroup.POST("/get_users_info", ParseToken, u.GetUsersPublicInfo)
|
||||
userRouterGroup.POST("/get_all_users_uid", ParseToken, u.GetAllUsersID)
|
||||
userRouterGroup.POST("/account_check", ParseToken, u.AccountCheck)
|
||||
userRouterGroup.POST("/get_users", ParseToken, u.GetUsers)
|
||||
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
|
||||
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
||||
}
|
||||
//friend routing group
|
||||
friendRouterGroup := r.Group("/friend")
|
||||
friendRouterGroup := r.Group("/friend", ParseToken)
|
||||
{
|
||||
f := NewFriendApi(discov)
|
||||
friendRouterGroup.Use(mw.GinParseToken(rdb))
|
||||
friendRouterGroup.POST("/delete_friend", f.DeleteFriend) //1
|
||||
friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList) //1
|
||||
friendRouterGroup.POST("/get_self_friend_apply_list", f.GetSelfApplyList) //1
|
||||
friendRouterGroup.POST("/get_friend_list", f.GetFriendList) //1
|
||||
friendRouterGroup.POST("/add_friend", f.ApplyToAddFriend) //1
|
||||
friendRouterGroup.POST("/add_friend_response", f.RespondFriendApply) //1
|
||||
friendRouterGroup.POST("/set_friend_remark", f.SetFriendRemark) //1
|
||||
friendRouterGroup.POST("/add_black", f.AddBlack) //1
|
||||
friendRouterGroup.POST("/get_black_list", f.GetPaginationBlacks) //1
|
||||
friendRouterGroup.POST("/remove_black", f.RemoveBlack) //1
|
||||
friendRouterGroup.POST("/import_friend", f.ImportFriends) //1
|
||||
friendRouterGroup.POST("/is_friend", f.IsFriend) //1
|
||||
friendRouterGroup.POST("/delete_friend", f.DeleteFriend)
|
||||
friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList)
|
||||
friendRouterGroup.POST("/get_self_friend_apply_list", f.GetSelfApplyList)
|
||||
friendRouterGroup.POST("/get_friend_list", f.GetFriendList)
|
||||
friendRouterGroup.POST("/add_friend", f.ApplyToAddFriend)
|
||||
friendRouterGroup.POST("/add_friend_response", f.RespondFriendApply)
|
||||
friendRouterGroup.POST("/set_friend_remark", f.SetFriendRemark)
|
||||
friendRouterGroup.POST("/add_black", f.AddBlack)
|
||||
friendRouterGroup.POST("/get_black_list", f.GetPaginationBlacks)
|
||||
friendRouterGroup.POST("/remove_black", f.RemoveBlack)
|
||||
friendRouterGroup.POST("/import_friend", f.ImportFriends)
|
||||
friendRouterGroup.POST("/is_friend", f.IsFriend)
|
||||
}
|
||||
g := NewGroupApi(discov)
|
||||
groupRouterGroup := r.Group("/group")
|
||||
groupRouterGroup := r.Group("/group", ParseToken)
|
||||
{
|
||||
|
||||
groupRouterGroup.Use(mw.GinParseToken(rdb))
|
||||
groupRouterGroup.POST("/create_group", g.CreateGroup) //1
|
||||
groupRouterGroup.POST("/set_group_info", g.SetGroupInfo) //1
|
||||
groupRouterGroup.POST("/join_group", g.JoinGroup) //1
|
||||
groupRouterGroup.POST("/quit_group", g.QuitGroup) //1
|
||||
groupRouterGroup.POST("/group_application_response", g.ApplicationGroupResponse) //1
|
||||
groupRouterGroup.POST("/transfer_group", g.TransferGroupOwner) //1
|
||||
groupRouterGroup.POST("/get_recv_group_applicationList", g.GetRecvGroupApplicationList) //1
|
||||
groupRouterGroup.POST("/create_group", g.CreateGroup)
|
||||
groupRouterGroup.POST("/set_group_info", g.SetGroupInfo)
|
||||
groupRouterGroup.POST("/join_group", g.JoinGroup)
|
||||
groupRouterGroup.POST("/quit_group", g.QuitGroup)
|
||||
groupRouterGroup.POST("/group_application_response", g.ApplicationGroupResponse)
|
||||
groupRouterGroup.POST("/transfer_group", g.TransferGroupOwner)
|
||||
groupRouterGroup.POST("/get_recv_group_applicationList", g.GetRecvGroupApplicationList)
|
||||
groupRouterGroup.POST("/get_user_req_group_applicationList", g.GetUserReqGroupApplicationList)
|
||||
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo) //1
|
||||
groupRouterGroup.POST("/kick_group", g.KickGroupMember) //1
|
||||
// groupRouterGroup.POST("/get_group_all_member_list", g.GetGroupAllMemberList) //1
|
||||
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo) //1
|
||||
groupRouterGroup.POST("/get_group_member_list", g.GetGroupMemberList) //1
|
||||
groupRouterGroup.POST("/invite_user_to_group", g.InviteUserToGroup) //1
|
||||
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo)
|
||||
groupRouterGroup.POST("/kick_group", g.KickGroupMember)
|
||||
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo)
|
||||
groupRouterGroup.POST("/get_group_member_list", g.GetGroupMemberList)
|
||||
groupRouterGroup.POST("/invite_user_to_group", g.InviteUserToGroup)
|
||||
groupRouterGroup.POST("/get_joined_group_list", g.GetJoinedGroupList)
|
||||
groupRouterGroup.POST("/dismiss_group", g.DismissGroup) //
|
||||
groupRouterGroup.POST("/mute_group_member", g.MuteGroupMember)
|
||||
groupRouterGroup.POST("/cancel_mute_group_member", g.CancelMuteGroupMember) //MuteGroup
|
||||
groupRouterGroup.POST("/cancel_mute_group_member", g.CancelMuteGroupMember)
|
||||
groupRouterGroup.POST("/mute_group", g.MuteGroup)
|
||||
groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup)
|
||||
//groupRouterGroup.POST("/set_group_member_nickname", g.SetGroupMemberNickname)
|
||||
groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo)
|
||||
groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo)
|
||||
}
|
||||
superGroupRouterGroup := r.Group("/super_group")
|
||||
superGroupRouterGroup := r.Group("/super_group", ParseToken)
|
||||
{
|
||||
superGroupRouterGroup.Use(mw.GinParseToken(rdb))
|
||||
superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList)
|
||||
superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo)
|
||||
}
|
||||
////certificate
|
||||
//certificate
|
||||
authRouterGroup := r.Group("/auth")
|
||||
{
|
||||
a := NewAuthApi(discov)
|
||||
u := NewUserApi(discov)
|
||||
authRouterGroupChild := mw.NewRouterGroup(authRouterGroup, "")
|
||||
authRouterGroupChildToken := mw.NewRouterGroup(authRouterGroup, "", mw.WithGinParseToken(rdb))
|
||||
authRouterGroupChild.POST("/user_register", u.UserRegister) //1
|
||||
authRouterGroupChild.POST("/user_token", a.UserToken) //1
|
||||
authRouterGroupChildToken.POST("/parse_token", a.ParseToken) //1
|
||||
authRouterGroupChildToken.POST("/force_logout", a.ForceLogout) //1
|
||||
authRouterGroup.POST("/user_token", a.UserToken)
|
||||
authRouterGroup.POST("/parse_token", a.ParseToken)
|
||||
authRouterGroup.POST("/force_logout", ParseToken, a.ForceLogout)
|
||||
}
|
||||
////Third service
|
||||
thirdGroup := r.Group("/third")
|
||||
//Third service
|
||||
thirdGroup := r.Group("/third", ParseToken)
|
||||
{
|
||||
t := NewThirdApi(discov)
|
||||
thirdGroup.Use(mw.GinParseToken(rdb))
|
||||
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
|
||||
thirdGroup.POST("/set_app_badge", t.SetAppBadge)
|
||||
|
||||
thirdGroup.POST("/apply_put", t.ApplyPut)
|
||||
thirdGroup.POST("/get_put", t.GetPut)
|
||||
thirdGroup.POST("/confirm_put", t.ConfirmPut)
|
||||
thirdGroup.POST("/get_hash", t.GetHash)
|
||||
thirdGroup.POST("/object", t.GetURL)
|
||||
thirdGroup.GET("/object", t.GetURL)
|
||||
objectGroup := r.Group("/object", ParseToken)
|
||||
|
||||
objectGroup.POST("/part_limit", t.PartLimit)
|
||||
objectGroup.POST("/part_size", t.PartSize)
|
||||
objectGroup.POST("/initiate_multipart_upload", t.InitiateMultipartUpload)
|
||||
objectGroup.POST("/auth_sign", t.AuthSign)
|
||||
objectGroup.POST("/complete_multipart_upload", t.CompleteMultipartUpload)
|
||||
objectGroup.POST("/access_url", t.AccessURL)
|
||||
objectGroup.GET("/*name", t.ObjectRedirect)
|
||||
}
|
||||
////Message
|
||||
msgGroup := r.Group("/msg")
|
||||
//Message
|
||||
msgGroup := r.Group("/msg", ParseToken)
|
||||
{
|
||||
m := NewMessageApi(discov)
|
||||
msgGroup.Use(mw.GinParseToken(rdb))
|
||||
msgGroup.POST("/newest_seq", m.GetSeq)
|
||||
msgGroup.POST("/send_msg", m.SendMessage)
|
||||
msgGroup.POST("/pull_msg_by_seq", m.PullMsgBySeqs)
|
||||
@@ -151,32 +139,23 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
||||
|
||||
msgGroup.POST("/batch_send_msg", m.ManagementBatchSendMsg)
|
||||
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
|
||||
|
||||
//msgGroup.POST("/set_message_reaction_extensions", msg.SetMessageReactionExtensions)
|
||||
//msgGroup.POST("/get_message_list_reaction_extensions", msg.GetMessageListReactionExtensions)
|
||||
//msgGroup.POST("/add_message_reaction_extensions", msg.AddMessageReactionExtensions)
|
||||
//msgGroup.POST("/delete_message_reaction_extensions", msg.DeleteMessageReactionExtensions)
|
||||
}
|
||||
////Conversation
|
||||
conversationGroup := r.Group("/conversation")
|
||||
//Conversation
|
||||
conversationGroup := r.Group("/conversation", ParseToken)
|
||||
{
|
||||
c := NewConversationApi(discov)
|
||||
conversationGroup.Use(mw.GinParseToken(rdb))
|
||||
conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
|
||||
conversationGroup.POST("/get_conversation", c.GetConversation)
|
||||
conversationGroup.POST("/get_conversations", c.GetConversations)
|
||||
conversationGroup.POST("/set_conversation", c.SetConversation)
|
||||
conversationGroup.POST("/batch_set_conversation", c.BatchSetConversations)
|
||||
conversationGroup.POST("/set_recv_msg_opt", c.SetRecvMsgOpt)
|
||||
conversationGroup.POST("/modify_conversation_field", c.ModifyConversationField)
|
||||
conversationGroup.POST("/set_conversations", c.SetConversations)
|
||||
}
|
||||
|
||||
statisticsGroup := r.Group("/statistics")
|
||||
statisticsGroup := r.Group("/statistics", ParseToken)
|
||||
{
|
||||
s := NewStatisticsApi(discov)
|
||||
conversationGroup.Use(mw.GinParseToken(rdb))
|
||||
statisticsGroup.POST("/user_register", s.UserRegister)
|
||||
statisticsGroup.POST("/user/register", u.UserRegisterCount)
|
||||
statisticsGroup.POST("/user/active", m.GetActiveUser)
|
||||
statisticsGroup.POST("/group/create", g.GroupCreateCount)
|
||||
statisticsGroup.POST("/group/active", m.GetActiveGroup)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
+37
-35
@@ -1,18 +1,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
"github.com/gin-gonic/gin"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ThirdApi rpcclient.Third
|
||||
@@ -21,22 +19,6 @@ func NewThirdApi(discov discoveryregistry.SvcDiscoveryRegistry) ThirdApi {
|
||||
return ThirdApi(*rpcclient.NewThird(discov))
|
||||
}
|
||||
|
||||
func (o *ThirdApi) ApplyPut(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.ApplyPut, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) GetPut(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.GetPut, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) ConfirmPut(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.ConfirmPut, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) GetHash(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.GetHashInfo, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) FcmUpdateToken(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.FcmUpdateToken, o.Client, c)
|
||||
}
|
||||
@@ -45,27 +27,47 @@ func (o *ThirdApi) SetAppBadge(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.SetAppBadge, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) GetURL(c *gin.Context) {
|
||||
if c.Request.Method == http.MethodPost {
|
||||
a2r.Call(third.ThirdClient.GetUrl, o.Client, c)
|
||||
return
|
||||
}
|
||||
name := c.Query("name")
|
||||
// #################### s3 ####################
|
||||
|
||||
func (o *ThirdApi) PartLimit(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.PartLimit, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) PartSize(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.PartSize, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) InitiateMultipartUpload(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.InitiateMultipartUpload, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) AuthSign(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.AuthSign, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) CompleteMultipartUpload(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.CompleteMultipartUpload, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) AccessURL(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.AccessURL, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
if name == "" {
|
||||
c.String(http.StatusBadRequest, "name is empty")
|
||||
return
|
||||
}
|
||||
if name[0] == '/' {
|
||||
name = name[1:]
|
||||
}
|
||||
operationID := c.Query("operationID")
|
||||
if operationID == "" {
|
||||
operationID = "auto_" + strconv.Itoa(rand.Int())
|
||||
operationID = strconv.Itoa(rand.Int())
|
||||
}
|
||||
expires, _ := strconv.ParseInt(c.Query("expires"), 10, 64)
|
||||
if expires <= 0 {
|
||||
expires = 3600 * 1000
|
||||
}
|
||||
attachment, _ := strconv.ParseBool(c.Query("attachment"))
|
||||
c.Set(constant.OperationID, operationID)
|
||||
resp, err := o.Client.GetUrl(mcontext.SetOperationID(c, operationID), &third.GetUrlReq{Name: name, Expires: expires, Attachment: attachment})
|
||||
ctx := mcontext.SetOperationID(c, operationID)
|
||||
resp, err := o.Client.AccessURL(ctx, &third.AccessURLReq{Name: name})
|
||||
if err != nil {
|
||||
if errs.ErrArgs.Is(err) {
|
||||
c.String(http.StatusBadRequest, err.Error())
|
||||
|
||||
+113
-6
@@ -3,10 +3,12 @@ package api
|
||||
import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/apiresp"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -47,13 +49,118 @@ func (u *UserApi) GetUsers(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
||||
params := apistruct.ManagementSendMsgReq{}
|
||||
if err := c.BindJSON(¶ms); err != nil {
|
||||
var req msggateway.GetUsersOnlineStatusReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
if !tokenverify.IsAppManagerUid(c) {
|
||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
var wsResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult
|
||||
var respResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult
|
||||
flag := false
|
||||
|
||||
//Online push message
|
||||
for _, v := range conns {
|
||||
msgClient := msggateway.NewMsgGatewayClient(v)
|
||||
reply, err := msgClient.GetUsersOnlineStatus(c, &req)
|
||||
if err != nil {
|
||||
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
||||
continue
|
||||
} else {
|
||||
wsResult = append(wsResult, reply.SuccessResult...)
|
||||
}
|
||||
}
|
||||
// 遍历 api 请求体中的 userIDs
|
||||
for _, v1 := range req.UserIDs {
|
||||
flag = false
|
||||
res := new(msggateway.GetUsersOnlineStatusResp_SuccessResult)
|
||||
// 遍历从各个网关中获取的在线结果
|
||||
for _, v2 := range wsResult {
|
||||
// 如果匹配上说明在线,反之
|
||||
if v2.UserID == v1 {
|
||||
flag = true
|
||||
res.UserID = v1
|
||||
res.Status = constant.OnlineStatus
|
||||
res.DetailPlatformStatus = append(res.DetailPlatformStatus, v2.DetailPlatformStatus...)
|
||||
break
|
||||
}
|
||||
}
|
||||
if !flag {
|
||||
res.UserID = v1
|
||||
res.Status = constant.OnlineStatus
|
||||
}
|
||||
respResult = append(respResult, res)
|
||||
}
|
||||
apiresp.GinSuccess(c, respResult)
|
||||
}
|
||||
|
||||
func (u *UserApi) UserRegisterCount(c *gin.Context) {
|
||||
a2r.Call(user.UserClient.UserRegisterCount, u.Client, c)
|
||||
}
|
||||
|
||||
func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
|
||||
var wsResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult
|
||||
var respResult []*msggateway.SingleDetail
|
||||
flag := false
|
||||
var req msggateway.GetUsersOnlineStatusReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
}
|
||||
//Online push message
|
||||
for _, v := range conns {
|
||||
msgClient := msggateway.NewMsgGatewayClient(v)
|
||||
reply, err := msgClient.GetUsersOnlineStatus(c, &req)
|
||||
if err != nil {
|
||||
log.ZWarn(c, "GetUsersOnlineStatus rpc err", err)
|
||||
continue
|
||||
} else {
|
||||
wsResult = append(wsResult, reply.SuccessResult...)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v1 := range req.UserIDs {
|
||||
m := make(map[string][]string, 10)
|
||||
flag = false
|
||||
temp := new(msggateway.SingleDetail)
|
||||
for _, v2 := range wsResult {
|
||||
if v2.UserID == v1 {
|
||||
flag = true
|
||||
temp.UserID = v1
|
||||
temp.Status = constant.OnlineStatus
|
||||
for _, status := range v2.DetailPlatformStatus {
|
||||
if v, ok := m[status.Platform]; ok {
|
||||
m[status.Platform] = append(v, status.Token)
|
||||
} else {
|
||||
m[status.Platform] = []string{status.Token}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for p, tokens := range m {
|
||||
t := new(msggateway.SinglePlatformToken)
|
||||
t.Platform = p
|
||||
t.Token = tokens
|
||||
t.Total = int32(len(tokens))
|
||||
temp.SinglePlatformToken = append(temp.SinglePlatformToken, t)
|
||||
}
|
||||
|
||||
if flag {
|
||||
respResult = append(respResult, temp)
|
||||
}
|
||||
}
|
||||
|
||||
apiresp.GinSuccess(c, respResult)
|
||||
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ type Client struct {
|
||||
longConnServer LongConnServer
|
||||
closed bool
|
||||
closedErr error
|
||||
token string
|
||||
}
|
||||
|
||||
func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
|
||||
@@ -65,7 +66,7 @@ func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground, isCompress bool, longConnServer LongConnServer) {
|
||||
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground, isCompress bool, longConnServer LongConnServer, token string) {
|
||||
c.w = new(sync.Mutex)
|
||||
c.conn = conn
|
||||
c.PlatformID = utils.StringToInt(ctx.GetPlatformID())
|
||||
@@ -77,6 +78,7 @@ func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isBackground,
|
||||
c.IsBackground = false
|
||||
c.closed = false
|
||||
c.closedErr = nil
|
||||
c.token = token
|
||||
}
|
||||
func (c *Client) pongHandler(_ string) error {
|
||||
c.conn.SetReadDeadline(pongWait)
|
||||
@@ -212,6 +214,7 @@ func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error
|
||||
} else {
|
||||
msg.Msgs = m
|
||||
}
|
||||
log.ZDebug(ctx, "PushMessage", "msg", &msg)
|
||||
data, err := proto.Marshal(&msg)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -2,6 +2,7 @@ package msggateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
@@ -70,6 +71,7 @@ func (s *Server) GetUsersOnlineStatus(ctx context.Context, req *msggateway.GetUs
|
||||
ps.Platform = constant.PlatformIDToName(client.PlatformID)
|
||||
ps.Status = constant.OnlineStatus
|
||||
ps.ConnID = client.ctx.GetConnID()
|
||||
ps.Token = client.token
|
||||
ps.IsBackground = client.IsBackground
|
||||
temp.Status = constant.OnlineStatus
|
||||
temp.DetailPlatformStatus = append(temp.DetailPlatformStatus, ps)
|
||||
@@ -107,7 +109,7 @@ func (s *Server) SuperGroupOnlineBatchPushOneMsg(ctx context.Context, req *msgga
|
||||
RecvID: v,
|
||||
RecvPlatFormID: int32(client.PlatformID),
|
||||
}
|
||||
if !client.IsBackground {
|
||||
if !client.IsBackground || (client.IsBackground == true && client.PlatformID != constant.IOSPlatformID) {
|
||||
err := client.PushMessage(ctx, req.MsgData)
|
||||
if err != nil {
|
||||
temp.ResultCode = -2
|
||||
@@ -138,11 +140,14 @@ func (s *Server) KickUserOffline(ctx context.Context, req *msggateway.KickUserOf
|
||||
for _, v := range req.KickUserIDList {
|
||||
if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok {
|
||||
for _, client := range clients {
|
||||
log.ZDebug(ctx, "kick user offline", "userID", v, "platformID", req.PlatformID, "client", client)
|
||||
err := client.KickOnlineMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.ZWarn(ctx, "conn not exist", nil, "userID", v, "platformID", req.PlatformID)
|
||||
}
|
||||
}
|
||||
return &msggateway.KickUserOfflineResp{}, nil
|
||||
|
||||
@@ -12,7 +12,7 @@ func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
||||
longServer, err := NewWsServer(
|
||||
WithPort(wsPort),
|
||||
WithMaxConnNum(int64(config.Config.LongConnSvr.WebsocketMaxConnNum)),
|
||||
WithHandshakeTimeout(time.Duration(config.Config.LongConnSvr.WebsocketTimeOut)*time.Second),
|
||||
WithHandshakeTimeout(time.Duration(config.Config.LongConnSvr.WebsocketTimeout)*time.Second),
|
||||
WithMessageMaxMsgLength(config.Config.LongConnSvr.WebsocketMaxMsgLen))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -312,7 +312,7 @@ func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
client := ws.clientPool.Get().(*Client)
|
||||
client.ResetClient(connContext, wsLongConn, connContext.GetBackground(), compression, ws)
|
||||
client.ResetClient(connContext, wsLongConn, connContext.GetBackground(), compression, ws, token)
|
||||
ws.registerChan <- client
|
||||
go client.readMessage()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
|
||||
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/tx"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
|
||||
@@ -25,7 +24,7 @@ type MsgTransfer struct {
|
||||
persistentCH *PersistentConsumerHandler // 聊天记录持久化到mysql的消费者 订阅的topic: ws2ms_chat
|
||||
historyCH *OnlineHistoryRedisConsumerHandler // 这个消费者聚合消息, 订阅的topic:ws2ms_chat, 修改通知发往msg_to_modify topic, 消息存入redis后Incr Redis, 再发消息到ms2pschat topic推送, 发消息到msg_to_mongo topic持久化
|
||||
historyMongoCH *OnlineHistoryMongoConsumerHandler // mongoDB批量插入, 成功后删除redis中消息,以及处理删除通知消息删除的 订阅的topic: msg_to_mongo
|
||||
modifyCH *ModifyMsgConsumerHandler // 负责消费修改消息通知的consumer, 订阅的topic: msg_to_modify
|
||||
// modifyCH *ModifyMsgConsumerHandler // 负责消费修改消息通知的consumer, 订阅的topic: msg_to_modify
|
||||
}
|
||||
|
||||
func StartTransfer(prometheusPort int) error {
|
||||
@@ -34,7 +33,7 @@ func StartTransfer(prometheusPort int) error {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationTb.ChatLogModel{}); err != nil {
|
||||
return err
|
||||
fmt.Printf("gorm: AutoMigrate ChatLogModel err: %v\n", err)
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
@@ -48,31 +47,31 @@ func StartTransfer(prometheusPort int) error {
|
||||
return err
|
||||
}
|
||||
client, err := openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
openKeeper.WithFreq(time.Hour), openKeeper.WithRoundRobin(), openKeeper.WithUserNameAndPassword(config.Config.Zookeeper.UserName,
|
||||
openKeeper.WithFreq(time.Hour), openKeeper.WithRoundRobin(), openKeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), openKeeper.WithTimeout(10), openKeeper.WithLogger(log.NewZkLogger()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||
return err
|
||||
}
|
||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
msgModel := cache.NewMsgCacheModel(rdb)
|
||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
||||
extendMsgModel := unrelation.NewExtendMsgSetMongoDriver(mongo.GetDatabase())
|
||||
extendMsgCache := cache.NewExtendMsgSetCacheRedis(rdb, extendMsgModel, cache.GetDefaultOpt())
|
||||
chatLogDatabase := controller.NewChatLogDatabase(relation.NewChatLogGorm(db))
|
||||
extendMsgDatabase := controller.NewExtendMsgDatabase(extendMsgModel, extendMsgCache, tx.NewMongo(mongo.GetClient()))
|
||||
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgTransfer := NewMsgTransfer(chatLogDatabase, extendMsgDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
msgTransfer := NewMsgTransfer(chatLogDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||
msgTransfer.initPrometheus()
|
||||
return msgTransfer.Start(prometheusPort)
|
||||
}
|
||||
|
||||
func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase,
|
||||
extendMsgDatabase controller.ExtendMsgDatabase, msgDatabase controller.CommonMsgDatabase,
|
||||
msgDatabase controller.CommonMsgDatabase,
|
||||
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer {
|
||||
return &MsgTransfer{persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
|
||||
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase), modifyCH: NewModifyMsgConsumerHandler(extendMsgDatabase)}
|
||||
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase)}
|
||||
}
|
||||
|
||||
func (m *MsgTransfer) initPrometheus() {
|
||||
@@ -97,7 +96,7 @@ func (m *MsgTransfer) Start(prometheusPort int) error {
|
||||
}
|
||||
go m.historyCH.historyConsumerGroup.RegisterHandleAndConsumer(m.historyCH)
|
||||
go m.historyMongoCH.historyConsumerGroup.RegisterHandleAndConsumer(m.historyMongoCH)
|
||||
go m.modifyCH.modifyMsgConsumerGroup.RegisterHandleAndConsumer(m.modifyCH)
|
||||
// go m.modifyCH.modifyMsgConsumerGroup.RegisterHandleAndConsumer(m.modifyCH)
|
||||
err := prome.StartPrometheusSrv(prometheusPort)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
package msgtransfer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
kfk "github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
pbMsg "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
"github.com/Shopify/sarama"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type ModifyMsgConsumerHandler struct {
|
||||
modifyMsgConsumerGroup *kfk.MConsumerGroup
|
||||
|
||||
extendMsgDatabase controller.ExtendMsgDatabase
|
||||
extendSetMsgModel unRelationTb.ExtendMsgSetModel
|
||||
}
|
||||
|
||||
func NewModifyMsgConsumerHandler(database controller.ExtendMsgDatabase) *ModifyMsgConsumerHandler {
|
||||
return &ModifyMsgConsumerHandler{
|
||||
modifyMsgConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToModify.Topic},
|
||||
config.Config.Kafka.MsgToModify.Addr, config.Config.Kafka.ConsumerGroupID.MsgToModify),
|
||||
extendMsgDatabase: database,
|
||||
}
|
||||
}
|
||||
|
||||
func (ModifyMsgConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (ModifyMsgConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (mmc *ModifyMsgConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
|
||||
claim sarama.ConsumerGroupClaim) error {
|
||||
for msg := range claim.Messages() {
|
||||
ctx := mmc.modifyMsgConsumerGroup.GetContextFromMsg(msg)
|
||||
log.ZDebug(ctx, "kafka get info to mysql", "ModifyMsgConsumerHandler", msg.Topic, "msgPartition", msg.Partition, "msg", string(msg.Value), "key", string(msg.Key))
|
||||
if len(msg.Value) != 0 {
|
||||
mmc.ModifyMsg(ctx, msg, string(msg.Key), sess)
|
||||
} else {
|
||||
log.ZError(ctx, "msg get from kafka but is nil", nil, "key", msg.Key)
|
||||
}
|
||||
sess.MarkMessage(msg, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mmc *ModifyMsgConsumerHandler) ModifyMsg(ctx context.Context, cMsg *sarama.ConsumerMessage, msgKey string, _ sarama.ConsumerGroupSession) {
|
||||
msgFromMQ := pbMsg.MsgDataToModifyByMQ{}
|
||||
operationID := mcontext.GetOperationID(ctx)
|
||||
err := proto.Unmarshal(cMsg.Value, &msgFromMQ)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "msg_transfer Unmarshal msg err", err, "msg", string(cMsg.Value))
|
||||
return
|
||||
}
|
||||
log.ZDebug(ctx, "proto.Unmarshal MsgDataToMQ", "msgs", msgFromMQ.String())
|
||||
for _, msg := range msgFromMQ.Messages {
|
||||
isReactionFromCache := utils.GetSwitchFromOptions(msg.Options, constant.IsReactionFromCache)
|
||||
if !isReactionFromCache {
|
||||
continue
|
||||
}
|
||||
ctx = mcontext.SetOperationID(ctx, operationID)
|
||||
if msg.ContentType == constant.ReactionMessageModifier {
|
||||
notification := &sdkws.ReactionMessageModifierNotification{}
|
||||
if err := json.Unmarshal(msg.Content, notification); err != nil {
|
||||
continue
|
||||
}
|
||||
if notification.IsExternalExtensions {
|
||||
continue
|
||||
}
|
||||
if !notification.IsReact {
|
||||
// first time to modify
|
||||
var reactionExtensionList = make(map[string]unRelationTb.KeyValueModel)
|
||||
extendMsg := unRelationTb.ExtendMsgModel{
|
||||
ReactionExtensionList: reactionExtensionList,
|
||||
ClientMsgID: notification.ClientMsgID,
|
||||
MsgFirstModifyTime: notification.MsgFirstModifyTime,
|
||||
}
|
||||
for _, v := range notification.SuccessReactionExtensions {
|
||||
reactionExtensionList[v.TypeKey] = unRelationTb.KeyValueModel{
|
||||
TypeKey: v.TypeKey,
|
||||
Value: v.Value,
|
||||
LatestUpdateTime: v.LatestUpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
if err := mmc.extendMsgDatabase.InsertExtendMsg(ctx, notification.ConversationID, notification.SessionType, &extendMsg); err != nil {
|
||||
// log.ZError(ctx, "MsgFirstModify InsertExtendMsg failed", notification.ConversationID, notification.SessionType, extendMsg, err.Error())
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if err := mmc.extendMsgDatabase.InsertOrUpdateReactionExtendMsgSet(ctx, notification.ConversationID, notification.SessionType, notification.ClientMsgID, notification.MsgFirstModifyTime, mmc.extendSetMsgModel.Pb2Model(notification.SuccessReactionExtensions)); err != nil {
|
||||
// log.NewError(operationID, "InsertOrUpdateReactionExtendMsgSet failed")
|
||||
}
|
||||
}
|
||||
} else if msg.ContentType == constant.ReactionMessageDeleter {
|
||||
notification := &sdkws.ReactionMessageDeleteNotification{}
|
||||
if err := json.Unmarshal(msg.Content, notification); err != nil {
|
||||
continue
|
||||
}
|
||||
if err := mmc.extendMsgDatabase.DeleteReactionExtendMsgSet(ctx, notification.ConversationID, notification.SessionType, notification.ClientMsgID, notification.MsgFirstModifyTime, mmc.extendSetMsgModel.Pb2Model(notification.SuccessReactionExtensions)); err != nil {
|
||||
// log.NewError(operationID, "InsertOrUpdateReactionExtendMsgSet failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,8 +75,8 @@ func NewOnlineHistoryRedisConsumerHandler(database controller.CommonMsgDatabase,
|
||||
och.conversationRpcClient = conversationRpcClient
|
||||
och.groupRpcClient = groupRpcClient
|
||||
och.historyConsumerGroup = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.Ws2mschat.Topic},
|
||||
config.Config.Kafka.Ws2mschat.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
|
||||
//statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
|
||||
return &och
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase)
|
||||
mc := &OnlineHistoryMongoConsumerHandler{
|
||||
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToMongo.Topic},
|
||||
config.Config.Kafka.MsgToMongo.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo),
|
||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo),
|
||||
msgDatabase: database,
|
||||
}
|
||||
return mc
|
||||
|
||||
@@ -29,8 +29,8 @@ type PersistentConsumerHandler struct {
|
||||
func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler {
|
||||
return &PersistentConsumerHandler{
|
||||
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.Ws2mschat.Topic},
|
||||
config.Config.Kafka.Ws2mschat.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
|
||||
chatLogDatabase: database,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +124,8 @@ func newPushReq(title, content string) PushReq {
|
||||
Title: title,
|
||||
Body: content,
|
||||
ClickType: "startapp",
|
||||
ChannelID: config.Config.Push.Getui.ChannelID,
|
||||
ChannelName: config.Config.Push.Getui.ChannelName,
|
||||
ChannelID: config.Config.Push.GeTui.ChannelID,
|
||||
ChannelName: config.Config.Push.GeTui.ChannelName,
|
||||
}}}
|
||||
return pushReq
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package getui
|
||||
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
"sync"
|
||||
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/internal/push/offlinepush"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
@@ -11,12 +16,6 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils/splitter"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -98,12 +97,12 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
||||
|
||||
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(config.Config.Push.Getui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.Getui.MasterSecret))
|
||||
h.Write([]byte(config.Config.Push.GeTui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.GeTui.MasterSecret))
|
||||
sign := hex.EncodeToString(h.Sum(nil))
|
||||
reqAuth := AuthReq{
|
||||
Sign: sign,
|
||||
Timestamp: strconv.Itoa(int(timeStamp)),
|
||||
AppKey: config.Config.Push.Getui.AppKey,
|
||||
AppKey: config.Config.Push.GeTui.AppKey,
|
||||
}
|
||||
respAuth := AuthResp{}
|
||||
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
||||
@@ -146,7 +145,7 @@ func (g *Client) request(ctx context.Context, url string, input interface{}, tok
|
||||
header := map[string]string{"token": token}
|
||||
resp := &Resp{}
|
||||
resp.Data = output
|
||||
return g.postReturn(ctx, config.Config.Push.Getui.PushUrl+url, header, input, resp, 3)
|
||||
return g.postReturn(ctx, config.Config.Push.GeTui.PushUrl+url, header, input, resp, 3)
|
||||
}
|
||||
|
||||
func (g *Client) postReturn(ctx context.Context, url string, header map[string]string, input interface{}, output RespI, timeout int) error {
|
||||
|
||||
@@ -23,7 +23,7 @@ func NewConsumerHandler(pusher *Pusher) *ConsumerHandler {
|
||||
var consumerHandler ConsumerHandler
|
||||
consumerHandler.pusher = pusher
|
||||
consumerHandler.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.Ms2pschat.Topic}, config.Config.Kafka.Ms2pschat.Addr,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
|
||||
config.Config.Kafka.ConsumerGroupID.MsgToPush)
|
||||
return &consumerHandler
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
pbPush "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/push"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -26,7 +27,10 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
||||
offlinePusher := NewOfflinePusher(cacheModel)
|
||||
database := controller.NewPushDatabase(cacheModel)
|
||||
pusher := NewPusher(client, offlinePusher, database, localcache.NewGroupLocalCache(client), localcache.NewConversationLocalCache(client))
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
pusher := NewPusher(client, offlinePusher, database, localcache.NewGroupLocalCache(&groupRpcClient), localcache.NewConversationLocalCache(&conversationRpcClient), &conversationRpcClient, &groupRpcClient, &msgRpcClient)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
|
||||
@@ -26,11 +26,11 @@ import (
|
||||
|
||||
type Pusher struct {
|
||||
database controller.PushDatabase
|
||||
client discoveryregistry.SvcDiscoveryRegistry
|
||||
discov discoveryregistry.SvcDiscoveryRegistry
|
||||
offlinePusher offlinepush.OfflinePusher
|
||||
groupLocalCache *localcache.GroupLocalCache
|
||||
conversationLocalCache *localcache.ConversationLocalCache
|
||||
msgClient *rpcclient.MessageRpcClient
|
||||
msgRpcClient *rpcclient.MessageRpcClient
|
||||
conversationRpcClient *rpcclient.ConversationRpcClient
|
||||
groupRpcClient *rpcclient.GroupRpcClient
|
||||
successCount int
|
||||
@@ -39,30 +39,28 @@ type Pusher struct {
|
||||
var errNoOfflinePusher = errors.New("no offlinePusher is configured")
|
||||
|
||||
func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
|
||||
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache) *Pusher {
|
||||
msgClient := rpcclient.NewMessageRpcClient(discov)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(discov)
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(discov)
|
||||
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache,
|
||||
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient) *Pusher {
|
||||
return &Pusher{
|
||||
discov: discov,
|
||||
database: database,
|
||||
offlinePusher: offlinePusher,
|
||||
groupLocalCache: groupLocalCache,
|
||||
conversationLocalCache: conversationLocalCache,
|
||||
msgClient: &msgClient,
|
||||
conversationRpcClient: &conversationRpcClient,
|
||||
groupRpcClient: &groupRpcClient,
|
||||
msgRpcClient: msgRpcClient,
|
||||
conversationRpcClient: conversationRpcClient,
|
||||
groupRpcClient: groupRpcClient,
|
||||
}
|
||||
}
|
||||
|
||||
func NewOfflinePusher(cache cache.MsgModel) offlinepush.OfflinePusher {
|
||||
var offlinePusher offlinepush.OfflinePusher
|
||||
if config.Config.Push.Getui.Enable {
|
||||
switch config.Config.Push.Enable {
|
||||
case "getui":
|
||||
offlinePusher = getui.NewClient(cache)
|
||||
}
|
||||
if config.Config.Push.Fcm.Enable {
|
||||
case "fcm":
|
||||
offlinePusher = fcm.NewClient(cache)
|
||||
}
|
||||
if config.Config.Push.Jpns.Enable {
|
||||
case "jpush":
|
||||
offlinePusher = jpush.NewClient()
|
||||
}
|
||||
return offlinePusher
|
||||
@@ -70,7 +68,7 @@ func NewOfflinePusher(cache cache.MsgModel) offlinepush.OfflinePusher {
|
||||
|
||||
func (p *Pusher) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID string, userIDs []string) error {
|
||||
conevrsationID := utils.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID)
|
||||
maxSeq, err := p.msgClient.GetConversationMaxSeq(ctx, conevrsationID)
|
||||
maxSeq, err := p.msgRpcClient.GetConversationMaxSeq(ctx, conevrsationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -163,8 +161,8 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
||||
return err
|
||||
}
|
||||
log.ZInfo(ctx, "GroupDismissedNotificationInfo****", "groupID", groupID, "num", len(pushToUserIDs), "list", pushToUserIDs)
|
||||
if len(config.Config.Manager.AppManagerUid) > 0 {
|
||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.Manager.AppManagerUid[0])
|
||||
if len(config.Config.Manager.UserID) > 0 {
|
||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.Manager.UserID[0])
|
||||
}
|
||||
defer func(groupID string) {
|
||||
if err := p.groupRpcClient.DismissGroup(ctx, groupID); err != nil {
|
||||
@@ -237,7 +235,7 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
||||
}
|
||||
|
||||
func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) (wsResults []*msggateway.SingleMsgToUserResults, err error) {
|
||||
conns, err := p.client.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||
conns, err := p.discov.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||
log.ZDebug(ctx, "get gateway conn", "conn length", len(conns))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -246,7 +244,6 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
|
||||
for _, v := range conns {
|
||||
msgClient := msggateway.NewMsgGatewayClient(v)
|
||||
reply, err := msgClient.SuperGroupOnlineBatchPushOneMsg(ctx, &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs})
|
||||
v.Close()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -33,13 +33,16 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
pbAuth.RegisterAuthServer(server, &authServer{
|
||||
userRpcClient: &userRpcClient,
|
||||
RegisterCenter: client,
|
||||
authDatabase: controller.NewAuthDatabase(cache.NewMsgCacheModel(rdb), config.Config.TokenPolicy.AccessSecret, config.Config.TokenPolicy.AccessExpire),
|
||||
authDatabase: controller.NewAuthDatabase(cache.NewMsgCacheModel(rdb), config.Config.Secret, config.Config.TokenPolicy.Expire),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *authServer) UserToken(ctx context.Context, req *pbAuth.UserTokenReq) (*pbAuth.UserTokenResp, error) {
|
||||
resp := pbAuth.UserTokenResp{}
|
||||
if req.Secret != config.Config.Secret {
|
||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||
}
|
||||
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -48,7 +51,7 @@ func (s *authServer) UserToken(ctx context.Context, req *pbAuth.UserTokenReq) (*
|
||||
return nil, err
|
||||
}
|
||||
resp.Token = token
|
||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.AccessExpire
|
||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.Expire * 24 * 60 * 60
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
@@ -90,14 +93,13 @@ func (s *authServer) ParseToken(ctx context.Context, req *pbAuth.ParseTokenReq)
|
||||
}
|
||||
|
||||
func (s *authServer) ForceLogout(ctx context.Context, req *pbAuth.ForceLogoutReq) (*pbAuth.ForceLogoutResp, error) {
|
||||
resp := pbAuth.ForceLogoutResp{}
|
||||
if err := tokenverify.CheckAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
return &pbAuth.ForceLogoutResp{}, nil
|
||||
}
|
||||
|
||||
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
|
||||
@@ -109,8 +111,7 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID
|
||||
client := msggateway.NewMsgGatewayClient(v)
|
||||
kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
|
||||
_, err := client.KickUserOffline(ctx, kickReq)
|
||||
v.Close()
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
return errs.ErrInternalServer.Wrap()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ type conversationServer struct {
|
||||
groupRpcClient *rpcclient.GroupRpcClient
|
||||
conversationDatabase controller.ConversationDatabase
|
||||
conversationNotificationSender *notification.ConversationNotificationSender
|
||||
msgRpcClient *rpcclient.MessageRpcClient
|
||||
}
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
@@ -43,9 +42,8 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
pbConversation.RegisterConversationServer(server, &conversationServer{
|
||||
conversationNotificationSender: notification.NewConversationNotificationSender(client),
|
||||
conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient),
|
||||
groupRpcClient: &groupRpcClient,
|
||||
msgRpcClient: &msgRpcClient,
|
||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewGorm(db)),
|
||||
})
|
||||
return nil
|
||||
@@ -84,16 +82,6 @@ func (c *conversationServer) GetConversations(ctx context.Context, req *pbConver
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *conversationServer) BatchSetConversations(ctx context.Context, req *pbConversation.BatchSetConversationsReq) (*pbConversation.BatchSetConversationsResp, error) {
|
||||
conversations := convert.ConversationsPb2DB(req.Conversations)
|
||||
err := c.conversationDatabase.SetUserConversations(ctx, req.OwnerUserID, conversations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = c.conversationNotificationSender.ConversationChangeNotification(ctx, req.OwnerUserID)
|
||||
return &pbConversation.BatchSetConversationsResp{}, nil
|
||||
}
|
||||
|
||||
func (c *conversationServer) SetConversation(ctx context.Context, req *pbConversation.SetConversationReq) (*pbConversation.SetConversationResp, error) {
|
||||
var conversation tableRelation.ConversationModel
|
||||
if err := utils.CopyStructFields(&conversation, req.Conversation); err != nil {
|
||||
@@ -108,78 +96,10 @@ func (c *conversationServer) SetConversation(ctx context.Context, req *pbConvers
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *conversationServer) SetRecvMsgOpt(ctx context.Context, req *pbConversation.SetRecvMsgOptReq) (*pbConversation.SetRecvMsgOptResp, error) {
|
||||
if err := c.conversationDatabase.SetUsersConversationFiledTx(ctx, []string{req.OwnerUserID}, &tableRelation.ConversationModel{OwnerUserID: req.OwnerUserID, ConversationID: req.ConversationID, RecvMsgOpt: req.RecvMsgOpt}, map[string]interface{}{"recv_msg_opt": req.RecvMsgOpt}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = c.conversationNotificationSender.ConversationChangeNotification(ctx, req.OwnerUserID)
|
||||
return &pbConversation.SetRecvMsgOptResp{}, nil
|
||||
}
|
||||
|
||||
// deprecated
|
||||
func (c *conversationServer) ModifyConversationField(ctx context.Context, req *pbConversation.ModifyConversationFieldReq) (*pbConversation.ModifyConversationFieldResp, error) {
|
||||
resp := &pbConversation.ModifyConversationFieldResp{}
|
||||
var err error
|
||||
isSyncConversation := true
|
||||
if req.Conversation.ConversationType == constant.GroupChatType {
|
||||
groupInfo, err := c.groupRpcClient.GetGroupInfo(ctx, req.Conversation.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if groupInfo.Status == constant.GroupStatusDismissed && req.FieldType != constant.FieldUnread {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
conversation := convert.ConversationPb2DB(req.Conversation)
|
||||
if req.FieldType == constant.FieldIsPrivateChat {
|
||||
err := c.conversationDatabase.SyncPeerUserPrivateConversationTx(ctx, []*tableRelation.ConversationModel{conversation})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.conversationNotificationSender.ConversationSetPrivateNotification(ctx, req.Conversation.OwnerUserID, req.Conversation.UserID, req.Conversation.IsPrivateChat)
|
||||
return resp, nil
|
||||
}
|
||||
filedMap := make(map[string]interface{})
|
||||
switch req.FieldType {
|
||||
case constant.FieldRecvMsgOpt:
|
||||
filedMap["recv_msg_opt"] = req.Conversation.RecvMsgOpt
|
||||
case constant.FieldGroupAtType:
|
||||
filedMap["group_at_type"] = req.Conversation.GroupAtType
|
||||
case constant.FieldIsPinned:
|
||||
filedMap["is_pinned"] = req.Conversation.IsPinned
|
||||
case constant.FieldEx:
|
||||
filedMap["ex"] = req.Conversation.Ex
|
||||
case constant.FieldAttachedInfo:
|
||||
filedMap["attached_info"] = req.Conversation.AttachedInfo
|
||||
case constant.FieldUnread:
|
||||
isSyncConversation = false
|
||||
filedMap["update_unread_count_time"] = req.Conversation.UpdateUnreadCountTime
|
||||
filedMap["has_read_seq"] = req.Conversation.HasReadSeq
|
||||
case constant.FieldBurnDuration:
|
||||
filedMap["burn_duration"] = req.Conversation.BurnDuration
|
||||
}
|
||||
err = c.conversationDatabase.SetUsersConversationFiledTx(ctx, req.UserIDList, conversation, filedMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isSyncConversation {
|
||||
for _, v := range req.UserIDList {
|
||||
c.conversationNotificationSender.ConversationChangeNotification(ctx, v)
|
||||
}
|
||||
} else {
|
||||
for _, v := range req.UserIDList {
|
||||
c.conversationNotificationSender.ConversationUnreadChangeNotification(ctx, v, req.Conversation.ConversationID, req.Conversation.UpdateUnreadCountTime, req.Conversation.HasReadSeq)
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *conversationServer) SetConversations(ctx context.Context, req *pbConversation.SetConversationsReq) (*pbConversation.SetConversationsResp, error) {
|
||||
if req.Conversation == nil {
|
||||
return nil, errs.ErrArgs.Wrap("conversation must not be nil")
|
||||
}
|
||||
isSyncConversation := true
|
||||
if req.Conversation.ConversationType == constant.GroupChatType {
|
||||
groupInfo, err := c.groupRpcClient.GetGroupInfo(ctx, req.Conversation.GroupID)
|
||||
if err != nil {
|
||||
@@ -188,6 +108,12 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbConver
|
||||
if groupInfo.Status == constant.GroupStatusDismissed {
|
||||
return nil, err
|
||||
}
|
||||
// for _, userID := range req.UserIDs {
|
||||
// if _, err := c.groupRpcClient.GetGroupMemberCache(ctx, req.Conversation.GroupID, userID); err != nil {
|
||||
// log.ZError(ctx, "user not in group", err, "userID", userID, "groupID", req.Conversation.GroupID)
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
}
|
||||
var conversation tableRelation.ConversationModel
|
||||
conversation.ConversationID = req.Conversation.ConversationID
|
||||
@@ -198,9 +124,6 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbConver
|
||||
if req.Conversation.RecvMsgOpt != nil {
|
||||
m["recv_msg_opt"] = req.Conversation.RecvMsgOpt.Value
|
||||
}
|
||||
if req.Conversation.DraftTextTime != nil {
|
||||
m["draft_text_time"] = req.Conversation.DraftTextTime.Value
|
||||
}
|
||||
if req.Conversation.AttachedInfo != nil {
|
||||
m["attached_info"] = req.Conversation.AttachedInfo.Value
|
||||
}
|
||||
@@ -210,42 +133,39 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbConver
|
||||
if req.Conversation.IsPinned != nil {
|
||||
m["is_pinned"] = req.Conversation.IsPinned.Value
|
||||
}
|
||||
if req.Conversation.IsPrivateChat != nil {
|
||||
if req.Conversation.GroupAtType != nil {
|
||||
m["group_at_type"] = req.Conversation.GroupAtType.Value
|
||||
}
|
||||
if req.Conversation.MsgDestructTime != nil {
|
||||
m["msg_destruct_time"] = req.Conversation.MsgDestructTime.Value
|
||||
}
|
||||
if req.Conversation.IsMsgDestruct != nil {
|
||||
m["is_msg_destruct"] = req.Conversation.IsMsgDestruct.Value
|
||||
}
|
||||
if req.Conversation.IsPrivateChat != nil && req.Conversation.ConversationType != constant.SuperGroupChatType {
|
||||
var conversations []*tableRelation.ConversationModel
|
||||
for _, ownerUserID := range req.UserIDs {
|
||||
conversation2 := conversation
|
||||
conversation.OwnerUserID = ownerUserID
|
||||
conversation.IsPrivateChat = req.Conversation.IsPrivateChat.Value
|
||||
conversation2.OwnerUserID = ownerUserID
|
||||
conversation2.IsPrivateChat = req.Conversation.IsPrivateChat.Value
|
||||
conversations = append(conversations, &conversation2)
|
||||
}
|
||||
if err := c.conversationDatabase.SyncPeerUserPrivateConversationTx(ctx, conversations); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, ownerUserID := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationSetPrivateNotification(ctx, ownerUserID, req.Conversation.UserID, req.Conversation.IsPrivateChat.Value)
|
||||
for _, userID := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationSetPrivateNotification(ctx, userID, req.Conversation.UserID, req.Conversation.IsPrivateChat.Value)
|
||||
}
|
||||
}
|
||||
if req.Conversation.BurnDuration != nil {
|
||||
m["burn_duration"] = req.Conversation.BurnDuration.Value
|
||||
}
|
||||
if req.Conversation.HasReadSeq != nil && req.Conversation.UpdateUnreadCountTime != nil {
|
||||
isSyncConversation = false
|
||||
m["has_read_seq"] = req.Conversation.HasReadSeq.Value
|
||||
m["update_unread_count_time"] = req.Conversation.UpdateUnreadCountTime.Value
|
||||
}
|
||||
err := c.conversationDatabase.SetUsersConversationFiledTx(ctx, req.UserIDs, &conversation, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isSyncConversation {
|
||||
for _, v := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationChangeNotification(ctx, v)
|
||||
}
|
||||
} else {
|
||||
for _, v := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationUnreadChangeNotification(ctx, v, req.Conversation.ConversationID, req.Conversation.UpdateUnreadCountTime.Value, req.Conversation.HasReadSeq.Value)
|
||||
}
|
||||
for _, v := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationChangeNotification(ctx, v)
|
||||
}
|
||||
return &pbConversation.SetConversationsResp{}, nil
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
blackDB := relation.NewBlackGorm(db)
|
||||
friendDB := relation.NewFriendGorm(db)
|
||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||
notificationSender := notification.NewFriendNotificationSender(client, notification.WithRpcFunc(userRpcClient.GetUsersInfo))
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
notificationSender := notification.NewFriendNotificationSender(&msgRpcClient, notification.WithRpcFunc(userRpcClient.GetUsersInfo))
|
||||
pbfriend.RegisterFriendServer(server, &friendServer{
|
||||
friendDatabase: controller.NewFriendDatabase(friendDB, relation.NewFriendRequestGorm(db), cache.NewFriendCacheRedis(rdb, friendDB, cache.GetDefaultOpt()), tx.NewGorm(db)),
|
||||
blackDatabase: controller.NewBlackDatabase(blackDB, cache.NewBlackCacheRedis(rdb, blackDB, cache.GetDefaultOpt())),
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"time"
|
||||
|
||||
pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
)
|
||||
|
||||
func UpdateGroupInfoMap(group *sdkws.GroupInfoForSet) map[string]any {
|
||||
func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[string]any {
|
||||
m := make(map[string]any)
|
||||
if group.GroupName != "" {
|
||||
m["name"] = group.GroupName
|
||||
}
|
||||
if group.Notification != "" {
|
||||
m["Notification"] = group.Notification
|
||||
m["notification"] = group.Notification
|
||||
m["notification_update_time"] = time.Now()
|
||||
m["notification_user_id"] = mcontext.GetOpUserID(ctx)
|
||||
}
|
||||
if group.Introduction != "" {
|
||||
m["introduction"] = group.Introduction
|
||||
|
||||
+32
-23
@@ -3,6 +3,8 @@ package group
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
@@ -48,30 +50,32 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user := rpcclient.NewUserClient(client)
|
||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
||||
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
||||
pbGroup.RegisterGroupServer(server, &groupServer{
|
||||
GroupDatabase: database,
|
||||
User: user,
|
||||
Notification: notification.NewGroupNotificationSender(database, client, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||
users, err := user.GetUsersInfo(ctx, userIDs)
|
||||
User: userRpcClient,
|
||||
Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
|
||||
}),
|
||||
conversationRpcClient: rpcclient.NewConversationClient(client),
|
||||
msgRpcClient: rpcclient.NewMsgClient(client),
|
||||
conversationRpcClient: conversationRpcClient,
|
||||
msgRpcClient: msgRpcClient,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type groupServer struct {
|
||||
GroupDatabase controller.GroupDatabase
|
||||
User *rpcclient.UserClient
|
||||
User rpcclient.UserRpcClient
|
||||
Notification *notification.GroupNotificationSender
|
||||
conversationRpcClient *rpcclient.ConversationClient
|
||||
msgRpcClient *rpcclient.MsgClient
|
||||
conversationRpcClient rpcclient.ConversationRpcClient
|
||||
msgRpcClient rpcclient.MessageRpcClient
|
||||
}
|
||||
|
||||
func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error {
|
||||
@@ -842,7 +846,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInf
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := UpdateGroupInfoMap(req.GroupInfoForSet)
|
||||
data := UpdateGroupInfoMap(ctx, req.GroupInfoForSet)
|
||||
if len(data) == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
@@ -863,21 +867,26 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInf
|
||||
}
|
||||
var num int
|
||||
if req.GroupInfoForSet.Notification != "" {
|
||||
go func() {
|
||||
nctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(ctx))
|
||||
conversation := &pbConversation.ConversationReq{
|
||||
ConversationID: utils.GetConversationIDBySessionType(constant.SuperGroupChatType, req.GroupInfoForSet.GroupID),
|
||||
ConversationType: constant.SuperGroupChatType,
|
||||
GroupID: req.GroupInfoForSet.GroupID,
|
||||
}
|
||||
resp, err := s.GetGroupMemberUserIDs(nctx, &pbGroup.GetGroupMemberUserIDsReq{GroupID: req.GroupInfoForSet.GroupID})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "GetGroupMemberIDs", err)
|
||||
return
|
||||
}
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification}
|
||||
if err := s.conversationRpcClient.SetConversations(nctx, resp.UserIDs, conversation); err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, resp.UserIDs, conversation)
|
||||
}
|
||||
}()
|
||||
num++
|
||||
s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser})
|
||||
//args := &pbConversation.ModifyConversationFieldReq{
|
||||
// Conversation: &pbConversation.Conversation{
|
||||
// OwnerUserID: mcontext.GetOpUserID(ctx),
|
||||
// ConversationID: utils.GetConversationIDBySessionType(constant.GroupChatType, group.GroupID),
|
||||
// ConversationType: constant.SuperGroupChatType,
|
||||
// GroupID: group.GroupID,
|
||||
// },
|
||||
// FieldType: constant.FieldGroupAtType,
|
||||
// UserIDList: userIDs,
|
||||
//}
|
||||
//if err := s.conversationRpcClient.ModifyConversationField(ctx, args); err != nil {
|
||||
// log.ZWarn(ctx, "modifyConversationField failed", err, "args", args)
|
||||
//}
|
||||
|
||||
}
|
||||
switch len(data) - num {
|
||||
case 0:
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCreateCountReq) (*group.GroupCreateCountResp, error) {
|
||||
if req.Start > req.End {
|
||||
return nil, errs.ErrArgs.Wrap("start > end")
|
||||
}
|
||||
total, err := s.GroupDatabase.CountTotal(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
start := time.UnixMilli(req.Start)
|
||||
before, err := s.GroupDatabase.CountTotal(ctx, &start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count, err := s.GroupDatabase.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &group.GroupCreateCountResp{Total: total, Before: before, Count: count}, nil
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
@@ -85,7 +84,7 @@ func (m *msgServer) MarkMsgsAsRead(ctx context.Context, req *msg.MarkMsgsAsReadR
|
||||
return
|
||||
}
|
||||
currentHasReadSeq, err := m.MsgDatabase.GetHasReadSeq(ctx, req.UserID, req.ConversationID)
|
||||
if err != nil && errors.Unwrap(err) != redis.Nil {
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return
|
||||
}
|
||||
if hasReadSeq > currentHasReadSeq {
|
||||
@@ -111,8 +110,12 @@ func (m *msgServer) MarkConversationAsRead(ctx context.Context, req *msg.MarkCon
|
||||
}
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "hasReadSeq", hasReadSeq, "req.HasReadSeq", req.HasReadSeq)
|
||||
var seqs []int64
|
||||
for i := hasReadSeq + 1; i <= req.HasReadSeq; i++ {
|
||||
seqs = append(seqs, i)
|
||||
if len(req.Seqs) == 0 {
|
||||
for i := hasReadSeq + 1; i <= req.HasReadSeq; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
} else {
|
||||
seqs = req.Seqs
|
||||
}
|
||||
if len(seqs) > 0 {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
|
||||
|
||||
@@ -1,361 +0,0 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
)
|
||||
|
||||
func (m *msgServer) SetMessageReactionExtensions(ctx context.Context, req *msg.SetMessageReactionExtensionsReq) (resp *msg.SetMessageReactionExtensionsResp, err error) {
|
||||
//resp = &msg.SetMessageReactionExtensionsResp{}
|
||||
////resp.ClientMsgID = req.ClientMsgID
|
||||
////resp.MsgFirstModifyTime = req.MsgFirstModifyTime
|
||||
//
|
||||
//if err := CallbackSetMessageReactionExtensions(ctx, req); err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
////if ExternalExtension
|
||||
//if req.IsExternalExtensions {
|
||||
// resp.MsgFirstModifyTime = req.MsgFirstModifyTime
|
||||
// notification.ExtendMessageUpdatedNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &resp, !req.IsReact, false)
|
||||
// return resp, nil
|
||||
//}
|
||||
//isExists, err := m.MsgDatabase.JudgeMessageReactionExist(ctx, req.ClientMsgID, req.SessionType)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//
|
||||
//if !isExists {
|
||||
// if !req.IsReact {
|
||||
// resp.MsgFirstModifyTime = utils.GetCurrentTimestampByMill()
|
||||
// for k, v := range req.ReactionExtensions {
|
||||
// err := m.MessageLocker.LockMessageTypeKey(ctx, req.ClientMsgID, k)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// v.LatestUpdateTime = utils.GetCurrentTimestampByMill()
|
||||
// if err := m.MsgDatabase.SetMessageTypeKeyValue(ctx, req.ClientMsgID, req.SessionType, k, utils.StructToJsonString(v)); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
// resp.IsReact = true
|
||||
// _, err := m.MsgDatabase.SetMessageReactionExpire(ctx, req.ClientMsgID, req.SessionType, time.Duration(24*3)*time.Hour)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// } else {
|
||||
// err := m.MessageLocker.LockGlobalMessage(ctx, req.ClientMsgID)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// mongoValue, err := m.MsgDatabase.GetExtendMsg(ctx, req.conversationID, req.SessionType, req.ClientMsgID, req.MsgFirstModifyTime)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// setValue := make(map[string]*sdkws.KeyValue)
|
||||
// for k, v := range req.ReactionExtensions {
|
||||
//
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// if vv, ok := mongoValue.ReactionExtensions[k]; ok {
|
||||
// utils.CopyStructFields(temp, &vv)
|
||||
// if v.LatestUpdateTime != vv.LatestUpdateTime {
|
||||
// setKeyResultInfo(&resp, 300, "message have update", req.ClientMsgID, k, temp)
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// temp.TypeKey = k
|
||||
// temp.Value = v.Value
|
||||
// temp.LatestUpdateTime = utils.GetCurrentTimestampByMill()
|
||||
// setValue[k] = temp
|
||||
// }
|
||||
// err = db.DB.InsertOrUpdateReactionExtendMsgSet(req.conversationID, req.SessionType, req.ClientMsgID, req.MsgFirstModifyTime, setValue)
|
||||
// if err != nil {
|
||||
// for _, value := range setValue {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = err.Error()
|
||||
// temp.ErrCode = 100
|
||||
// resp.Result = append(resp.Result, temp)
|
||||
// }
|
||||
// } else {
|
||||
// for _, value := range setValue {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// resp.Result = append(resp.Result, temp)
|
||||
// }
|
||||
// }
|
||||
// lockErr := m.dMessageLocker.UnLockGlobalMessage(req.ClientMsgID)
|
||||
// if lockErr != nil {
|
||||
// log.Error(req.OperationID, "UnLockGlobalMessage err:", lockErr.Error())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//} else {
|
||||
// log.Debug(req.OperationID, "redis handle secondly", req.String())
|
||||
//
|
||||
// for k, v := range req.Pb2Model {
|
||||
// err := m.dMessageLocker.LockMessageTypeKey(req.ClientMsgID, k)
|
||||
// if err != nil {
|
||||
// setKeyResultInfo(&resp, 100, err.Error(), req.ClientMsgID, k, v)
|
||||
// continue
|
||||
// }
|
||||
// redisValue, err := db.DB.GetMessageTypeKeyValue(req.ClientMsgID, req.SessionType, k)
|
||||
// if err != nil && err != go_redis.Nil {
|
||||
// setKeyResultInfo(&resp, 200, err.Error(), req.ClientMsgID, k, v)
|
||||
// continue
|
||||
// }
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// utils.JsonStringToStruct(redisValue, temp)
|
||||
// if v.LatestUpdateTime != temp.LatestUpdateTime {
|
||||
// setKeyResultInfo(&resp, 300, "message have update", req.ClientMsgID, k, temp)
|
||||
// continue
|
||||
// } else {
|
||||
// v.LatestUpdateTime = utils.GetCurrentTimestampByMill()
|
||||
// newerr := db.DB.SetMessageTypeKeyValue(req.ClientMsgID, req.SessionType, k, utils.StructToJsonString(v))
|
||||
// if newerr != nil {
|
||||
// setKeyResultInfo(&resp, 201, newerr.Error(), req.ClientMsgID, k, temp)
|
||||
// continue
|
||||
// }
|
||||
// setKeyResultInfo(&resp, 0, "", req.ClientMsgID, k, v)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
//if !isExists {
|
||||
// if !req.IsReact {
|
||||
// notification.ExtendMessageUpdatedNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &resp, true, true)
|
||||
// } else {
|
||||
// notification.ExtendMessageUpdatedNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &resp, false, false)
|
||||
// }
|
||||
//} else {
|
||||
// notification.ExtendMessageUpdatedNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &resp, false, true)
|
||||
//}
|
||||
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m return is:", resp.String())
|
||||
return resp, nil
|
||||
|
||||
}
|
||||
func (m *msgServer) setKeyResultInfo(ctx context.Context, r *msg.SetMessageReactionExtensionsResp, errCode int32, errMsg, clientMsgID, typeKey string, keyValue *sdkws.KeyValue) {
|
||||
temp := new(msg.KeyValueResp)
|
||||
temp.KeyValue = keyValue
|
||||
temp.ErrCode = errCode
|
||||
temp.ErrMsg = errMsg
|
||||
r.Result = append(r.Result, temp)
|
||||
_ = m.MessageLocker.UnLockMessageTypeKey(ctx, clientMsgID, typeKey)
|
||||
}
|
||||
func (m *msgServer) setDeleteKeyResultInfo(ctx context.Context, r *msg.DeleteMessagesReactionExtensionsResp, errCode int32, errMsg, clientMsgID, typeKey string, keyValue *sdkws.KeyValue) {
|
||||
temp := new(msg.KeyValueResp)
|
||||
temp.KeyValue = keyValue
|
||||
temp.ErrCode = errCode
|
||||
temp.ErrMsg = errMsg
|
||||
r.Result = append(r.Result, temp)
|
||||
_ = m.MessageLocker.UnLockMessageTypeKey(ctx, clientMsgID, typeKey)
|
||||
}
|
||||
|
||||
func (m *msgServer) GetMessagesReactionExtensions(ctx context.Context, req *msg.GetMessagesReactionExtensionsReq) (resp *msg.GetMessagesReactionExtensionsResp, err error) {
|
||||
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
|
||||
//var rResp msg.GetMessageListReactionExtensionsResp
|
||||
//for _, messageValue := range req.MessageReactionKeyList {
|
||||
// var oneMessage msg.SingleMessageExtensionResult
|
||||
// oneMessage.ClientMsgID = messageValue.ClientMsgID
|
||||
//
|
||||
// isExists, err := db.DB.JudgeMessageReactionExist(messageValue.ClientMsgID, req.SessionType)
|
||||
// if err != nil {
|
||||
// rResp.ErrCode = 100
|
||||
// rResp.ErrMsg = err.Error()
|
||||
// return &rResp, nil
|
||||
// }
|
||||
// if isExists {
|
||||
// redisValue, err := db.DB.GetOneMessageAllReactionList(messageValue.ClientMsgID, req.SessionType)
|
||||
// if err != nil {
|
||||
// oneMessage.ErrCode = 100
|
||||
// oneMessage.ErrMsg = err.Error()
|
||||
// rResp.SingleMessageResult = append(rResp.SingleMessageResult, &oneMessage)
|
||||
// continue
|
||||
// }
|
||||
// keyMap := make(map[string]*sdkws.KeyValue)
|
||||
//
|
||||
// for k, v := range redisValue {
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// utils.JsonStringToStruct(v, temp)
|
||||
// keyMap[k] = temp
|
||||
// }
|
||||
// oneMessage.Pb2Model = keyMap
|
||||
//
|
||||
// } else {
|
||||
// mongoValue, err := db.DB.GetExtendMsg(req.conversationID, req.SessionType, messageValue.ClientMsgID, messageValue.MsgFirstModifyTime)
|
||||
// if err != nil {
|
||||
// oneMessage.ErrCode = 100
|
||||
// oneMessage.ErrMsg = err.Error()
|
||||
// rResp.SingleMessageResult = append(rResp.SingleMessageResult, &oneMessage)
|
||||
// continue
|
||||
// }
|
||||
// keyMap := make(map[string]*sdkws.KeyValue)
|
||||
//
|
||||
// for k, v := range mongoValue.Pb2Model {
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// temp.TypeKey = v.TypeKey
|
||||
// temp.Value = v.Value
|
||||
// temp.LatestUpdateTime = v.LatestUpdateTime
|
||||
// keyMap[k] = temp
|
||||
// }
|
||||
// oneMessage.Pb2Model = keyMap
|
||||
// }
|
||||
// rResp.SingleMessageResult = append(rResp.SingleMessageResult, &oneMessage)
|
||||
//}
|
||||
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m return is:", rResp.String())
|
||||
return resp, nil
|
||||
|
||||
}
|
||||
|
||||
func (m *msgServer) AddMessageReactionExtensions(ctx context.Context, req *msg.ModifyMessageReactionExtensionsReq) (resp *msg.ModifyMessageReactionExtensionsResp, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *msgServer) DeleteMessageReactionExtensions(ctx context.Context, req *msg.DeleteMessagesReactionExtensionsReq) (resp *msg.DeleteMessagesReactionExtensionsResp, err error) {
|
||||
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
|
||||
//var rResp msg.DeleteMessagesReactionExtensionsResp
|
||||
//callbackResp := notification.callbackDeleteMessageReactionExtensions(req)
|
||||
//if callbackResp.ActionCode != constant.ActionAllow || callbackResp.ErrCode != 0 {
|
||||
// rResp.ErrCode = int32(callbackResp.ErrCode)
|
||||
// rResp.ErrMsg = callbackResp.ErrMsg
|
||||
// for _, value := range req.Pb2Model {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = callbackResp.ErrMsg
|
||||
// temp.ErrCode = 100
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// return &rResp, nil
|
||||
//}
|
||||
////if ExternalExtension
|
||||
//if req.IsExternalExtensions {
|
||||
// rResp.Result = callbackResp.ResultReactionExtensionList
|
||||
// notification.ExtendMessageDeleteNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &rResp, false, false)
|
||||
// return &rResp, nil
|
||||
//
|
||||
//}
|
||||
//for _, v := range callbackResp.ResultReactionExtensions {
|
||||
// if v.ErrCode != 0 {
|
||||
// func(req *[]*sdkws.KeyValue, typeKey string) {
|
||||
// for i := 0; i < len(*req); i++ {
|
||||
// if (*req)[i].TypeKey == typeKey {
|
||||
// *req = append((*req)[:i], (*req)[i+1:]...)
|
||||
// }
|
||||
// }
|
||||
// }(&req.Pb2Model, v.KeyValue.TypeKey)
|
||||
// rResp.Result = append(rResp.Result, v)
|
||||
// }
|
||||
//}
|
||||
//isExists, err := db.DB.JudgeMessageReactionExist(req.ClientMsgID, req.SessionType)
|
||||
//if err != nil {
|
||||
// rResp.ErrCode = 100
|
||||
// rResp.ErrMsg = err.Error()
|
||||
// for _, value := range req.Pb2Model {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = err.Error()
|
||||
// temp.ErrCode = 100
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// return &rResp, nil
|
||||
//}
|
||||
//
|
||||
//if isExists {
|
||||
// log.Debug(req.OperationID, "redis handle this delete", req.String())
|
||||
// for _, v := range req.Pb2Model {
|
||||
// err := m.dMessageLocker.LockMessageTypeKey(req.ClientMsgID, v.TypeKey)
|
||||
// if err != nil {
|
||||
// setDeleteKeyResultInfo(&rResp, 100, err.Error(), req.ClientMsgID, v.TypeKey, v)
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// redisValue, err := db.DB.GetMessageTypeKeyValue(req.ClientMsgID, req.SessionType, v.TypeKey)
|
||||
// if err != nil && err != go_redis.Nil {
|
||||
// setDeleteKeyResultInfo(&rResp, 200, err.Error(), req.ClientMsgID, v.TypeKey, v)
|
||||
// continue
|
||||
// }
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// utils.JsonStringToStruct(redisValue, temp)
|
||||
// if v.LatestUpdateTime != temp.LatestUpdateTime {
|
||||
// setDeleteKeyResultInfo(&rResp, 300, "message have update", req.ClientMsgID, v.TypeKey, temp)
|
||||
// continue
|
||||
// } else {
|
||||
// newErr := db.DB.DeleteOneMessageKey(req.ClientMsgID, req.SessionType, v.TypeKey)
|
||||
// if newErr != nil {
|
||||
// setDeleteKeyResultInfo(&rResp, 201, newErr.Error(), req.ClientMsgID, v.TypeKey, temp)
|
||||
// continue
|
||||
// }
|
||||
// setDeleteKeyResultInfo(&rResp, 0, "", req.ClientMsgID, v.TypeKey, v)
|
||||
// }
|
||||
// }
|
||||
//} else {
|
||||
// err := m.dMessageLocker.LockGlobalMessage(req.ClientMsgID)
|
||||
// if err != nil {
|
||||
// rResp.ErrCode = 100
|
||||
// rResp.ErrMsg = err.Error()
|
||||
// for _, value := range req.Pb2Model {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = err.Error()
|
||||
// temp.ErrCode = 100
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// return &rResp, nil
|
||||
// }
|
||||
// mongoValue, err := db.DB.GetExtendMsg(req.conversationID, req.SessionType, req.ClientMsgID, req.MsgFirstModifyTime)
|
||||
// if err != nil {
|
||||
// rResp.ErrCode = 200
|
||||
// rResp.ErrMsg = err.Error()
|
||||
// for _, value := range req.Pb2Model {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = err.Error()
|
||||
// temp.ErrCode = 100
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// return &rResp, nil
|
||||
// }
|
||||
// setValue := make(map[string]*sdkws.KeyValue)
|
||||
// for _, v := range req.Pb2Model {
|
||||
//
|
||||
// temp := new(sdkws.KeyValue)
|
||||
// if vv, ok := mongoValue.Pb2Model[v.TypeKey]; ok {
|
||||
// utils.CopyStructFields(temp, &vv)
|
||||
// if v.LatestUpdateTime != vv.LatestUpdateTime {
|
||||
// setDeleteKeyResultInfo(&rResp, 300, "message have update", req.ClientMsgID, v.TypeKey, temp)
|
||||
// continue
|
||||
// }
|
||||
// } else {
|
||||
// setDeleteKeyResultInfo(&rResp, 400, "key not in", req.ClientMsgID, v.TypeKey, v)
|
||||
// continue
|
||||
// }
|
||||
// temp.TypeKey = v.TypeKey
|
||||
// setValue[v.TypeKey] = temp
|
||||
// }
|
||||
// err = db.DB.DeleteReactionExtendMsgSet(req.conversationID, req.SessionType, req.ClientMsgID, req.MsgFirstModifyTime, setValue)
|
||||
// if err != nil {
|
||||
// for _, value := range setValue {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// temp.ErrMsg = err.Error()
|
||||
// temp.ErrCode = 100
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// } else {
|
||||
// for _, value := range setValue {
|
||||
// temp := new(msg.KeyValueResp)
|
||||
// temp.KeyValue = value
|
||||
// rResp.Result = append(rResp.Result, temp)
|
||||
// }
|
||||
// }
|
||||
// lockErr := m.dMessageLocker.UnLockGlobalMessage(req.ClientMsgID)
|
||||
// if lockErr != nil {
|
||||
// log.Error(req.OperationID, "UnLockGlobalMessage err:", lockErr.Error())
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//notification.ExtendMessageDeleteNotification(req.OperationID, req.OpUserID, req.conversationID, req.SessionType, req, &rResp, false, isExists)
|
||||
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m return is:", rResp.String())
|
||||
return resp, nil
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cbapi "github.com/OpenIMSDK/Open-IM-Server/pkg/callbackstruct"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/http"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
)
|
||||
|
||||
func callbackSetMessageReactionExtensions(ctx context.Context, setReq *msg.SetMessageReactionExtensionsReq) error {
|
||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackBeforeSetMessageReactionExtReq{
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
CallbackCommand: constant.CallbackBeforeSetMessageReactionExtensionCommand,
|
||||
ConversationID: setReq.ConversationID,
|
||||
OpUserID: mcontext.GetOpUserID(ctx),
|
||||
SessionType: setReq.SessionType,
|
||||
ReactionExtensionList: setReq.ReactionExtensions,
|
||||
ClientMsgID: setReq.ClientMsgID,
|
||||
IsReact: setReq.IsReact,
|
||||
IsExternalExtensions: setReq.IsExternalExtensions,
|
||||
MsgFirstModifyTime: setReq.MsgFirstModifyTime,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeSetMessageReactionExtResp{}
|
||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
setReq.MsgFirstModifyTime = resp.MsgFirstModifyTime
|
||||
return nil
|
||||
}
|
||||
|
||||
func callbackDeleteMessageReactionExtensions(ctx context.Context, setReq *msg.DeleteMessagesReactionExtensionsReq) error {
|
||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackDeleteMessageReactionExtReq{
|
||||
OperationID: setReq.OperationID,
|
||||
CallbackCommand: constant.CallbackBeforeDeleteMessageReactionExtensionsCommand,
|
||||
ConversationID: setReq.ConversationID,
|
||||
OpUserID: setReq.OpUserID,
|
||||
SessionType: setReq.SessionType,
|
||||
ReactionExtensionList: setReq.ReactionExtensions,
|
||||
ClientMsgID: setReq.ClientMsgID,
|
||||
IsExternalExtensions: setReq.IsExternalExtensions,
|
||||
MsgFirstModifyTime: setReq.MsgFirstModifyTime,
|
||||
}
|
||||
resp := &cbapi.CallbackDeleteMessageReactionExtResp{}
|
||||
return http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg)
|
||||
}
|
||||
|
||||
func callbackGetMessageListReactionExtensions(ctx context.Context, getReq *msg.GetMessagesReactionExtensionsReq) error {
|
||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackGetMessageListReactionExtReq{
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
CallbackCommand: constant.CallbackGetMessageListReactionExtensionsCommand,
|
||||
ConversationID: getReq.ConversationID,
|
||||
OpUserID: mcontext.GetOperationID(ctx),
|
||||
SessionType: getReq.SessionType,
|
||||
TypeKeyList: getReq.TypeKeys,
|
||||
}
|
||||
resp := &cbapi.CallbackGetMessageListReactionExtResp{}
|
||||
return http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg)
|
||||
}
|
||||
|
||||
func callbackAddMessageReactionExtensions(ctx context.Context, setReq *msg.ModifyMessageReactionExtensionsReq) error {
|
||||
req := &cbapi.CallbackAddMessageReactionExtReq{
|
||||
OperationID: mcontext.GetOperationID(ctx),
|
||||
CallbackCommand: constant.CallbackAddMessageListReactionExtensionsCommand,
|
||||
ConversationID: setReq.ConversationID,
|
||||
OpUserID: mcontext.GetOperationID(ctx),
|
||||
SessionType: setReq.SessionType,
|
||||
ReactionExtensionList: setReq.ReactionExtensions,
|
||||
ClientMsgID: setReq.ClientMsgID,
|
||||
IsReact: setReq.IsReact,
|
||||
IsExternalExtensions: setReq.IsExternalExtensions,
|
||||
MsgFirstModifyTime: setReq.MsgFirstModifyTime,
|
||||
}
|
||||
resp := &cbapi.CallbackAddMessageReactionExtResp{}
|
||||
return http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg)
|
||||
}
|
||||
@@ -40,49 +40,56 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
||||
if len(msgs) == 0 || msgs[0] == nil {
|
||||
return nil, errs.ErrRecordNotFound.Wrap("msg not found")
|
||||
}
|
||||
// todo: 判断是否已经撤回
|
||||
if msgs[0].ContentType == constant.MsgRevokeNotification {
|
||||
return nil, errs.ErrMsgAlreadyRevoke.Wrap("msg already revoke")
|
||||
}
|
||||
data, _ := json.Marshal(msgs[0])
|
||||
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
||||
var role int32
|
||||
if !tokenverify.IsAppManagerUid(ctx) {
|
||||
switch msgs[0].SessionType {
|
||||
case constant.SingleChatType:
|
||||
if err := tokenverify.CheckAccessV3(ctx, msgs[0].SendID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
role = user.AppMangerLevel
|
||||
case constant.SuperGroupChatType:
|
||||
members, err := m.Group.GetGroupMemberInfoMap(ctx, msgs[0].GroupID, utils.Distinct([]string{req.UserID, msgs[0].SendID}), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.UserID != msgs[0].SendID {
|
||||
roleLevel := members[req.UserID].RoleLevel
|
||||
switch members[req.UserID].RoleLevel {
|
||||
case constant.GroupOwner:
|
||||
case constant.GroupAdmin:
|
||||
if roleLevel != constant.GroupOrdinaryUsers {
|
||||
if members[msgs[0].SendID].RoleLevel != constant.GroupOrdinaryUsers {
|
||||
return nil, errs.ErrNoPermission.Wrap("no permission")
|
||||
}
|
||||
default:
|
||||
return nil, errs.ErrNoPermission.Wrap("no permission")
|
||||
}
|
||||
}
|
||||
if member := members[req.UserID]; member != nil {
|
||||
role = member.RoleLevel
|
||||
}
|
||||
default:
|
||||
return nil, errs.ErrInternalServer.Wrap("msg sessionType not supported")
|
||||
}
|
||||
}
|
||||
now := time.Now().UnixMilli()
|
||||
err = m.MsgDatabase.RevokeMsg(ctx, req.ConversationID, req.Seq, &unRelationTb.RevokeModel{
|
||||
Role: role,
|
||||
UserID: req.UserID,
|
||||
Nickname: user.Nickname,
|
||||
Time: time.Now().UnixMilli(),
|
||||
Time: now,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tips := sdkws.RevokeMsgTips{
|
||||
RevokerUserID: req.UserID,
|
||||
ClientMsgID: "",
|
||||
RevokeTime: utils.GetCurrentTimestampByMill(),
|
||||
ClientMsgID: msgs[0].ClientMsgID,
|
||||
RevokeTime: now,
|
||||
Seq: req.Seq,
|
||||
SesstionType: msgs[0].SessionType,
|
||||
ConversationID: req.ConversationID,
|
||||
|
||||
+67
-15
@@ -5,28 +5,36 @@ import (
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
promePkg "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
|
||||
pbMsg "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
)
|
||||
|
||||
func (m *msgServer) SendMsg(ctx context.Context, req *pbMsg.SendMsgReq) (resp *pbMsg.SendMsgResp, error error) {
|
||||
resp = &pbMsg.SendMsgResp{}
|
||||
flag := isMessageHasReadEnabled(req.MsgData)
|
||||
if !flag {
|
||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||
}
|
||||
m.encapsulateMsgData(req.MsgData)
|
||||
switch req.MsgData.SessionType {
|
||||
case constant.SingleChatType:
|
||||
return m.sendMsgSingleChat(ctx, req)
|
||||
case constant.NotificationChatType:
|
||||
return m.sendMsgNotification(ctx, req)
|
||||
case constant.SuperGroupChatType:
|
||||
return m.sendMsgSuperGroupChat(ctx, req)
|
||||
default:
|
||||
return nil, errs.ErrArgs.Wrap("unknown sessionType")
|
||||
if req.MsgData != nil {
|
||||
flag := isMessageHasReadEnabled(req.MsgData)
|
||||
if !flag {
|
||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||
}
|
||||
m.encapsulateMsgData(req.MsgData)
|
||||
switch req.MsgData.SessionType {
|
||||
case constant.SingleChatType:
|
||||
return m.sendMsgSingleChat(ctx, req)
|
||||
case constant.NotificationChatType:
|
||||
return m.sendMsgNotification(ctx, req)
|
||||
case constant.SuperGroupChatType:
|
||||
return m.sendMsgSuperGroupChat(ctx, req)
|
||||
default:
|
||||
return nil, errs.ErrArgs.Wrap("unknown sessionType")
|
||||
}
|
||||
} else {
|
||||
return nil, errs.ErrArgs.Wrap("msgData is nil")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +54,9 @@ func (m *msgServer) sendMsgSuperGroupChat(ctx context.Context, req *pbMsg.SendMs
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.MsgData.ContentType == constant.AtText {
|
||||
go m.setConversationAtInfo(ctx, req.MsgData)
|
||||
}
|
||||
if err = callbackAfterSendGroupMsg(ctx, req); err != nil {
|
||||
log.ZWarn(ctx, "CallbackAfterSendGroupMsg", err)
|
||||
}
|
||||
@@ -56,6 +67,47 @@ func (m *msgServer) sendMsgSuperGroupChat(ctx context.Context, req *pbMsg.SendMs
|
||||
resp.ClientMsgID = req.MsgData.ClientMsgID
|
||||
return resp, nil
|
||||
}
|
||||
func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgData) {
|
||||
log.ZDebug(nctx, "setConversationAtInfo", "msg", msg)
|
||||
ctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(nctx))
|
||||
var atUserID []string
|
||||
conversation := &pbConversation.ConversationReq{
|
||||
ConversationID: utils.GetConversationIDByMsg(msg),
|
||||
ConversationType: msg.SessionType,
|
||||
GroupID: msg.GroupID,
|
||||
}
|
||||
tagAll := utils.IsContain(constant.AtAllString, msg.AtUserIDList)
|
||||
if tagAll {
|
||||
memberUserIDList, err := m.Group.GetGroupMemberIDs(ctx, msg.GroupID)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "GetGroupMemberIDs", err)
|
||||
return
|
||||
}
|
||||
atUserID = utils.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList)
|
||||
if len(atUserID) == 0 { //just @everyone
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
||||
} else { //@Everyone and @other people
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
|
||||
err := m.Conversation.SetConversations(ctx, atUserID, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
||||
}
|
||||
memberUserIDList = utils.DifferenceString(atUserID, memberUserIDList)
|
||||
}
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
||||
err = m.Conversation.SetConversations(ctx, memberUserIDList, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, "userID", memberUserIDList, "conversation", conversation)
|
||||
}
|
||||
} else {
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtMe}
|
||||
err := m.Conversation.SetConversations(ctx, msg.AtUserIDList, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (m *msgServer) sendMsgNotification(ctx context.Context, req *pbMsg.SendMsgReq) (resp *pbMsg.SendMsgResp, err error) {
|
||||
promePkg.Inc(promePkg.SingleChatMsgRecvSuccessCounter)
|
||||
@@ -86,7 +138,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbMsg.SendMsgReq
|
||||
}
|
||||
if !isSend {
|
||||
promePkg.Inc(promePkg.SingleChatMsgProcessFailedCounter)
|
||||
return nil, errs.ErrUserNotRecvMsg
|
||||
return nil, nil
|
||||
} else {
|
||||
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/localcache"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/tx"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
@@ -21,7 +20,6 @@ type MessageInterceptorChain []MessageInterceptorFunc
|
||||
type msgServer struct {
|
||||
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
|
||||
MsgDatabase controller.CommonMsgDatabase
|
||||
ExtendMsgDatabase controller.ExtendMsgDatabase
|
||||
Group *rpcclient.GroupRpcClient
|
||||
User *rpcclient.UserRpcClient
|
||||
Conversation *rpcclient.ConversationRpcClient
|
||||
@@ -62,9 +60,6 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
}
|
||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
||||
extendMsgModel := unrelation.NewExtendMsgSetMongoDriver(mongo.GetDatabase())
|
||||
extendMsgCacheModel := cache.NewExtendMsgSetCacheRedis(rdb, extendMsgModel, cache.GetDefaultOpt())
|
||||
extendMsgDatabase := controller.NewExtendMsgDatabase(extendMsgModel, extendMsgCacheModel, tx.NewMongo(mongo.GetClient()))
|
||||
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
|
||||
conversationClient := rpcclient.NewConversationRpcClient(client)
|
||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
||||
@@ -75,10 +70,9 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
||||
User: &userRpcClient,
|
||||
Group: &groupRpcClient,
|
||||
MsgDatabase: msgDatabase,
|
||||
ExtendMsgDatabase: extendMsgDatabase,
|
||||
RegisterCenter: client,
|
||||
GroupLocalCache: localcache.NewGroupLocalCache(client),
|
||||
ConversationLocalCache: localcache.NewConversationLocalCache(client),
|
||||
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
|
||||
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
|
||||
friend: &friendRpcClient,
|
||||
MessageLocker: NewLockerMessage(cacheModel),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq) (*msg.GetActiveUserResp, error) {
|
||||
msgCount, userCount, users, dateCount, err := m.MsgDatabase.RangeUserSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Group, req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbUsers []*msg.ActiveUser
|
||||
if len(users) > 0 {
|
||||
userIDs := utils.Slice(users, func(e *unrelation.UserCount) string { return e.UserID })
|
||||
userMap, err := m.User.GetUsersInfoMap(ctx, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbUsers = make([]*msg.ActiveUser, 0, len(users))
|
||||
for _, user := range users {
|
||||
pbUser := userMap[user.UserID]
|
||||
if pbUser == nil {
|
||||
pbUser = &sdkws.UserInfo{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.UserID,
|
||||
}
|
||||
}
|
||||
pbUsers = append(pbUsers, &msg.ActiveUser{
|
||||
User: pbUser,
|
||||
Count: user.Count,
|
||||
})
|
||||
}
|
||||
}
|
||||
return &msg.GetActiveUserResp{
|
||||
MsgCount: msgCount,
|
||||
UserCount: userCount,
|
||||
DateCount: dateCount,
|
||||
Users: pbUsers,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupReq) (*msg.GetActiveGroupResp, error) {
|
||||
msgCount, groupCount, groups, dateCount, err := m.MsgDatabase.RangeGroupSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbGroups []*msg.ActiveGroup
|
||||
if len(groups) > 0 {
|
||||
groupIDs := utils.Slice(groups, func(e *unrelation.GroupCount) string { return e.GroupID })
|
||||
resp, err := m.Group.GetGroupInfos(ctx, groupIDs, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupMap := make(map[string]*sdkws.GroupInfo, len(groups))
|
||||
for i, group := range groups {
|
||||
groupMap[group.GroupID] = resp[i]
|
||||
}
|
||||
pbGroups = make([]*msg.ActiveGroup, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
pbGroup := groupMap[group.GroupID]
|
||||
if pbGroup == nil {
|
||||
pbGroup = &sdkws.GroupInfo{
|
||||
GroupID: group.GroupID,
|
||||
GroupName: group.GroupID,
|
||||
}
|
||||
}
|
||||
pbGroups = append(pbGroups, &msg.ActiveGroup{
|
||||
Group: pbGroup,
|
||||
Count: group.Count,
|
||||
})
|
||||
}
|
||||
}
|
||||
return &msg.GetActiveGroupResp{
|
||||
MsgCount: msgCount,
|
||||
GroupCount: groupCount,
|
||||
DateCount: dateCount,
|
||||
Groups: pbGroups,
|
||||
}, nil
|
||||
}
|
||||
@@ -38,7 +38,7 @@ type MessageRevoked struct {
|
||||
func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgReq) error {
|
||||
switch data.MsgData.SessionType {
|
||||
case constant.SingleChatType:
|
||||
if utils.IsContain(data.MsgData.SendID, config.Config.Manager.AppManagerUid) {
|
||||
if utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
||||
return nil
|
||||
}
|
||||
if data.MsgData.ContentType <= constant.NotificationEnd && data.MsgData.ContentType >= constant.NotificationBegin {
|
||||
@@ -73,7 +73,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
||||
if groupInfo.GroupType == constant.SuperGroup {
|
||||
return nil
|
||||
}
|
||||
if utils.IsContain(data.MsgData.SendID, config.Config.Manager.AppManagerUid) {
|
||||
if utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
||||
return nil
|
||||
}
|
||||
if data.MsgData.ContentType <= constant.NotificationEnd && data.MsgData.ContentType >= constant.NotificationBegin {
|
||||
|
||||
+132
-18
@@ -2,36 +2,150 @@ package third
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (t *thirdServer) ApplyPut(ctx context.Context, req *third.ApplyPutReq) (*third.ApplyPutResp, error) {
|
||||
return t.s3dataBase.ApplyPut(ctx, req)
|
||||
func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) {
|
||||
limit := t.s3dataBase.PartLimit()
|
||||
return &third.PartLimitResp{
|
||||
MinPartSize: limit.MinPartSize,
|
||||
MaxPartSize: limit.MaxPartSize,
|
||||
MaxNumSize: int32(limit.MaxNumSize),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) GetPut(ctx context.Context, req *third.GetPutReq) (*third.GetPutResp, error) {
|
||||
return t.s3dataBase.GetPut(ctx, req)
|
||||
func (t *thirdServer) PartSize(ctx context.Context, req *third.PartSizeReq) (*third.PartSizeResp, error) {
|
||||
size, err := t.s3dataBase.PartSize(ctx, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.PartSizeResp{Size: size}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) ConfirmPut(ctx context.Context, req *third.ConfirmPutReq) (*third.ConfirmPutResp, error) {
|
||||
return t.s3dataBase.ConfirmPut(ctx, req)
|
||||
}
|
||||
|
||||
func (t *thirdServer) GetUrl(ctx context.Context, req *third.GetUrlReq) (*third.GetUrlResp, error) {
|
||||
if req.Expires <= 0 {
|
||||
if err := tokenverify.CheckAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.InitiateMultipartUploadReq) (*third.InitiateMultipartUploadResp, error) {
|
||||
defer log.ZDebug(ctx, "return")
|
||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expireTime := time.Now().Add(t.defaultExpire)
|
||||
result, err := t.s3dataBase.InitiateMultipartUpload(ctx, req.Hash, req.Size, t.defaultExpire, int(req.MaxParts))
|
||||
if err != nil {
|
||||
if haErr, ok := errs.Unwrap(err).(*cont.HashAlreadyExistsError); ok {
|
||||
obj := &relation.ObjectModel{
|
||||
Name: req.Name,
|
||||
UserID: mcontext.GetOpUserID(ctx),
|
||||
Hash: req.Hash,
|
||||
Key: haErr.Object.Key,
|
||||
Size: haErr.Object.Size,
|
||||
ContentType: req.ContentType,
|
||||
Cause: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.InitiateMultipartUploadResp{
|
||||
Url: t.apiAddress(obj.Name),
|
||||
}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var sign *third.AuthSignParts
|
||||
if result.Sign != nil && len(result.Sign.Parts) > 0 {
|
||||
sign = &third.AuthSignParts{
|
||||
Url: result.Sign.URL,
|
||||
Query: toPbMapArray(result.Sign.Query),
|
||||
Header: toPbMapArray(result.Sign.Header),
|
||||
Parts: make([]*third.SignPart, len(result.Sign.Parts)),
|
||||
}
|
||||
for i, part := range result.Sign.Parts {
|
||||
sign.Parts[i] = &third.SignPart{
|
||||
PartNumber: int32(part.PartNumber),
|
||||
Url: part.URL,
|
||||
Query: toPbMapArray(part.Query),
|
||||
Header: toPbMapArray(part.Header),
|
||||
}
|
||||
}
|
||||
}
|
||||
return t.s3dataBase.GetUrl(ctx, req)
|
||||
return &third.InitiateMultipartUploadResp{
|
||||
Upload: &third.UploadInfo{
|
||||
UploadID: result.UploadID,
|
||||
PartSize: result.PartSize,
|
||||
Sign: sign,
|
||||
ExpireTime: expireTime.UnixMilli(),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) GetHashInfo(ctx context.Context, req *third.GetHashInfoReq) (*third.GetHashInfoResp, error) {
|
||||
return t.s3dataBase.GetHashInfo(ctx, req)
|
||||
func (t *thirdServer) AuthSign(ctx context.Context, req *third.AuthSignReq) (*third.AuthSignResp, error) {
|
||||
defer log.ZDebug(ctx, "return")
|
||||
partNumbers := utils.Slice(req.PartNumbers, func(partNumber int32) int { return int(partNumber) })
|
||||
result, err := t.s3dataBase.AuthSign(ctx, req.UploadID, partNumbers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := &third.AuthSignResp{
|
||||
Url: result.URL,
|
||||
Query: toPbMapArray(result.Query),
|
||||
Header: toPbMapArray(result.Header),
|
||||
Parts: make([]*third.SignPart, len(result.Parts)),
|
||||
}
|
||||
for i, part := range result.Parts {
|
||||
resp.Parts[i] = &third.SignPart{
|
||||
PartNumber: int32(part.PartNumber),
|
||||
Url: part.URL,
|
||||
Query: toPbMapArray(part.Query),
|
||||
Header: toPbMapArray(part.Header),
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) CleanObject(ctx context.Context, now time.Time) {
|
||||
t.s3dataBase.CleanExpirationObject(ctx, now)
|
||||
func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.CompleteMultipartUploadReq) (*third.CompleteMultipartUploadResp, error) {
|
||||
defer log.ZDebug(ctx, "return")
|
||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := t.s3dataBase.CompleteMultipartUpload(ctx, req.UploadID, req.Parts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj := &relation.ObjectModel{
|
||||
Name: req.Name,
|
||||
UserID: mcontext.GetOpUserID(ctx),
|
||||
Hash: result.Hash,
|
||||
Key: result.Key,
|
||||
Size: result.Size,
|
||||
ContentType: req.ContentType,
|
||||
Cause: req.Cause,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.s3dataBase.SetObject(ctx, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.CompleteMultipartUploadResp{
|
||||
Url: t.apiAddress(obj.Name),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (*third.AccessURLResp, error) {
|
||||
expireTime, rawURL, err := t.s3dataBase.AccessURL(ctx, req.Name, t.defaultExpire)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.AccessURLResp{
|
||||
Url: rawURL,
|
||||
ExpireTime: expireTime.UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) apiAddress(name string) string {
|
||||
return t.apiURL + name
|
||||
}
|
||||
|
||||
+38
-11
@@ -2,12 +2,17 @@ package third
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/obj"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
|
||||
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
@@ -17,37 +22,59 @@ import (
|
||||
)
|
||||
|
||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
u, err := url.Parse(config.Config.Object.ApiURL)
|
||||
if err != nil {
|
||||
apiURL := config.Config.Object.ApiURL
|
||||
if apiURL == "" {
|
||||
return fmt.Errorf("api url is empty")
|
||||
}
|
||||
if _, err := url.Parse(config.Config.Object.ApiURL); err != nil {
|
||||
return err
|
||||
}
|
||||
if apiURL[len(apiURL)-1] != '/' {
|
||||
apiURL += "/"
|
||||
}
|
||||
rdb, err := cache.NewRedis()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o, err := obj.NewMinioInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := relation.NewGormDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.AutoMigrate(&relationTb.ObjectHashModel{}, &relationTb.ObjectInfoModel{}, &relationTb.ObjectPutModel{}); err != nil {
|
||||
if err := db.AutoMigrate(&relationTb.ObjectModel{}); err != nil {
|
||||
return err
|
||||
}
|
||||
// 根据配置文件策略选择 oss 方式
|
||||
enable := config.Config.Object.Enable
|
||||
var o s3.Interface
|
||||
switch config.Config.Object.Enable {
|
||||
case "minio":
|
||||
o, err = minio.NewMinio()
|
||||
case "cos":
|
||||
o, err = cos.NewCos()
|
||||
case "oss":
|
||||
o, err = oss.NewOSS()
|
||||
default:
|
||||
err = fmt.Errorf("invalid object enable: %s", enable)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
third.RegisterThirdServer(server, &thirdServer{
|
||||
apiURL: apiURL,
|
||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb)),
|
||||
userRpcClient: rpcclient.NewUserClient(client),
|
||||
s3dataBase: controller.NewS3Database(o, relation.NewObjectHash(db), relation.NewObjectInfo(db), relation.NewObjectPut(db), u),
|
||||
userRpcClient: rpcclient.NewUserRpcClient(client),
|
||||
s3dataBase: controller.NewS3Database(o, relation.NewObjectInfo(db)),
|
||||
defaultExpire: time.Hour * 24 * 7,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type thirdServer struct {
|
||||
apiURL string
|
||||
thirdDatabase controller.ThirdDatabase
|
||||
s3dataBase controller.S3Database
|
||||
userRpcClient *rpcclient.UserClient
|
||||
userRpcClient rpcclient.UserRpcClient
|
||||
defaultExpire time.Duration
|
||||
}
|
||||
|
||||
func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package third
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
||||
res := make([]*third.KeyValues, 0, len(m))
|
||||
for key := range m {
|
||||
res = append(res, &third.KeyValues{
|
||||
Key: key,
|
||||
Values: m[key],
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func checkUploadName(ctx context.Context, name string) error {
|
||||
if name == "" {
|
||||
return errs.ErrArgs.Wrap("name is empty")
|
||||
}
|
||||
if name[0] == '/' {
|
||||
return errs.ErrArgs.Wrap("name cannot start with `/`")
|
||||
}
|
||||
if err := checkValidObjectName(name); err != nil {
|
||||
return errs.ErrArgs.Wrap(err.Error())
|
||||
}
|
||||
opUserID := mcontext.GetOpUserID(ctx)
|
||||
if opUserID == "" {
|
||||
return errs.ErrNoPermission.Wrap("opUserID is empty")
|
||||
}
|
||||
if !tokenverify.IsManagerUserID(opUserID) {
|
||||
if !strings.HasPrefix(name, opUserID+"/") {
|
||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("name must start with `%s/`", opUserID))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkValidObjectNamePrefix(objectName string) error {
|
||||
if len(objectName) > 1024 {
|
||||
return errors.New("object name cannot be longer than 1024 characters")
|
||||
}
|
||||
if !utf8.ValidString(objectName) {
|
||||
return errors.New("object name with non UTF-8 strings are not supported")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkValidObjectName(objectName string) error {
|
||||
if strings.TrimSpace(objectName) == "" {
|
||||
return errors.New("object name cannot be empty")
|
||||
}
|
||||
return checkValidObjectNamePrefix(objectName)
|
||||
}
|
||||
@@ -11,13 +11,18 @@ func (s *userServer) UserRegisterCount(ctx context.Context, req *pbuser.UserRegi
|
||||
if req.Start > req.End {
|
||||
return nil, errs.ErrArgs.Wrap("start > end")
|
||||
}
|
||||
total, err := s.CountTotal(ctx)
|
||||
total, err := s.CountTotal(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count, err := s.CountRangeEverydayTotal(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End))
|
||||
start := time.UnixMilli(req.Start)
|
||||
before, err := s.CountTotal(ctx, &start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbuser.UserRegisterCountResp{Total: total, Count: count}, nil
|
||||
count, err := s.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbuser.UserRegisterCountResp{Total: total, Before: before, Count: count}, nil
|
||||
}
|
||||
|
||||
+11
-10
@@ -2,6 +2,8 @@ package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -45,27 +47,27 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||
return err
|
||||
}
|
||||
users := make([]*tablerelation.UserModel, 0)
|
||||
if len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname) {
|
||||
return errs.ErrConfig.Wrap("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)")
|
||||
if len(config.Config.Manager.UserID) != len(config.Config.Manager.Nickname) {
|
||||
return errors.New("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)")
|
||||
}
|
||||
for k, v := range config.Config.Manager.AppManagerUid {
|
||||
for k, v := range config.Config.Manager.UserID {
|
||||
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k]})
|
||||
}
|
||||
userDB := relation.NewUserGorm(db)
|
||||
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
||||
database := controller.NewUserDatabase(userDB, cache, tx.NewGorm(db))
|
||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
||||
u := &userServer{
|
||||
UserDatabase: database,
|
||||
RegisterCenter: client,
|
||||
friendRpcClient: &friendRpcClient,
|
||||
notificationSender: notification.NewFriendNotificationSender(client, notification.WithDBFunc(database.FindWithError)),
|
||||
notificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
||||
}
|
||||
pbuser.RegisterUserServer(server, u)
|
||||
return u.UserDatabase.InitOnce(context.Background(), users)
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesignateUsersReq) (resp *pbuser.GetDesignateUsersResp, err error) {
|
||||
resp = &pbuser.GetDesignateUsersResp{}
|
||||
users, err := s.FindWithError(ctx, req.UserIDs)
|
||||
@@ -79,7 +81,6 @@ func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesig
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
||||
resp = &pbuser.UpdateUserInfoResp{}
|
||||
err = tokenverify.CheckAccessV3(ctx, req.UserInfo.UserID)
|
||||
@@ -105,7 +106,6 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.SetGlobalRecvMessageOptReq) (resp *pbuser.SetGlobalRecvMessageOptResp, err error) {
|
||||
resp = &pbuser.SetGlobalRecvMessageOptResp{}
|
||||
if _, err := s.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
@@ -120,7 +120,6 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckReq) (resp *pbuser.AccountCheckResp, err error) {
|
||||
resp = &pbuser.AccountCheckResp{}
|
||||
if utils.Duplicate(req.CheckUserIDs) {
|
||||
@@ -150,7 +149,6 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) {
|
||||
var pageNumber, showNumber int32
|
||||
if req.Pagination != nil {
|
||||
@@ -164,12 +162,15 @@ func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPagi
|
||||
return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err
|
||||
}
|
||||
|
||||
// ok
|
||||
func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterReq) (resp *pbuser.UserRegisterResp, err error) {
|
||||
resp = &pbuser.UserRegisterResp{}
|
||||
if len(req.Users) == 0 {
|
||||
return nil, errs.ErrArgs.Wrap("users is empty")
|
||||
}
|
||||
if req.Secret != config.Config.Secret {
|
||||
log.ZDebug(ctx, "UserRegister", config.Config.Secret, req.Secret)
|
||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||
}
|
||||
if utils.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
||||
return nil, errs.ErrArgs.Wrap("userID repeated")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
)
|
||||
|
||||
func (c *MsgTool) ConversationsDestructMsgs() {
|
||||
log.ZInfo(context.Background(), "start msg destruct cron task")
|
||||
ctx := mcontext.NewCtx(utils.GetSelfFuncName())
|
||||
conversations, err := c.conversationDatabase.GetConversationIDsNeedDestruct(ctx)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "get conversation id need destruct failed", err)
|
||||
return
|
||||
}
|
||||
log.ZDebug(context.Background(), "nums conversations need destruct", "nums", len(conversations))
|
||||
for _, conversation := range conversations {
|
||||
log.ZDebug(ctx, "UserMsgsDestruct", "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID, "msgDestructTime", conversation.MsgDestructTime, "lastMsgDestructTime", conversation.LatestMsgDestructTime)
|
||||
seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||
continue
|
||||
}
|
||||
if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": time.Now()}); err != nil {
|
||||
log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||
continue
|
||||
}
|
||||
if len(seqs) > 0 {
|
||||
if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil {
|
||||
log.ZError(ctx, "userDeleteMsgsNotification failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func StartCronTask() error {
|
||||
log.ZInfo(context.Background(), "start cron task", "cron config", config.Config.Mongo.ChatRecordsClearTime)
|
||||
fmt.Println("cron task start, config", config.Config.Mongo.ChatRecordsClearTime)
|
||||
fmt.Println("cron task start, config", config.Config.ChatRecordsClearTime)
|
||||
msgTool, err := InitMsgTool()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -20,10 +19,17 @@ func StartCronTask() error {
|
||||
c := cron.New()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
_, err = c.AddFunc(config.Config.Mongo.ChatRecordsClearTime, msgTool.AllConversationClearMsgAndFixSeq)
|
||||
log.ZInfo(context.Background(), "start chatRecordsClearTime cron task", "cron config", config.Config.ChatRecordsClearTime)
|
||||
_, err = c.AddFunc(config.Config.ChatRecordsClearTime, msgTool.AllConversationClearMsgAndFixSeq)
|
||||
if err != nil {
|
||||
fmt.Println("start cron failed", err.Error(), config.Config.Mongo.ChatRecordsClearTime)
|
||||
return err
|
||||
fmt.Println("start allConversationClearMsgAndFixSeq cron failed", err.Error(), config.Config.ChatRecordsClearTime)
|
||||
panic(err)
|
||||
}
|
||||
log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime)
|
||||
_, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs)
|
||||
if err != nil {
|
||||
fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime)
|
||||
panic(err)
|
||||
}
|
||||
c.Start()
|
||||
wg.Wait()
|
||||
|
||||
+38
-18
@@ -2,9 +2,9 @@ package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
|
||||
@@ -14,24 +14,33 @@ import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry/zookeeper"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
type MsgTool struct {
|
||||
msgDatabase controller.CommonMsgDatabase
|
||||
conversationDatabase controller.ConversationDatabase
|
||||
userDatabase controller.UserDatabase
|
||||
groupDatabase controller.GroupDatabase
|
||||
msgDatabase controller.CommonMsgDatabase
|
||||
conversationDatabase controller.ConversationDatabase
|
||||
userDatabase controller.UserDatabase
|
||||
groupDatabase controller.GroupDatabase
|
||||
msgNotificationSender *notification.MsgNotificationSender
|
||||
}
|
||||
|
||||
var errSeq = errors.New("cache max seq and mongo max seq is diff > 10")
|
||||
|
||||
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase, groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase) *MsgTool {
|
||||
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
|
||||
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender) *MsgTool {
|
||||
return &MsgTool{
|
||||
msgDatabase: msgDatabase,
|
||||
userDatabase: userDatabase,
|
||||
groupDatabase: groupDatabase,
|
||||
conversationDatabase: conversationDatabase,
|
||||
msgDatabase: msgDatabase,
|
||||
userDatabase: userDatabase,
|
||||
groupDatabase: groupDatabase,
|
||||
conversationDatabase: conversationDatabase,
|
||||
msgNotificationSender: msgNotificationSender,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,12 +57,21 @@ func InitMsgTool() (*MsgTool, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
userDB := relation.NewUserGorm(db)
|
||||
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
|
||||
userDatabase := controller.NewUserDatabase(userDB, cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()), tx.NewGorm(db))
|
||||
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
|
||||
conversationDatabase := controller.NewConversationDatabase(relation.NewConversationGorm(db), cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)), tx.NewGorm(db))
|
||||
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase)
|
||||
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
|
||||
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
|
||||
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender)
|
||||
return msgTool, nil
|
||||
}
|
||||
|
||||
@@ -74,23 +92,22 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
|
||||
|
||||
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
|
||||
for _, conversationID := range conversationIDs {
|
||||
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(config.Config.Mongo.DBRetainChatRecords*24*60*60)); err != nil {
|
||||
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", config.Config.Mongo.DBRetainChatRecords)
|
||||
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(config.Config.RetainChatRecords*24*60*60)); err != nil {
|
||||
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", config.Config.RetainChatRecords)
|
||||
}
|
||||
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
|
||||
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (c *MsgTool) checkMaxSeqWithMongo(ctx context.Context, conversationID string, maxSeqCache int64) error {
|
||||
maxSeqMongo, _, err := c.msgDatabase.GetMongoMaxAndMinSeq(ctx, conversationID)
|
||||
minSeqMongo, maxSeqMongo, err := c.msgDatabase.GetMongoMaxAndMinSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
|
||||
return errSeq
|
||||
log.ZError(ctx, "cache max seq and mongo max seq is diff > 10", nil, "maxSeqMongo", maxSeqMongo, "minSeqMongo", minSeqMongo, "maxSeqCache", maxSeqCache, "conversationID", conversationID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -98,6 +115,9 @@ func (c *MsgTool) checkMaxSeqWithMongo(ctx context.Context, conversationID strin
|
||||
func (c *MsgTool) checkMaxSeq(ctx context.Context, conversationID string) error {
|
||||
maxSeq, err := c.msgDatabase.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
if errs.Unwrap(err) == redis.Nil {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err := c.checkMaxSeqWithMongo(ctx, conversationID, maxSeq); err != nil {
|
||||
|
||||
+4
-6
@@ -2,6 +2,7 @@ package a2r
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/checker"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/apiresp"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
|
||||
@@ -21,12 +22,9 @@ func Call[A, B, C any](
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap()) // 参数错误
|
||||
return
|
||||
}
|
||||
if check, ok := any(&req).(interface{ Check() error }); ok {
|
||||
if err := check.Check(); err != nil {
|
||||
log.ZWarn(c, "custom check error", err, "req", req)
|
||||
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error())) // 参数校验失败
|
||||
return
|
||||
}
|
||||
if err := checker.Validate(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error())) // 参数校验失败
|
||||
return
|
||||
}
|
||||
data, err := rpc(client, c, &req)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package apiresp
|
||||
|
||||
type ApiFormat interface {
|
||||
ApiFormat()
|
||||
}
|
||||
@@ -34,6 +34,9 @@ func isAllFieldsPrivate(v any) bool {
|
||||
}
|
||||
|
||||
func ApiSuccess(data any) *ApiResponse {
|
||||
if format, ok := data.(ApiFormat); ok {
|
||||
format.ApiFormat()
|
||||
}
|
||||
if isAllFieldsPrivate(data) {
|
||||
return &ApiResponse{}
|
||||
}
|
||||
|
||||
+1
-69
@@ -1,10 +1,5 @@
|
||||
package apistruct
|
||||
|
||||
import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
)
|
||||
|
||||
type DelMsgReq struct {
|
||||
UserID string `json:"userID,omitempty" binding:"required"`
|
||||
SeqList []uint32 `json:"seqList,omitempty" binding:"required"`
|
||||
@@ -49,69 +44,6 @@ type SetMsgMinSeqReq struct {
|
||||
type SetMsgMinSeqResp struct {
|
||||
}
|
||||
|
||||
type ModifyMessageReactionExtensionsReq struct {
|
||||
OperationID string `json:"operationID" binding:"required"`
|
||||
conversationID string `json:"conversationID" binding:"required"`
|
||||
SessionType int32 `json:"sessionType" binding:"required"`
|
||||
ReactionExtensionList map[string]*sdkws.KeyValue `json:"reactionExtensionList,omitempty" binding:"required"`
|
||||
ClientMsgID string `json:"clientMsgID" binding:"required"`
|
||||
Ex *string `json:"ex"`
|
||||
AttachedInfo *string `json:"attachedInfo"`
|
||||
IsReact bool `json:"isReact"`
|
||||
IsExternalExtensions bool `json:"isExternalExtensions"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
|
||||
type ModifyMessageReactionExtensionsResp struct {
|
||||
Data struct {
|
||||
ResultKeyValue []*msg.KeyValueResp `json:"result"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
IsReact bool `json:"isReact"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
//type OperateMessageListReactionExtensionsReq struct {
|
||||
// OperationID string `json:"operationID" binding:"required"`
|
||||
// conversationID string `json:"conversationID" binding:"required"`
|
||||
// SessionType string `json:"sessionType" binding:"required"`
|
||||
// MessageReactionKeyList []*msg.GetMessageListReactionExtensionsReq_MessageReactionKey `json:"messageReactionKeyList" binding:"required"`
|
||||
//}
|
||||
|
||||
type OperateMessageListReactionExtensionsResp struct {
|
||||
Data struct {
|
||||
SuccessList []*msg.ExtendMsgResp `json:"successList"`
|
||||
FailedList []*msg.ExtendMsgResp `json:"failedList"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type SetMessageReactionExtensionsCallbackReq ModifyMessageReactionExtensionsReq
|
||||
|
||||
type SetMessageReactionExtensionsCallbackResp ModifyMessageReactionExtensionsResp
|
||||
|
||||
//type GetMessageListReactionExtensionsReq OperateMessageListReactionExtensionsReq
|
||||
|
||||
type GetMessageListReactionExtensionsResp struct {
|
||||
Data []*msg.SingleMessageExtensionResult `json:"data"`
|
||||
}
|
||||
|
||||
type AddMessageReactionExtensionsReq ModifyMessageReactionExtensionsReq
|
||||
|
||||
type AddMessageReactionExtensionsResp ModifyMessageReactionExtensionsResp
|
||||
|
||||
type DeleteMessageReactionExtensionsReq struct {
|
||||
OperationID string `json:"operationID" binding:"required"`
|
||||
conversationID string `json:"conversationID" binding:"required"`
|
||||
SessionType int32 `json:"sessionType" binding:"required"`
|
||||
ClientMsgID string `json:"clientMsgID" binding:"required"`
|
||||
IsExternalExtensions bool `json:"isExternalExtensions"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime" binding:"required"`
|
||||
ReactionExtensionList []*sdkws.KeyValue `json:"reactionExtensionList" binding:"required"`
|
||||
}
|
||||
|
||||
type DeleteMessageReactionExtensionsResp struct {
|
||||
Data []*msg.KeyValueResp
|
||||
}
|
||||
|
||||
type PictureBaseInfo struct {
|
||||
UUID string `mapstructure:"uuid"`
|
||||
Type string `mapstructure:"type" `
|
||||
@@ -171,7 +103,7 @@ type CustomElem struct {
|
||||
Extension string `mapstructure:"extension"`
|
||||
}
|
||||
type TextElem struct {
|
||||
Text string `mapstructure:"text" validate:"required"`
|
||||
Content string `mapstructure:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type RevokeElem struct {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package callbackstruct
|
||||
|
||||
import (
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
|
||||
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
|
||||
)
|
||||
|
||||
@@ -66,71 +65,3 @@ type CallbackMsgModifyCommandResp struct {
|
||||
AttachedInfo *string `json:"attachedInfo"`
|
||||
Ex *string `json:"ex"`
|
||||
}
|
||||
type CallbackBeforeSetMessageReactionExtReq struct {
|
||||
OperationID string `json:"operationID"`
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
ConversationID string `json:"conversationID"`
|
||||
OpUserID string `json:"opUserID"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
ReactionExtensionList map[string]*sdkws.KeyValue `json:"reactionExtensionList"`
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
IsReact bool `json:"isReact"`
|
||||
IsExternalExtensions bool `json:"isExternalExtensions"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
type CallbackBeforeSetMessageReactionExtResp struct {
|
||||
CommonCallbackResp
|
||||
ResultReactionExtensionList []*msg.KeyValueResp `json:"resultReactionExtensionList"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
type CallbackDeleteMessageReactionExtReq struct {
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
OperationID string `json:"operationID"`
|
||||
ConversationID string `json:"conversationID"`
|
||||
OpUserID string `json:"opUserID"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
ReactionExtensionList []*sdkws.KeyValue `json:"reactionExtensionList"`
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
IsExternalExtensions bool `json:"isExternalExtensions"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
type CallbackDeleteMessageReactionExtResp struct {
|
||||
CommonCallbackResp
|
||||
ResultReactionExtensionList []*msg.KeyValueResp `json:"resultReactionExtensionList"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
|
||||
type CallbackGetMessageListReactionExtReq struct {
|
||||
OperationID string `json:"operationID"`
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
ConversationID string `json:"conversationID"`
|
||||
OpUserID string `json:"opUserID"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
TypeKeyList []string `json:"typeKeyList"`
|
||||
//MessageKeyList []*msg.GetMessageListReactionExtensionsReq_MessageReactionKey `json:"messageKeyList"`
|
||||
}
|
||||
|
||||
type CallbackGetMessageListReactionExtResp struct {
|
||||
CommonCallbackResp
|
||||
MessageResultList []*msg.SingleMessageExtensionResult `json:"messageResultList"`
|
||||
}
|
||||
|
||||
type CallbackAddMessageReactionExtReq struct {
|
||||
OperationID string `json:"operationID"`
|
||||
CallbackCommand `json:"callbackCommand"`
|
||||
ConversationID string `json:"conversationID"`
|
||||
OpUserID string `json:"opUserID"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
ReactionExtensionList map[string]*sdkws.KeyValue `json:"reactionExtensionList"`
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
IsReact bool `json:"isReact"`
|
||||
IsExternalExtensions bool `json:"isExternalExtensions"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
|
||||
type CallbackAddMessageReactionExtResp struct {
|
||||
CommonCallbackResp
|
||||
ResultReactionExtensionList []*msg.KeyValueResp `json:"resultReactionExtensionList"`
|
||||
IsReact bool `json:"isReact"`
|
||||
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package checker
|
||||
|
||||
type Checker interface {
|
||||
Check() error
|
||||
}
|
||||
|
||||
func Validate(args any) error {
|
||||
if checker, ok := args.(Checker); ok {
|
||||
if err := checker.Check(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -7,7 +7,7 @@ type CronTaskCmd struct {
|
||||
}
|
||||
|
||||
func NewCronTaskCmd() *CronTaskCmd {
|
||||
return &CronTaskCmd{NewRootCmd("cronTask")}
|
||||
return &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
|
||||
}
|
||||
|
||||
func (c *CronTaskCmd) addRunE(f func() error) {
|
||||
|
||||
+28
-5
@@ -16,17 +16,40 @@ type RootCmd struct {
|
||||
prometheusPort int
|
||||
}
|
||||
|
||||
func NewRootCmd(name string) (rootCmd *RootCmd) {
|
||||
type CmdOpts struct {
|
||||
loggerPrefixName string
|
||||
}
|
||||
|
||||
func WithCronTaskLogName() func(*CmdOpts) {
|
||||
return func(opts *CmdOpts) {
|
||||
opts.loggerPrefixName = "OpenIM.CronTask.log.all"
|
||||
}
|
||||
}
|
||||
|
||||
func WithLogName(logName string) func(*CmdOpts) {
|
||||
return func(opts *CmdOpts) {
|
||||
opts.loggerPrefixName = logName
|
||||
}
|
||||
}
|
||||
|
||||
func NewRootCmd(name string, opts ...func(*CmdOpts)) (rootCmd *RootCmd) {
|
||||
rootCmd = &RootCmd{Name: name}
|
||||
c := cobra.Command{
|
||||
Use: "start",
|
||||
Short: fmt.Sprintf(`Start %s server`, name),
|
||||
Long: fmt.Sprintf(`Start %s server`, name),
|
||||
Use: "start openIM application",
|
||||
Short: fmt.Sprintf(`Start %s `, name),
|
||||
Long: fmt.Sprintf(`Start %s `, name),
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := rootCmd.getConfFromCmdAndInit(cmd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := log.InitFromConfig("OpenIM.log.all", name, config.Config.Log.RemainLogLevel, config.Config.Log.IsStdout, config.Config.Log.IsJson, config.Config.Log.StorageLocation, config.Config.Log.RemainRotationCount); err != nil {
|
||||
cmdOpts := &CmdOpts{}
|
||||
for _, opt := range opts {
|
||||
opt(cmdOpts)
|
||||
}
|
||||
if cmdOpts.loggerPrefixName == "" {
|
||||
cmdOpts.loggerPrefixName = "OpenIM.log.all"
|
||||
}
|
||||
if err := log.InitFromConfig(cmdOpts.loggerPrefixName, name, config.Config.Log.RemainLogLevel, config.Config.Log.IsStdout, config.Config.Log.IsJson, config.Config.Log.StorageLocation, config.Config.Log.RemainRotationCount); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -26,7 +26,7 @@ func (a *RpcCmd) Exec() error {
|
||||
return a.Execute()
|
||||
}
|
||||
|
||||
func (a *RpcCmd) StartSvr(name string, rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
||||
func (a *RpcCmd) StartSvr(name string, rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
||||
if a.GetPortFlag() == 0 {
|
||||
return errors.New("port is required")
|
||||
}
|
||||
|
||||
+141
-273
@@ -2,42 +2,17 @@ package config
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
|
||||
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed version
|
||||
var Version string
|
||||
|
||||
var (
|
||||
_, b, _, _ = runtime.Caller(0)
|
||||
// Root folder of this project
|
||||
Root = filepath.Join(filepath.Dir(b), "../../..")
|
||||
)
|
||||
|
||||
const (
|
||||
FileName = "config.yaml"
|
||||
NotificationFileName = "notification.yaml"
|
||||
ENV = "CONFIG_NAME"
|
||||
DefaultFolderPath = "../config/"
|
||||
ConfKey = "conf"
|
||||
)
|
||||
|
||||
var Config config
|
||||
|
||||
type CallBackConfig struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
CallbackTimeOut int `yaml:"callbackTimeOut"`
|
||||
CallbackFailedContinue *bool `yaml:"callbackFailedContinue"`
|
||||
CallbackTimeOut int `yaml:"timeout"`
|
||||
CallbackFailedContinue *bool `yaml:"failedContinue"`
|
||||
}
|
||||
|
||||
type NotificationConf struct {
|
||||
@@ -55,100 +30,97 @@ type POfflinePush struct {
|
||||
}
|
||||
|
||||
type config struct {
|
||||
ServerIP string `yaml:"serverip"`
|
||||
Zookeeper struct {
|
||||
Schema string `yaml:"schema"`
|
||||
ZkAddr []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"zookeeper"`
|
||||
|
||||
RpcRegisterIP string `yaml:"rpcRegisterIP"`
|
||||
ListenIP string `yaml:"listenIP"`
|
||||
Mysql struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Database string `yaml:"database"`
|
||||
MaxOpenConn int `yaml:"maxOpenConn"`
|
||||
MaxIdleConn int `yaml:"maxIdleConn"`
|
||||
MaxLifeTime int `yaml:"maxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
} `yaml:"mysql"`
|
||||
|
||||
ServerVersion string `yaml:"serverversion"`
|
||||
Api struct {
|
||||
GinPort []int `yaml:"openImApiPort"`
|
||||
ListenIP string `yaml:"listenIP"`
|
||||
}
|
||||
Sdk struct {
|
||||
WsPort []int `yaml:"openImSdkWsPort"`
|
||||
DataDir []string `yaml:"dataDir"`
|
||||
}
|
||||
Credential struct {
|
||||
}
|
||||
Mongo struct {
|
||||
Uri string `yaml:"uri"`
|
||||
Address []string `yaml:"address"`
|
||||
Database string `yaml:"database"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
MaxPoolSize int `yaml:"maxPoolSize"`
|
||||
} `yaml:"mongo"`
|
||||
|
||||
Redis struct {
|
||||
Address []string `yaml:"address"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"redis"`
|
||||
|
||||
Kafka struct {
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
Addr []string `yaml:"addr"`
|
||||
LatestMsgToRedis struct {
|
||||
Topic string `yaml:"topic"`
|
||||
} `yaml:"latestMsgToRedis"`
|
||||
MsgToMongo struct {
|
||||
Topic string `yaml:"topic"`
|
||||
} `yaml:"offlineMsgToMongo"`
|
||||
MsgToPush struct {
|
||||
Topic string `yaml:"topic"`
|
||||
} `yaml:"msgToPush"`
|
||||
ConsumerGroupID struct {
|
||||
MsgToRedis string `yaml:"msgToRedis"`
|
||||
MsgToMongo string `yaml:"msgToMongo"`
|
||||
MsgToMySql string `yaml:"msgToMySql"`
|
||||
MsgToPush string `yaml:"msgToPush"`
|
||||
} `yaml:"consumerGroupID"`
|
||||
} `yaml:"kafka"`
|
||||
|
||||
Rpc struct {
|
||||
RegisterIP string `yaml:"registerIP"`
|
||||
ListenIP string `yaml:"listenIP"`
|
||||
} `yaml:"rpc"`
|
||||
|
||||
Api struct {
|
||||
OpenImApiPort []int `yaml:"openImApiPort"`
|
||||
ListenIP string `yaml:"listenIP"`
|
||||
} `yaml:"api"`
|
||||
|
||||
Object struct {
|
||||
Enable string `yaml:"enable"`
|
||||
ApiURL string `yaml:"apiURL"`
|
||||
Minio struct {
|
||||
TempBucket string `yaml:"tempBucket"`
|
||||
DataBucket string `yaml:"dataBucket"`
|
||||
Location string `yaml:"location"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||
IsDistributedMod bool `yaml:"isDistributedMod"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
SecretAccessKey string `yaml:"secretAccessKey"`
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
} `yaml:"minio"`
|
||||
Tencent struct {
|
||||
AppID string `yaml:"appID"`
|
||||
Region string `yaml:"region"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
SecretID string `yaml:"secretID"`
|
||||
SecretKey string `yaml:"secretKey"`
|
||||
}
|
||||
Ali struct {
|
||||
RegionID string `yaml:"regionID"`
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
AccessKeySecret string `yaml:"accessKeySecret"`
|
||||
StsEndpoint string `yaml:"stsEndpoint"`
|
||||
OssEndpoint string `yaml:"ossEndpoint"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
FinalHost string `yaml:"finalHost"`
|
||||
StsDurationSeconds int64 `yaml:"stsDurationSeconds"`
|
||||
OssRoleArn string `yaml:"OssRoleArn"`
|
||||
}
|
||||
Aws struct {
|
||||
Cos struct {
|
||||
BucketURL string `yaml:"bucketURL"`
|
||||
SecretID string `yaml:"secretID"`
|
||||
SecretKey string `yaml:"secretKey"`
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
} `yaml:"cos"`
|
||||
Oss struct {
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
BucketURL string `yaml:"bucketURL"`
|
||||
AccessKeyID string `yaml:"accessKeyID"`
|
||||
AccessKeySecret string `yaml:"accessKeySecret"`
|
||||
Region string `yaml:"region"`
|
||||
Bucket string `yaml:"bucket"`
|
||||
FinalHost string `yaml:"finalHost"`
|
||||
RoleArn string `yaml:"roleArn"`
|
||||
ExternalId string `yaml:"externalId"`
|
||||
RoleSessionName string `yaml:"roleSessionName"`
|
||||
} `yaml:"aws"`
|
||||
}
|
||||
SessionToken string `yaml:"sessionToken"`
|
||||
} `yaml:"oss"`
|
||||
} `yaml:"object"`
|
||||
|
||||
Mysql struct {
|
||||
DBAddress []string `yaml:"dbMysqlAddress"`
|
||||
DBUserName string `yaml:"dbMysqlUserName"`
|
||||
DBPassword string `yaml:"dbMysqlPassword"`
|
||||
DBDatabaseName string `yaml:"dbMysqlDatabaseName"`
|
||||
DBTableName string `yaml:"DBTableName"`
|
||||
DBMsgTableNum int `yaml:"dbMsgTableNum"`
|
||||
DBMaxOpenConns int `yaml:"dbMaxOpenConns"`
|
||||
DBMaxIdleConns int `yaml:"dbMaxIdleConns"`
|
||||
DBMaxLifeTime int `yaml:"dbMaxLifeTime"`
|
||||
LogLevel int `yaml:"logLevel"`
|
||||
SlowThreshold int `yaml:"slowThreshold"`
|
||||
}
|
||||
Mongo struct {
|
||||
DBUri string `yaml:"dbUri"`
|
||||
DBAddress []string `yaml:"dbAddress"`
|
||||
DBDirect bool `yaml:"dbDirect"`
|
||||
DBTimeout int `yaml:"dbTimeout"`
|
||||
DBDatabase string `yaml:"dbDatabase"`
|
||||
DBSource string `yaml:"dbSource"`
|
||||
DBUserName string `yaml:"dbUserName"`
|
||||
DBPassword string `yaml:"dbPassword"`
|
||||
DBMaxPoolSize int `yaml:"dbMaxPoolSize"`
|
||||
DBRetainChatRecords int `yaml:"dbRetainChatRecords"`
|
||||
ChatRecordsClearTime string `yaml:"chatRecordsClearTime"`
|
||||
}
|
||||
Redis struct {
|
||||
DBAddress []string `yaml:"dbAddress"`
|
||||
DBMaxIdle int `yaml:"dbMaxIdle"`
|
||||
DBMaxActive int `yaml:"dbMaxActive"`
|
||||
DBIdleTimeout int `yaml:"dbIdleTimeout"`
|
||||
DBUserName string `yaml:"dbUserName"`
|
||||
DBPassWord string `yaml:"dbPassWord"`
|
||||
EnableCluster bool `yaml:"enableCluster"`
|
||||
}
|
||||
RpcPort struct {
|
||||
OpenImUserPort []int `yaml:"openImUserPort"`
|
||||
OpenImFriendPort []int `yaml:"openImFriendPort"`
|
||||
@@ -158,10 +130,10 @@ type config struct {
|
||||
OpenImAuthPort []int `yaml:"openImAuthPort"`
|
||||
OpenImPushPort []int `yaml:"openImPushPort"`
|
||||
OpenImConversationPort []int `yaml:"openImConversationPort"`
|
||||
OpenImCachePort []int `yaml:"openImCachePort"`
|
||||
OpenImRtcPort []int `yaml:"openImRtcPort"`
|
||||
OpenImThirdPort []int `yaml:"openImThirdPort"`
|
||||
}
|
||||
} `yaml:"rpcPort"`
|
||||
|
||||
RpcRegisterName struct {
|
||||
OpenImUserName string `yaml:"openImUserName"`
|
||||
OpenImFriendName string `yaml:"openImFriendName"`
|
||||
@@ -171,128 +143,90 @@ type config struct {
|
||||
OpenImGroupName string `yaml:"openImGroupName"`
|
||||
OpenImAuthName string `yaml:"openImAuthName"`
|
||||
OpenImConversationName string `yaml:"openImConversationName"`
|
||||
OpenImRtcName string `yaml:"openImRtcName"`
|
||||
OpenImThirdName string `yaml:"openImThirdName"`
|
||||
}
|
||||
Zookeeper struct {
|
||||
Schema string `yaml:"schema"`
|
||||
ZkAddr []string `yaml:"zkAddr"`
|
||||
UserName string `yaml:"userName"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"zookeeper"`
|
||||
} `yaml:"rpcRegisterName"`
|
||||
|
||||
Log struct {
|
||||
StorageLocation string `yaml:"storageLocation"`
|
||||
RotationTime int `yaml:"rotationTime"`
|
||||
RemainRotationCount uint `yaml:"remainRotationCount"`
|
||||
RemainLogLevel int `yaml:"remainLogLevel"`
|
||||
IsStdout bool `yaml:"isStdout"`
|
||||
WithStack bool `yaml:"withStack"`
|
||||
IsJson bool `yaml:"isJson"`
|
||||
}
|
||||
ModuleName struct {
|
||||
LongConnSvrName string `yaml:"longConnSvrName"`
|
||||
MsgTransferName string `yaml:"msgTransferName"`
|
||||
PushName string `yaml:"pushName"`
|
||||
}
|
||||
WithStack bool `yaml:"withStack"`
|
||||
} `yaml:"log"`
|
||||
|
||||
LongConnSvr struct {
|
||||
WebsocketPort []int `yaml:"openImWsPort"`
|
||||
OpenImWsPort []int `yaml:"openImWsPort"`
|
||||
WebsocketMaxConnNum int `yaml:"websocketMaxConnNum"`
|
||||
WebsocketMaxMsgLen int `yaml:"websocketMaxMsgLen"`
|
||||
WebsocketTimeOut int `yaml:"websocketTimeOut"`
|
||||
}
|
||||
WebsocketTimeout int `yaml:"websocketTimeout"`
|
||||
} `yaml:"longConnSvr"`
|
||||
|
||||
Push struct {
|
||||
Enable string `yaml:"enable"`
|
||||
GeTui struct {
|
||||
PushUrl string `yaml:"pushUrl"`
|
||||
AppKey string `yaml:"appKey"`
|
||||
Intent string `yaml:"intent"`
|
||||
MasterSecret string `yaml:"masterSecret"`
|
||||
ChannelID string `yaml:"channelID"`
|
||||
ChannelName string `yaml:"channelName"`
|
||||
} `yaml:"geTui"`
|
||||
Fcm struct {
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
} `yaml:"fcm"`
|
||||
Jpns struct {
|
||||
AppKey string `yaml:"appKey"`
|
||||
MasterSecret string `yaml:"masterSecret"`
|
||||
PushUrl string `yaml:"pushUrl"`
|
||||
PushIntent string `yaml:"pushIntent"`
|
||||
Enable bool `yaml:"enable"`
|
||||
}
|
||||
Getui struct {
|
||||
PushUrl string `yaml:"pushUrl"`
|
||||
AppKey string `yaml:"appKey"`
|
||||
Enable bool `yaml:"enable"`
|
||||
Intent string `yaml:"intent"`
|
||||
MasterSecret string `yaml:"masterSecret"`
|
||||
ChannelID string `yaml:"channelID"`
|
||||
ChannelName string `yaml:"channelName"`
|
||||
}
|
||||
Fcm struct {
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
Enable bool `yaml:"enable"`
|
||||
}
|
||||
} `yaml:"jpns"`
|
||||
}
|
||||
Manager struct {
|
||||
AppManagerUid []string `yaml:"appManagerUid"`
|
||||
Nickname []string `yaml:"nickname"`
|
||||
}
|
||||
UserID []string `yaml:"userID"`
|
||||
Nickname []string `yaml:"nickname"`
|
||||
} `yaml:"manager"`
|
||||
|
||||
Kafka struct {
|
||||
SASLUserName string `yaml:"SASLUserName"`
|
||||
SASLPassword string `yaml:"SASLPassword"`
|
||||
Ws2mschat struct {
|
||||
Addr []string `yaml:"addr"`
|
||||
Topic string `yaml:"topic"`
|
||||
}
|
||||
MsgToMongo struct {
|
||||
Addr []string `yaml:"addr"`
|
||||
Topic string `yaml:"topic"`
|
||||
}
|
||||
Ms2pschat struct {
|
||||
Addr []string `yaml:"addr"`
|
||||
Topic string `yaml:"topic"`
|
||||
}
|
||||
MsgToModify struct {
|
||||
Addr []string `yaml:"addr"`
|
||||
Topic string `yaml:"topic"`
|
||||
}
|
||||
ConsumerGroupID struct {
|
||||
MsgToRedis string `yaml:"msgToTransfer"`
|
||||
MsgToMongo string `yaml:"msgToMongo"`
|
||||
MsgToMySql string `yaml:"msgToMySql"`
|
||||
MsgToPush string `yaml:"msgToPush"`
|
||||
MsgToModify string `yaml:"msgToModify"`
|
||||
}
|
||||
}
|
||||
Secret string `yaml:"secret"`
|
||||
MultiLoginPolicy int `yaml:"multiloginpolicy"`
|
||||
ChatPersistenceMysql bool `yaml:"chatpersistencemysql"`
|
||||
MultiLoginPolicy int `yaml:"multiLoginPolicy"`
|
||||
ChatPersistenceMysql bool `yaml:"chatPersistenceMysql"`
|
||||
MsgCacheTimeout int `yaml:"msgCacheTimeout"`
|
||||
GroupMessageHasReadReceiptEnable bool `yaml:"groupMessageHasReadReceiptEnable"`
|
||||
SingleMessageHasReadReceiptEnable bool `yaml:"singleMessageHasReadReceiptEnable"`
|
||||
|
||||
TokenPolicy struct {
|
||||
AccessSecret string `yaml:"accessSecret"`
|
||||
AccessExpire int64 `yaml:"accessExpire"`
|
||||
}
|
||||
RetainChatRecords int `yaml:"retainChatRecords"`
|
||||
ChatRecordsClearTime string `yaml:"chatRecordsClearTime"`
|
||||
MsgDestructTime string `yaml:"msgDestructTime"`
|
||||
Secret string `yaml:"secret"`
|
||||
TokenPolicy struct {
|
||||
Expire int64 `yaml:"expire"`
|
||||
} `yaml:"tokenPolicy"`
|
||||
MessageVerify struct {
|
||||
FriendVerify *bool `yaml:"friendVerify"`
|
||||
}
|
||||
} `yaml:"messageVerify"`
|
||||
|
||||
IOSPush struct {
|
||||
PushSound string `yaml:"pushSound"`
|
||||
BadgeCount bool `yaml:"badgeCount"`
|
||||
Production bool `yaml:"production"`
|
||||
}
|
||||
} `yaml:"iosPush"`
|
||||
Callback struct {
|
||||
CallbackUrl string `yaml:"callbackUrl"`
|
||||
CallbackBeforeSendSingleMsg CallBackConfig `yaml:"callbackBeforeSendSingleMsg"`
|
||||
CallbackAfterSendSingleMsg CallBackConfig `yaml:"callbackAfterSendSingleMsg"`
|
||||
CallbackBeforeSendGroupMsg CallBackConfig `yaml:"callbackBeforeSendGroupMsg"`
|
||||
CallbackAfterSendGroupMsg CallBackConfig `yaml:"callbackAfterSendGroupMsg"`
|
||||
CallbackMsgModify CallBackConfig `yaml:"callbackMsgModify"`
|
||||
CallbackUserOnline CallBackConfig `yaml:"callbackUserOnline"`
|
||||
CallbackUserOffline CallBackConfig `yaml:"callbackUserOffline"`
|
||||
CallbackUserKickOff CallBackConfig `yaml:"callbackUserKickOff"`
|
||||
CallbackOfflinePush CallBackConfig `yaml:"callbackOfflinePush"`
|
||||
CallbackOnlinePush CallBackConfig `yaml:"callbackOnlinePush"`
|
||||
CallbackBeforeSuperGroupOnlinePush CallBackConfig `yaml:"callbackSuperGroupOnlinePush"`
|
||||
CallbackBeforeAddFriend CallBackConfig `yaml:"callbackBeforeAddFriend"`
|
||||
CallbackBeforeCreateGroup CallBackConfig `yaml:"callbackBeforeCreateGroup"`
|
||||
CallbackBeforeMemberJoinGroup CallBackConfig `yaml:"callbackBeforeMemberJoinGroup"`
|
||||
CallbackBeforeSetGroupMemberInfo CallBackConfig `yaml:"callbackBeforeSetGroupMemberInfo"`
|
||||
CallbackUrl string `yaml:"url"`
|
||||
CallbackBeforeSendSingleMsg CallBackConfig `yaml:"beforeSendSingleMsg"`
|
||||
CallbackAfterSendSingleMsg CallBackConfig `yaml:"afterSendSingleMsg"`
|
||||
CallbackBeforeSendGroupMsg CallBackConfig `yaml:"beforeSendGroupMsg"`
|
||||
CallbackAfterSendGroupMsg CallBackConfig `yaml:"afterSendGroupMsg"`
|
||||
CallbackMsgModify CallBackConfig `yaml:"msgModify"`
|
||||
CallbackUserOnline CallBackConfig `yaml:"userOnline"`
|
||||
CallbackUserOffline CallBackConfig `yaml:"userOffline"`
|
||||
CallbackUserKickOff CallBackConfig `yaml:"userKickOff"`
|
||||
CallbackOfflinePush CallBackConfig `yaml:"offlinePush"`
|
||||
CallbackOnlinePush CallBackConfig `yaml:"onlinePush"`
|
||||
CallbackBeforeSuperGroupOnlinePush CallBackConfig `yaml:"superGroupOnlinePush"`
|
||||
CallbackBeforeAddFriend CallBackConfig `yaml:"beforeAddFriend"`
|
||||
CallbackBeforeCreateGroup CallBackConfig `yaml:"beforeCreateGroup"`
|
||||
CallbackBeforeMemberJoinGroup CallBackConfig `yaml:"beforeMemberJoinGroup"`
|
||||
CallbackBeforeSetGroupMemberInfo CallBackConfig `yaml:"beforeSetGroupMemberInfo"`
|
||||
} `yaml:"callback"`
|
||||
Notification Notification `yaml:"notification"`
|
||||
|
||||
Prometheus struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
@@ -308,9 +242,10 @@ type config struct {
|
||||
MessageTransferPrometheusPort []int `yaml:"messageTransferPrometheusPort"`
|
||||
ThirdPrometheusPort []int `yaml:"thirdPrometheusPort"`
|
||||
} `yaml:"prometheus"`
|
||||
Notification notification `yaml:"notification"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
type notification struct {
|
||||
GroupCreated NotificationConf `yaml:"groupCreated"`
|
||||
GroupInfoSet NotificationConf `yaml:"groupInfoSet"`
|
||||
JoinGroupApplication NotificationConf `yaml:"joinGroupApplication"`
|
||||
@@ -348,74 +283,7 @@ type Notification struct {
|
||||
ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"`
|
||||
}
|
||||
|
||||
func GetOptionsByNotification(cfg NotificationConf) utils.Options {
|
||||
opts := utils.NewOptions()
|
||||
if cfg.UnreadCount {
|
||||
opts = utils.WithOptions(opts, utils.WithUnreadCount(true))
|
||||
}
|
||||
if cfg.OfflinePush.Enable {
|
||||
opts = utils.WithOptions(opts, utils.WithOfflinePush(true))
|
||||
}
|
||||
switch cfg.ReliabilityLevel {
|
||||
case constant.UnreliableNotification:
|
||||
case constant.ReliableNotificationNoMsg:
|
||||
opts = utils.WithOptions(opts, utils.WithHistory(true), utils.WithPersistent())
|
||||
}
|
||||
opts = utils.WithOptions(opts, utils.WithSendMsg(cfg.IsSendMsg))
|
||||
return opts
|
||||
}
|
||||
|
||||
func (c *config) unmarshalConfig(config interface{}, configPath string) error {
|
||||
bytes, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = yaml.Unmarshal(bytes, config); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *config) initConfig(config interface{}, configName, configFolderPath string) error {
|
||||
if configFolderPath == "" {
|
||||
configFolderPath = DefaultFolderPath
|
||||
}
|
||||
configPath := filepath.Join(configFolderPath, configName)
|
||||
defer func() {
|
||||
fmt.Println("use config", configPath)
|
||||
}()
|
||||
_, err := os.Stat(configPath)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
configPath = filepath.Join(Root, "config", configName)
|
||||
} else {
|
||||
Root = filepath.Dir(configPath)
|
||||
}
|
||||
return c.unmarshalConfig(config, configPath)
|
||||
}
|
||||
|
||||
func (c *config) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRegistry) error {
|
||||
bytes, err := yaml.Marshal(Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return registry.RegisterConf2Registry(ConfKey, bytes)
|
||||
}
|
||||
|
||||
func (c *config) GetConfFromRegistry(registry discoveryregistry.SvcDiscoveryRegistry) ([]byte, error) {
|
||||
return registry.GetConfFromRegistry(ConfKey)
|
||||
}
|
||||
|
||||
func InitConfig(configFolderPath string) error {
|
||||
err := Config.initConfig(&Config, FileName, configFolderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = Config.initConfig(&Config.Notification, NotificationFileName, configFolderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func GetServiceNames() []string {
|
||||
return []string{Config.RpcRegisterName.OpenImUserName, Config.RpcRegisterName.OpenImFriendName, Config.RpcRegisterName.OpenImMsgName, Config.RpcRegisterName.OpenImPushName, Config.RpcRegisterName.OpenImMessageGatewayName,
|
||||
Config.RpcRegisterName.OpenImGroupName, Config.RpcRegisterName.OpenImAuthName, Config.RpcRegisterName.OpenImConversationName, Config.RpcRegisterName.OpenImThirdName}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user