mao-service-discovery 1.6.0-commit-2023-07-24-04-37-15.0 → 1.6.0-commit-2023-07-24-06-22-14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MaoServerDiscovery +0 -0
- package/package.json +1 -1
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/codeql-analysis.yml +0 -75
- package/.github/workflows/docker-image.yml +0 -24
- package/.github/workflows/docker-publish.yml +0 -94
- package/.github/workflows/go.yml +0 -29
- package/.github/workflows/go_static.yml +0 -29
- package/.github/workflows/npm-publish-release.yml +0 -36
- package/.github/workflows/npm-publish.yml +0 -32
- package/Dockerfile +0 -19
- package/LICENSE +0 -201
- package/MODULES.md +0 -39
- package/README.md +0 -54
- package/bak/index.html +0 -42
- package/bak/receiveProcessIcmpLoopV4V6.bak +0 -73
- package/bak/test/test-icmp-ka-module.go +0 -297
- package/bak/test/test-tech.go +0 -110
- package/bak/using_etcd/main.go +0 -165
- package/cmd/api/aux-data-module.go +0 -14
- package/cmd/api/config-module.go +0 -11
- package/cmd/api/email-module.go +0 -14
- package/cmd/api/gateway-module.go +0 -23
- package/cmd/api/grpc-ka-module.go +0 -29
- package/cmd/api/icmp-ka-module.go +0 -26
- package/cmd/api/restful-server-module.go +0 -13
- package/cmd/api/topo-module.go +0 -31
- package/cmd/api/wechat-module.go +0 -18
- package/cmd/general_client.go +0 -366
- package/cmd/lib/AuxDataProcessor/aux-data-processor-module.go +0 -64
- package/cmd/lib/AuxDataProcessor/env-temp-processor.go +0 -63
- package/cmd/lib/AuxDataProcessor/env-temp-processor_test.go +0 -30
- package/cmd/lib/Config/config-yaml-module.go +0 -303
- package/cmd/lib/Config/config-yaml-module_test.go +0 -308
- package/cmd/lib/Email/login-auth.go +0 -35
- package/cmd/lib/Email/login-auth_test.go +0 -13
- package/cmd/lib/Email/smtp-email-module.go +0 -229
- package/cmd/lib/Email/smtp-email-module_test.go +0 -12
- package/cmd/lib/GrpcKa/grpc-detect-module.go +0 -269
- package/cmd/lib/GrpcKa/grpc-detect-module_test.go +0 -26
- package/cmd/lib/IcmpKa/icmp-detect-module.go +0 -545
- package/cmd/lib/IcmpKa/icmp-detect-module_test.go +0 -23
- package/cmd/lib/InfluxDB/influxdb-util.go +0 -72
- package/cmd/lib/MaoCommon/gps.go +0 -15
- package/cmd/lib/MaoCommon/service-registry-util.go +0 -59
- package/cmd/lib/MaoCommon/service-registry.go +0 -14
- package/cmd/lib/MaoCommon/service-registry_test.go +0 -30
- package/cmd/lib/MaoEnhancedGolang/smtp.go +0 -438
- package/cmd/lib/Restful/restful-server-impl.go +0 -87
- package/cmd/lib/Soap/soap-tplink-util.go +0 -186
- package/cmd/lib/Soap/soap-tplink-util_test.go +0 -45
- package/cmd/lib/Soap/tplink-gateway-module.go +0 -200
- package/cmd/server.go +0 -327
- package/go.mod +0 -38
- package/go.sum +0 -222
- package/grpc.maojianwei.com/server/discovery/api/generate_api_from_protobuf.sh +0 -1
- package/grpc.maojianwei.com/server/discovery/api/mao-server-discovery.pb.go +0 -403
- package/grpc.maojianwei.com/server/discovery/api/mao-server-discovery.proto +0 -35
- package/grpc.maojianwei.com/server/discovery/api/mao-server-discovery_grpc.pb.go +0 -207
- package/incubator/OnosTopoShow/onos-topo-module.go +0 -347
- package/incubator/Wechat/wechat-message-module.go +0 -267
- package/incubator/Wechat/wechat-message-module_test.go +0 -108
- package/main.go +0 -383
- package/notebook/notebook.txt +0 -8
- package/resource/index-email.html +0 -67
- package/resource/index-icmp.html +0 -41
- package/resource/index-onos.html +0 -38
- package/resource/index-server.html +0 -57
- package/resource/index-wechat.html +0 -64
- package/resource/jquery-3.6.0.min.js +0 -2
- package/screenshot/2-cli-output.png +0 -0
- package/screenshot/2-cli-parameters.png +0 -0
- package/screenshot/2-json-format.png +0 -0
- package/screenshot/2-readable-format.png +0 -0
- package/screenshot/client-server-mode-1.png +0 -0
- package/screenshot/client-server-mode-2.png +0 -0
- package/screenshot/client-server-mode-production.png +0 -0
- package/screenshot/show_using_etcd.png +0 -0
- package/statically_linked_compilation.sh +0 -2
- package/util/mao_log.go +0 -42
- package/util/mao_log_test.go +0 -73
- package/util/mao_util.go +0 -53
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
package OnosTopoShow
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
MaoApi "MaoServerDiscovery/cmd/api"
|
|
5
|
-
"MaoServerDiscovery/cmd/lib/MaoCommon"
|
|
6
|
-
"MaoServerDiscovery/util"
|
|
7
|
-
"bytes"
|
|
8
|
-
"encoding/json"
|
|
9
|
-
"fmt"
|
|
10
|
-
"github.com/gin-gonic/gin"
|
|
11
|
-
"net/http"
|
|
12
|
-
"time"
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
const (
|
|
16
|
-
MODULE_NAME = "ONOS-Topology-module"
|
|
17
|
-
|
|
18
|
-
ADD_DEVICE_API_SUFFIX = "/MaoIntegration/addDevice"
|
|
19
|
-
REMOVE_DEVICE_API_SUFFIX = "/MaoIntegration/removeDevice"
|
|
20
|
-
ADD_LINK_API_SUFFIX = "/MaoIntegration/addBiLink" // bidirectional link
|
|
21
|
-
REMOVE_LINK_API_SUFFIX = "/MaoIntegration/removeBiLink" // bidirectional link
|
|
22
|
-
|
|
23
|
-
URL_ONOS_HOMEPAGE = "/configOnos"
|
|
24
|
-
URL_ONOS_CONFIG = "/addOnosInfo"
|
|
25
|
-
URL_ONOS_SHOW = "/getOnosInfo"
|
|
26
|
-
|
|
27
|
-
ONOS_CONFIG_PATH = "/ONOS"
|
|
28
|
-
ONOS_API_CONFIG_PATH = "/ONOS/APIs"
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
type OnosTopoModule struct {
|
|
32
|
-
|
|
33
|
-
/* Local info */
|
|
34
|
-
hostname string
|
|
35
|
-
version string
|
|
36
|
-
|
|
37
|
-
/* API Config */
|
|
38
|
-
addrPort string
|
|
39
|
-
ADD_DEVICE_API string
|
|
40
|
-
REMOVE_DEVICE_API string
|
|
41
|
-
DELETE_DEVICE_API string
|
|
42
|
-
ADD_LINK_API string
|
|
43
|
-
REMOVE_LINK_API string
|
|
44
|
-
|
|
45
|
-
/* Internal */
|
|
46
|
-
portIterators map[string]uint
|
|
47
|
-
portMapping map[string]uint // local-remote-protocol => local port number
|
|
48
|
-
|
|
49
|
-
needShutdown bool
|
|
50
|
-
topoEventChannel chan *MaoApi.TopoEvent
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
func (o *OnosTopoModule) RequireShutdown() {
|
|
54
|
-
o.needShutdown = true
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
func (o *OnosTopoModule) InitOnosTopoModule(hostname string, version string) bool {
|
|
58
|
-
o.hostname = hostname
|
|
59
|
-
o.version = version
|
|
60
|
-
o.needShutdown = false
|
|
61
|
-
o.topoEventChannel = make(chan *MaoApi.TopoEvent, 1024)
|
|
62
|
-
|
|
63
|
-
o.portIterators = make(map[string]uint)
|
|
64
|
-
o.portIterators[hostname] = 1
|
|
65
|
-
|
|
66
|
-
o.portMapping = make(map[string]uint)
|
|
67
|
-
|
|
68
|
-
o.configRestControlInterface()
|
|
69
|
-
|
|
70
|
-
go o.topoEventLoop()
|
|
71
|
-
return true
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
func (o *OnosTopoModule) configRestControlInterface() {
|
|
79
|
-
restfulServer := MaoCommon.ServiceRegistryGetRestfulServerModule()
|
|
80
|
-
if restfulServer == nil {
|
|
81
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to get RestfulServerModule, unable to register restful apis.")
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
restfulServer.RegisterUiPage(URL_ONOS_HOMEPAGE, o.showOnosPage)
|
|
86
|
-
restfulServer.RegisterGetApi(URL_ONOS_SHOW, o.showOnosInfo)
|
|
87
|
-
restfulServer.RegisterPostApi(URL_ONOS_CONFIG, o.processOnosInfo)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
func (o *OnosTopoModule) showOnosPage(c *gin.Context) {
|
|
91
|
-
c.HTML(200, "index-onos.html", nil)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
func (o *OnosTopoModule) showOnosInfo(c *gin.Context) {
|
|
95
|
-
// TODO: TEST
|
|
96
|
-
data := make(map[string]interface{})
|
|
97
|
-
data["addrPort"] = o.addrPort
|
|
98
|
-
data["ADD_DEVICE_API"] = o.ADD_DEVICE_API
|
|
99
|
-
data["REMOVE_DEVICE_API"] = o.REMOVE_DEVICE_API
|
|
100
|
-
data["DELETE_DEVICE_API"] = o.DELETE_DEVICE_API
|
|
101
|
-
data["ADD_LINK_API"] = o.ADD_LINK_API
|
|
102
|
-
data["REMOVE_LINK_API"] = o.REMOVE_LINK_API
|
|
103
|
-
|
|
104
|
-
// Attention: password can't be outputted !!!
|
|
105
|
-
c.JSON(200, data)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
func (o *OnosTopoModule) processOnosInfo(c *gin.Context) {
|
|
109
|
-
// TODO: TEST
|
|
110
|
-
|
|
111
|
-
addrPort, ok := c.GetPostForm("addrPort")
|
|
112
|
-
if ok {
|
|
113
|
-
o.addrPort = addrPort
|
|
114
|
-
o.configOnosEndpointAPI(addrPort)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
configModule := MaoCommon.ServiceRegistryGetConfigModule()
|
|
118
|
-
if configModule == nil {
|
|
119
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to get config module instance, can't save email info")
|
|
120
|
-
} else {
|
|
121
|
-
data := make(map[string]interface{})
|
|
122
|
-
data["addrPort"] = o.addrPort
|
|
123
|
-
data["ADD_DEVICE_API"] = o.ADD_DEVICE_API
|
|
124
|
-
data["REMOVE_DEVICE_API"] = o.REMOVE_DEVICE_API
|
|
125
|
-
data["DELETE_DEVICE_API"] = o.DELETE_DEVICE_API
|
|
126
|
-
data["ADD_LINK_API"] = o.ADD_LINK_API
|
|
127
|
-
data["REMOVE_LINK_API"] = o.REMOVE_LINK_API
|
|
128
|
-
|
|
129
|
-
configModule.PutConfig(ONOS_CONFIG_PATH, data)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
o.showOnosPage(c)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
func (o *OnosTopoModule) configOnosEndpointAPI(addrPort string) {
|
|
136
|
-
o.ADD_DEVICE_API = fmt.Sprintf("http://%s/onos/mao%s", addrPort, ADD_DEVICE_API_SUFFIX)
|
|
137
|
-
o.REMOVE_DEVICE_API = fmt.Sprintf("http://%s/onos/mao%s", addrPort, REMOVE_DEVICE_API_SUFFIX)
|
|
138
|
-
o.DELETE_DEVICE_API = fmt.Sprintf("http://%s/onos/v1/devices/mao:%%s", addrPort)
|
|
139
|
-
o.ADD_LINK_API = fmt.Sprintf("http://%s/onos/mao%s", addrPort, ADD_LINK_API_SUFFIX)
|
|
140
|
-
o.REMOVE_LINK_API = fmt.Sprintf("http://%s/onos/mao%s", addrPort, REMOVE_LINK_API_SUFFIX)
|
|
141
|
-
|
|
142
|
-
// Add local node to ONOS after updating the API URLs
|
|
143
|
-
// Init my local node to ONOS instance.
|
|
144
|
-
o.topoAddDevice(o.hostname, o.version, time.Now().String())
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
//func (o *OnosTopoModule) initConfig() (success bool) {
|
|
150
|
-
// apiConfig := o.getApiConfig()
|
|
151
|
-
// if apiConfig != nil {
|
|
152
|
-
// // TODO: confirm and apply config
|
|
153
|
-
// return true
|
|
154
|
-
// }
|
|
155
|
-
//
|
|
156
|
-
// // the config doesn't exist, init it.
|
|
157
|
-
//
|
|
158
|
-
// configModule := MaoCommon.ServiceRegistryGetConfigModule()
|
|
159
|
-
// if configModule == nil {
|
|
160
|
-
// util.MaoLogM(util.WARN, MODULE_NAME, "Fail to get config module instance")
|
|
161
|
-
// return false
|
|
162
|
-
// }
|
|
163
|
-
//
|
|
164
|
-
// _, errCode := configModule.PutConfig(ONOS_API_CONFIG_PATH, make([]string, 0))
|
|
165
|
-
// if errCode != Config.ERR_CODE_SUCCESS {
|
|
166
|
-
// util.MaoLogM(util.WARN, MODULE_NAME, "Fail to init ONOS_API_CONFIG_PATH, errCode: %d", errCode)
|
|
167
|
-
// return false
|
|
168
|
-
// }
|
|
169
|
-
//
|
|
170
|
-
// return true
|
|
171
|
-
//}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
func (o *OnosTopoModule) SendEvent(event *MaoApi.TopoEvent) {
|
|
176
|
-
o.topoEventChannel <- event
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
func (o *OnosTopoModule) topoEventLoop() {
|
|
180
|
-
kaInterval := time.Duration(1000) * time.Millisecond
|
|
181
|
-
kaShutdownTimer := time.NewTimer(kaInterval)
|
|
182
|
-
|
|
183
|
-
// Init my local node to ONOS instance.
|
|
184
|
-
o.topoAddDevice(o.hostname, o.version, time.Now().String())
|
|
185
|
-
for {
|
|
186
|
-
select {
|
|
187
|
-
case event := <-o.topoEventChannel:
|
|
188
|
-
qingdao := len(o.topoEventChannel)
|
|
189
|
-
util.MaoLogM(util.DEBUG, MODULE_NAME, "buffer len: %d", qingdao)
|
|
190
|
-
switch event.EventType {
|
|
191
|
-
case MaoApi.SERVICE_UP:
|
|
192
|
-
localPort, ok1 := o.portMapping[fmt.Sprintf("%s-%s-%s", o.hostname, event.ServiceName, event.EventSource)]
|
|
193
|
-
if !ok1 {
|
|
194
|
-
localPort = o.portIterators[o.hostname]
|
|
195
|
-
o.portIterators[o.hostname] = localPort + 1
|
|
196
|
-
o.portMapping[fmt.Sprintf("%s-%s-%s", o.hostname, event.ServiceName, event.EventSource)] = localPort
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
servicePort, ok2 := o.portMapping[fmt.Sprintf("%s-%s-%s", event.ServiceName, o.hostname, event.EventSource)]
|
|
200
|
-
if !ok2 {
|
|
201
|
-
servicePort, ok2 = o.portIterators[event.ServiceName]
|
|
202
|
-
if !ok2 {
|
|
203
|
-
servicePort = 1
|
|
204
|
-
}
|
|
205
|
-
o.portIterators[event.ServiceName] = servicePort + 1
|
|
206
|
-
o.portMapping[fmt.Sprintf("%s-%s-%s", event.ServiceName, o.hostname, event.EventSource)] = servicePort
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
go func() {
|
|
210
|
-
o.topoAddDevice(event.ServiceName, event.Timestamp.String(), event.EventSource)
|
|
211
|
-
o.topoAddLink(o.hostname, localPort, event.ServiceName, servicePort)
|
|
212
|
-
}()
|
|
213
|
-
case MaoApi.SERVICE_DOWN:
|
|
214
|
-
go func(){
|
|
215
|
-
o.topoAddDevice(event.ServiceName, event.Timestamp.String(), event.EventSource)
|
|
216
|
-
o.topoOfflineDevice(event.ServiceName)
|
|
217
|
-
}()
|
|
218
|
-
case MaoApi.SERVICE_DELETE:
|
|
219
|
-
go o.topoDeleteDevice(event.ServiceName)
|
|
220
|
-
}
|
|
221
|
-
case <-kaShutdownTimer.C:
|
|
222
|
-
if o.needShutdown {
|
|
223
|
-
if len(o.topoEventChannel) != 0 {
|
|
224
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Exiting, but the topoEventChannel is not empty, len: %d", len(o.topoEventChannel))
|
|
225
|
-
}
|
|
226
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Exit.")
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
go o.topoAddDevice(o.hostname, o.version, time.Now().String())
|
|
230
|
-
kaShutdownTimer.Reset(kaInterval)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
func (o *OnosTopoModule) topoAddDevice(serviceName string, timestamp string, eventSource string) {
|
|
236
|
-
if serviceName == "" {
|
|
237
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to add device, service name can't be empty")
|
|
238
|
-
return
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
jsonMap := make(map[string]string)
|
|
242
|
-
jsonMap["deviceId"] = serviceName
|
|
243
|
-
jsonMap["deviceName"] = serviceName
|
|
244
|
-
jsonMap["swVersion"] = timestamp
|
|
245
|
-
jsonMap["manageProtocol"] = eventSource
|
|
246
|
-
jsonBytes, err := json.Marshal(jsonMap)
|
|
247
|
-
if err != nil {
|
|
248
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to marshal device data, %s", err.Error())
|
|
249
|
-
return
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if sendRequest("POST", o.ADD_DEVICE_API, jsonBytes) {
|
|
253
|
-
//routerDatas = append(routerDatas, jsonBytes)
|
|
254
|
-
//routerNames = append(routerNames, router.deviceName)
|
|
255
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Add device: %s", serviceName)
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
func (o *OnosTopoModule) topoOfflineDevice(serviceName string) {
|
|
260
|
-
if serviceName == "" {
|
|
261
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to offline device, service name can't be empty")
|
|
262
|
-
return
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
jsonMap := make(map[string]string)
|
|
266
|
-
jsonMap["deviceId"] = serviceName
|
|
267
|
-
jsonBytes, err := json.Marshal(jsonMap)
|
|
268
|
-
if err != nil {
|
|
269
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to marshal device data, %s", err.Error())
|
|
270
|
-
return
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if sendRequest("POST", o.REMOVE_DEVICE_API, jsonBytes) {
|
|
274
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Offline device: %s", serviceName)
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
func (o *OnosTopoModule) topoDeleteDevice(serviceName string) {
|
|
279
|
-
if serviceName == "" {
|
|
280
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to delete device, service name can't be empty")
|
|
281
|
-
return
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if sendRequest("DELETE", fmt.Sprintf(o.DELETE_DEVICE_API, serviceName), nil) {
|
|
285
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Delete device: %s", serviceName)
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
func (o *OnosTopoModule) topoAddLink(serviceName1 string, portId1 uint, serviceName2 string, portId2 uint) {
|
|
290
|
-
if serviceName1 == "" || serviceName2 == ""{
|
|
291
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to add link, service name can't be empty, %s - %s", serviceName1, serviceName2)
|
|
292
|
-
return
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
jsonMap := make(map[string]interface{})
|
|
296
|
-
jsonMap["srcDeviceId"] = serviceName1
|
|
297
|
-
jsonMap["srcPortId"] = portId1
|
|
298
|
-
jsonMap["srcPortName"] = fmt.Sprintf("%s-%s", serviceName1, serviceName2)
|
|
299
|
-
jsonMap["dstDeviceId"] = serviceName2
|
|
300
|
-
jsonMap["dstPortId"] = portId2
|
|
301
|
-
jsonMap["dstPortName"] = fmt.Sprintf("%s-%s", serviceName2, serviceName1)
|
|
302
|
-
|
|
303
|
-
jsonBytes, err := json.Marshal(jsonMap)
|
|
304
|
-
if err != nil {
|
|
305
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to marshal link data, %s", err.Error())
|
|
306
|
-
return
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if sendRequest("POST", o.ADD_LINK_API, jsonBytes) {
|
|
310
|
-
//linkDatas = append(linkDatas, jsonBytes)
|
|
311
|
-
//linkNames = append(linkNames, GenerateLinkName(r1.deviceName, r2.deviceName))
|
|
312
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Add link: %s - %s", serviceName1, serviceName2)
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
func sendRequest(method string, url string, body []byte) bool {
|
|
317
|
-
if url == "" {
|
|
318
|
-
util.MaoLogM(util.DEBUG, MODULE_NAME, "API URL is not configured, not send request.")
|
|
319
|
-
return false
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
req, err := http.NewRequest(method, url, bytes.NewBuffer(body))
|
|
323
|
-
if err != nil {
|
|
324
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to create request: %s %s, %s",
|
|
325
|
-
method, url, err.Error())
|
|
326
|
-
return false
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// ONOS Web default password, karaf:karaf, basic authentication
|
|
330
|
-
req.Header.Add("Authorization", "Basic a2FyYWY6a2FyYWY=")
|
|
331
|
-
|
|
332
|
-
client := http.Client{}
|
|
333
|
-
resp, err := client.Do(req)
|
|
334
|
-
if err != nil {
|
|
335
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to do request: %s %s, err: %s",
|
|
336
|
-
req.Method, req.URL.String(), err.Error())
|
|
337
|
-
return false
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if resp.StatusCode != 200 {
|
|
341
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to finish request: %s %s, http code: %d, err: %s",
|
|
342
|
-
req.Method, req.URL.String(), resp.StatusCode, resp.Status)
|
|
343
|
-
return false
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return true
|
|
347
|
-
}
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
package Wechat
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
MaoApi "MaoServerDiscovery/cmd/api"
|
|
5
|
-
"MaoServerDiscovery/cmd/lib/MaoCommon"
|
|
6
|
-
"MaoServerDiscovery/util"
|
|
7
|
-
"fmt"
|
|
8
|
-
"github.com/gin-gonic/gin"
|
|
9
|
-
"strings"
|
|
10
|
-
"time"
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
const (
|
|
14
|
-
MODULE_NAME = "Wechat-Message-module"
|
|
15
|
-
|
|
16
|
-
URL_WECHAT_HOMEPAGE = "/configWechat"
|
|
17
|
-
URL_WECHAT_CONFIG = "/addWechatInfo"
|
|
18
|
-
URL_WECHAT_SHOW = "/getWechatInfo"
|
|
19
|
-
|
|
20
|
-
WECHAT_INFO_CONFIG_PATH = "/wechat"
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
const (
|
|
24
|
-
|
|
25
|
-
URL_TEMPLATE_GET_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s"
|
|
26
|
-
URL_TEMPLATE_SEND_MESSAGE = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s"
|
|
27
|
-
|
|
28
|
-
TEXT_CARD_JSON_TEMPLATE =
|
|
29
|
-
"{" +
|
|
30
|
-
"\"touser\":\"%s\"," +
|
|
31
|
-
"\"toparty\":\"\"," +
|
|
32
|
-
"\"totag\":\"\"," +
|
|
33
|
-
"\"msgtype\":\"textcard\"," +
|
|
34
|
-
"\"agentid\": %s," +
|
|
35
|
-
"\"textcard\": {" +
|
|
36
|
-
"\"title\":\"%s\"," +
|
|
37
|
-
"\"description\":\"%s\"," +
|
|
38
|
-
"\"url\":\"%s\"" +
|
|
39
|
-
"}" +
|
|
40
|
-
"}"
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
type WechatMessageModule struct {
|
|
44
|
-
|
|
45
|
-
corpId string
|
|
46
|
-
agentId string
|
|
47
|
-
agentSecret string // corpsecret. Attention: agentSecret can't be outputted !!!
|
|
48
|
-
globalReceivers []string // length == 0 and nil stand for all receivers.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// input the message
|
|
52
|
-
sendWechatMessageChannel chan *MaoApi.WechatMessage
|
|
53
|
-
lastSendTimestamp time.Time
|
|
54
|
-
|
|
55
|
-
// same as the other module, it is expected to be global
|
|
56
|
-
//checkInterval uint32
|
|
57
|
-
|
|
58
|
-
needShutdown bool
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
func (w *WechatMessageModule) RequireShutdown() {
|
|
62
|
-
w.needShutdown = true
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
func (w *WechatMessageModule) SendWechatMessage(message *MaoApi.WechatMessage) {
|
|
67
|
-
w.sendWechatMessageChannel <- message
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
func (w *WechatMessageModule) checkWechatInfo() bool {
|
|
71
|
-
|
|
72
|
-
if w.corpId == "" || w.agentId == "" || w.agentSecret == "" {
|
|
73
|
-
return false
|
|
74
|
-
}
|
|
75
|
-
return true
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
//func (w *WechatMessageModule) getAccessToken;
|
|
80
|
-
|
|
81
|
-
func (w *WechatMessageModule) sendWechatMessage(m *MaoApi.WechatMessage) {
|
|
82
|
-
|
|
83
|
-
if !w.checkWechatInfo() {
|
|
84
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to send wechat message, please config wechat info first.")
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
receiverConfig := w.globalReceivers
|
|
89
|
-
if m.Receivers != nil {
|
|
90
|
-
receiverConfig = m.Receivers
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
receivers := ""
|
|
94
|
-
if len(receiverConfig) == 0 {
|
|
95
|
-
receivers = "@all"
|
|
96
|
-
} else {
|
|
97
|
-
receivers = fmt.Sprintf("%s%s", receivers, receiverConfig[0])
|
|
98
|
-
for i := 1; i < len(receiverConfig); i++ {
|
|
99
|
-
receivers = fmt.Sprintf("%s%s", receivers, "|")
|
|
100
|
-
receivers = fmt.Sprintf("%s%s", receivers, receiverConfig[i])
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
wechatJson := fmt.Sprintf(TEXT_CARD_JSON_TEMPLATE, receivers, w.agentId, m.Title, m.ContentHttp, m.Url)
|
|
105
|
-
util.MaoLogM(util.HOT_DEBUG, MODULE_NAME, "Prepare wechat json:\n%s", wechatJson)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
//http.Get(fmt.Sprintf(URL_TEMPLATE_GET_ACCESS_TOKEN, ))
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
//req := http.Post("https://qyapi.weixin.qq.com/cgi-bin/message/send", )
|
|
112
|
-
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
// TODO
|
|
116
|
-
|
|
117
|
-
//// Set up authentication information everytime, that allows to update:
|
|
118
|
-
//// username, password, smtpServerAddrPort, sender, receiver
|
|
119
|
-
//auth := AuthLOGIN(s.username, s.password)
|
|
120
|
-
//
|
|
121
|
-
//// TODO: how to build multiple receivers string?
|
|
122
|
-
//// TODO: support multiple receivers
|
|
123
|
-
//msg := fmt.Sprintf("To: %s\r\n" +
|
|
124
|
-
// "Subject: %s%s\r\n" + "\r\n" +
|
|
125
|
-
// "%s\r\n",
|
|
126
|
-
// s.receiver[0], SUBJECT_FIX_PREFIX, m.Subject, m.Content)
|
|
127
|
-
//
|
|
128
|
-
////msg := []byte("To: @.com\r\n" +
|
|
129
|
-
//// "Subject: MaoReport: beijing tower\r\n" +
|
|
130
|
-
//// "\r\n" +
|
|
131
|
-
//// "This is the email body.\r\n")
|
|
132
|
-
//
|
|
133
|
-
//// TODO: make it configurable
|
|
134
|
-
//tlsConfig := &tls.Config{
|
|
135
|
-
// InsecureSkipVerify: true,
|
|
136
|
-
//}
|
|
137
|
-
//
|
|
138
|
-
//// Connect to the server, authenticate, set the sender and recipient,
|
|
139
|
-
//// and send the email all in one step.
|
|
140
|
-
//err := MaoEnhancedGolang.SendMail(s.smtpServerAddrPort, auth, s.sender, s.receiver, []byte(msg), tlsConfig)
|
|
141
|
-
//if err != nil {
|
|
142
|
-
// util.MaoLogM(util.WARN, MODULE_NAME, "Fail to send email, %s", err.Error())
|
|
143
|
-
//}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
func (w *WechatMessageModule) sendWechatMessageLoop() {
|
|
147
|
-
checkInterval := time.Duration(1000) * time.Millisecond
|
|
148
|
-
checkShutdownTimer := time.NewTimer(checkInterval)
|
|
149
|
-
for {
|
|
150
|
-
select {
|
|
151
|
-
case message := <-w.sendWechatMessageChannel:
|
|
152
|
-
if time.Now().Sub(w.lastSendTimestamp) < 1 * time.Second {
|
|
153
|
-
freezeTimer := time.NewTimer(time.Duration(1) * time.Second)
|
|
154
|
-
sent := false
|
|
155
|
-
for !sent {
|
|
156
|
-
select {
|
|
157
|
-
case <-freezeTimer.C:
|
|
158
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Sending wechat message, pending: %d", len(w.sendWechatMessageChannel))
|
|
159
|
-
w.sendWechatMessage(message)
|
|
160
|
-
w.lastSendTimestamp = time.Now()
|
|
161
|
-
sent = true
|
|
162
|
-
case <-checkShutdownTimer.C:
|
|
163
|
-
util.MaoLogM(util.HOT_DEBUG, MODULE_NAME, "CheckShutdown while freezing, event queue len %d", len(w.sendWechatMessageChannel))
|
|
164
|
-
if w.needShutdown {
|
|
165
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Exit while freezing, the sendWechatMessageChannel len: %d", len(w.sendWechatMessageChannel))
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
checkShutdownTimer.Reset(checkInterval)
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Sending wechat message, pending: %d", len(w.sendWechatMessageChannel))
|
|
173
|
-
w.sendWechatMessage(message)
|
|
174
|
-
w.lastSendTimestamp = time.Now()
|
|
175
|
-
}
|
|
176
|
-
case <-checkShutdownTimer.C:
|
|
177
|
-
util.MaoLogM(util.HOT_DEBUG, MODULE_NAME, "CheckShutdown, event queue len %d", len(w.sendWechatMessageChannel))
|
|
178
|
-
if w.needShutdown {
|
|
179
|
-
if len(w.sendWechatMessageChannel) != 0 {
|
|
180
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Exiting, but the sendWechatMessageChannel is not empty, len: %d", len(w.sendWechatMessageChannel))
|
|
181
|
-
}
|
|
182
|
-
util.MaoLogM(util.INFO, MODULE_NAME, "Exit.")
|
|
183
|
-
return
|
|
184
|
-
}
|
|
185
|
-
checkShutdownTimer.Reset(checkInterval)
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
func (w *WechatMessageModule) InitWechatMessageModule() bool {
|
|
191
|
-
w.sendWechatMessageChannel = make(chan *MaoApi.WechatMessage, 1024)
|
|
192
|
-
w.needShutdown = false
|
|
193
|
-
|
|
194
|
-
go w.sendWechatMessageLoop()
|
|
195
|
-
|
|
196
|
-
w.configRestControlInterface()
|
|
197
|
-
|
|
198
|
-
return true
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
func (w *WechatMessageModule) configRestControlInterface() {
|
|
202
|
-
restfulServer := MaoCommon.ServiceRegistryGetRestfulServerModule()
|
|
203
|
-
if restfulServer == nil {
|
|
204
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to get RestfulServerModule, unable to register restful apis.")
|
|
205
|
-
return
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
restfulServer.RegisterGetApi(URL_WECHAT_HOMEPAGE, w.showWechatPage)
|
|
209
|
-
restfulServer.RegisterGetApi(URL_WECHAT_SHOW, w.showWechatInfo)
|
|
210
|
-
restfulServer.RegisterPostApi(URL_WECHAT_CONFIG, w.processWechatInfo)
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
func (w *WechatMessageModule) showWechatPage(c *gin.Context) {
|
|
214
|
-
c.HTML(200, "index-wechat.html", nil)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
func (w *WechatMessageModule) showWechatInfo(c *gin.Context) {
|
|
218
|
-
data := make(map[string]interface{})
|
|
219
|
-
data["corpId"] = w.corpId
|
|
220
|
-
data["agentId"] = w.agentId
|
|
221
|
-
data["globalReceivers"] = w.globalReceivers
|
|
222
|
-
|
|
223
|
-
// Attention: agentSecret can't be outputted !!!
|
|
224
|
-
c.JSON(200, data)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
func (w *WechatMessageModule) processWechatInfo(c *gin.Context) {
|
|
228
|
-
|
|
229
|
-
// TODO: check and limit the length of corpId/agentId/agentSecret. Prevent injection attack
|
|
230
|
-
|
|
231
|
-
corpId, ok := c.GetPostForm("corpId")
|
|
232
|
-
if ok {
|
|
233
|
-
w.corpId = corpId
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
agentId, ok := c.GetPostForm("agentId")
|
|
237
|
-
if ok {
|
|
238
|
-
w.agentId = agentId
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
agentSecret, ok := c.GetPostForm("agentSecret")
|
|
242
|
-
if ok {
|
|
243
|
-
w.agentSecret = agentSecret
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
globalReceiversStr, ok := c.GetPostForm("globalReceivers")
|
|
247
|
-
if ok {
|
|
248
|
-
globalReceivers := strings.Fields(globalReceiversStr)
|
|
249
|
-
w.globalReceivers = globalReceivers
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
configModule := MaoCommon.ServiceRegistryGetConfigModule()
|
|
254
|
-
if configModule == nil {
|
|
255
|
-
util.MaoLogM(util.WARN, MODULE_NAME, "Fail to get config module instance, can't save wechat info")
|
|
256
|
-
} else {
|
|
257
|
-
data := make(map[string]interface{})
|
|
258
|
-
data["corpId"] = w.corpId
|
|
259
|
-
data["agentId"] = w.agentId
|
|
260
|
-
data["globalReceivers"] = w.globalReceivers
|
|
261
|
-
|
|
262
|
-
// Attention: agentSecret can't be outputted !!!
|
|
263
|
-
configModule.PutConfig(WECHAT_INFO_CONFIG_PATH, data)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
w.showWechatPage(c)
|
|
267
|
-
}
|