[message pusher] - standlone gin service
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"activeGroup": "Default",
|
||||||
|
"apiParamGroup": {
|
||||||
|
"message_pusher": {
|
||||||
|
"bodyKeyValueListJson": "",
|
||||||
|
"classDescription": "",
|
||||||
|
"className": "io.wdd.rpc.controller.ExecutionController",
|
||||||
|
"headerParamsKeyValueList": [
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"type": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"jsonDocument": "",
|
||||||
|
"method": "SyncCommandToAgentBody",
|
||||||
|
"methodDescription": "[命令] [同步] - 单机-等待命令结果",
|
||||||
|
"methodType": "GET",
|
||||||
|
"multipartKeyValueListJson": "[]",
|
||||||
|
"originUrl": "/octopus/server/executor/command/sync/one/body",
|
||||||
|
"pathParamsKeyValueListJson": "[]",
|
||||||
|
"postScript": "",
|
||||||
|
"postType": "json",
|
||||||
|
"preScript": "",
|
||||||
|
"returnDocument": "{\"code\":\"No comment,Type =Number\",\"msg\":\"No comment,Type =String\",\"data\":{}}",
|
||||||
|
"tempId": "",
|
||||||
|
"url": "/cmii",
|
||||||
|
"urlEncodedKeyValueListJson": "[]",
|
||||||
|
"urlEncodedKeyValueListText": "",
|
||||||
|
"urlParamsKeyValueListJson": "[]",
|
||||||
|
"urlParamsKeyValueListText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"childList": [],
|
||||||
|
"classDescription": "",
|
||||||
|
"description": "",
|
||||||
|
"directory": "/.fastRequest/collections/Root/server/ExecutionController",
|
||||||
|
"domain": "localhost:8080",
|
||||||
|
"enableEnv": "local",
|
||||||
|
"enableProject": "message_pusher",
|
||||||
|
"filePath": "/.fastRequest/collections/Root/server/ExecutionController~SyncCommandToAgentBody.rapi",
|
||||||
|
"id": "api_io.wdd.rpc.controller.ExecutionController.SyncCommandToAgentBody",
|
||||||
|
"name": "[命令] [同步] - 单机-等待命令结果",
|
||||||
|
"paramGroup": {
|
||||||
|
"bodyKeyValueListJson": "{\n \"Namespace\": \"devflight\",\n \"AppName\": \"cmii-uav-device\",\n \"ToTag\": \"5.5.0-1234\",\n \"Replicas\": 10\n}",
|
||||||
|
"classDescription": "",
|
||||||
|
"className": "io.wdd.rpc.controller.ExecutionController",
|
||||||
|
"headerParamsKeyValueList": [
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"type": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"jsonDocument": "",
|
||||||
|
"method": "SyncCommandToAgentBody",
|
||||||
|
"methodDescription": "[命令] [同步] - 单机-等待命令结果",
|
||||||
|
"methodType": "POST",
|
||||||
|
"multipartKeyValueListJson": "[{\"customFlag\":2,\"enabled\":true,\"key\":\"Namespace\",\"type\":\"String\",\"value\":\"devflight\"},{\"customFlag\":2,\"enabled\":true,\"key\":\"AppName\",\"type\":\"String\",\"value\":\"cmii-uag-device\"},{\"customFlag\":2,\"enabled\":true,\"key\":\"ToTag\",\"type\":\"String\",\"value\":\"5.5.0-1234\"},{\"customFlag\":2,\"enabled\":true,\"key\":\"Replicas\",\"type\":\"String\",\"value\":\"2\"}]",
|
||||||
|
"originUrl": "/octopus/server/executor/command/sync/one/body",
|
||||||
|
"pathParamsKeyValueListJson": "[]",
|
||||||
|
"postScript": "",
|
||||||
|
"postType": "json",
|
||||||
|
"preScript": "",
|
||||||
|
"returnDocument": "{\"code\":\"No comment,Type =Number\",\"msg\":\"No comment,Type =String\",\"data\":{}}",
|
||||||
|
"tempId": "",
|
||||||
|
"url": "/cmii/upgrade",
|
||||||
|
"urlEncodedKeyValueListJson": "[{\"customFlag\":2,\"enabled\":true,\"key\":\"{\\\"Namespace\\\":\\\"foo\\\",\\\"AppName\\\":\\\"bar\\\",\\\"ToTag\\\":\\\"baz\\\",\\\"Replicas\\\":10}\",\"type\":\"String\",\"value\":\"\"}]",
|
||||||
|
"urlEncodedKeyValueListText": "{\"Namespace\":\"foo\",\"AppName\":\"bar\",\"ToTag\":\"baz\",\"Replicas\":10}=",
|
||||||
|
"urlParamsKeyValueListJson": "[]",
|
||||||
|
"urlParamsKeyValueListText": ""
|
||||||
|
},
|
||||||
|
"pmRequestId": "",
|
||||||
|
"pmResponseId": "",
|
||||||
|
"tempId": "api_io.wdd.rpc.controller.ExecutionController.SyncCommandToAgentBody",
|
||||||
|
"type": 2
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"apiDocTemplate": "#if (${namingPolicy}=='byDoc')\n$H1 ${methodDescription}\n#else\n$H1 $!{methodName}\n\n$H3 Method description\n\n```\n$!{methodDescription}\n```\n#end\n\n> URL: $!{url}\n>\n> Origin Url: $!{originUrl}\n>\n> Type: $!{methodType}\n\n\n$H3 Request headers\n\n|Header Name| Header Value|\n|---------|------|\n#foreach( $h in ${headerList})\n|$h.type|$h.value|\n#end\n\n$H3 Parameters\n\n$H5 Path parameters\n\n| Parameter | Type | Value | Description |\n|---------|------|------|------------|\n#foreach( $node in ${pathKeyValueList})\n|$node.key|$!{node.type}|$!{node.value}|$!{node.comment}|\n#end\n\n\n$H5 URL parameters\n\n|Required| Parameter | Type | Value | Description |\n|---------|---------|------|------|------------|\n#foreach( $node in ${urlParamsKeyValueList})\n|$!{node.enabled}|$!{node.key}|$!{node.type}|$!{node.value}|$!{node.comment}|\n#end\n\n\n$H5 Body parameters\n\n$H6 JSON\n\n```\n${jsonParam}\n```\n\n$H6 JSON document\n\n```\n${jsonParamDocument}\n```\n\n\n$H5 Form URL-Encoded\n|Required| Parameter | Type | Value | Description |\n|---------|---------|------|------|------------|\n#foreach( $node in ${urlEncodedKeyValueList})\n|$!{node.enabled}|$!{node.key}|$!{node.type}|$!{node.value}|$!{node.comment}|\n#end\n\n\n$H5 Multipart\n|Required | Parameter | Type | Value | Description |\n|---------|---------|------|------|------------|\n#foreach( $node in ${multipartKeyValueList})\n|$!{node.enabled}|$!{node.key}|$!{node.type}|$!{node.value}|$!{node.comment}|\n#end\n\n\n$H3 Response\n\n$H5 Response example\n\n```\n$!{responseExample}\n```\n\n$H5 Response document\n```\n$!{returnDocument}\n```\n\n\n",
|
||||||
|
"apifoxSetting": {
|
||||||
|
"domain": "https://api.apifox.com",
|
||||||
|
"syncAfterSave": false
|
||||||
|
},
|
||||||
"dataList": [
|
"dataList": [
|
||||||
{
|
{
|
||||||
"hostGroup": [
|
"hostGroup": [
|
||||||
@@ -17,31 +22,46 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "server"
|
"name": "server"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hostGroup": [
|
||||||
|
{
|
||||||
|
"env": "local",
|
||||||
|
"url": "localhost:8080"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "message_pusher"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"envList": [
|
"envList": [
|
||||||
"local"
|
"local"
|
||||||
],
|
],
|
||||||
"headerList": [],
|
"headerList": [],
|
||||||
|
"ignoreParseFieldList": [],
|
||||||
|
"maxDescriptionLength": -1,
|
||||||
|
"pmCollectionId": "",
|
||||||
"postScript": "",
|
"postScript": "",
|
||||||
"preScript": "",
|
"preScript": "",
|
||||||
"projectList": [
|
"projectList": [
|
||||||
"OctpusGO",
|
"OctpusGO",
|
||||||
"server"
|
"server",
|
||||||
|
"message_pusher"
|
||||||
],
|
],
|
||||||
"syncModel": {
|
"syncModel": {
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"domain": "https://github.com",
|
"domain": "https://github.com",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
"gitToken": "",
|
||||||
"namingPolicy": "byDoc",
|
"namingPolicy": "byDoc",
|
||||||
"owner": "",
|
"owner": "",
|
||||||
"repo": "",
|
"repo": "",
|
||||||
"repoUrl": "",
|
"repoUrl": "",
|
||||||
"syncAfterRun": false,
|
"syncAfterRun": false,
|
||||||
"token": "",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
"syncPmAfterSave": false,
|
||||||
"urlEncodedKeyValueList": [],
|
"urlEncodedKeyValueList": [],
|
||||||
"urlParamsKeyValueList": [],
|
"urlParamsKeyValueList": [],
|
||||||
"urlSuffix": ""
|
"urlSuffix": "",
|
||||||
|
"workspaceId": ""
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"apifoxRelationMap": {},
|
||||||
|
"apifoxServerMap": {},
|
||||||
|
"environment": {},
|
||||||
|
"pmRelationMap": {}
|
||||||
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package message_pusher
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"wdd.io/agent-common/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestClient_Publish(t *testing.T) {
|
|
||||||
|
|
||||||
client := NewDefaultClient()
|
|
||||||
|
|
||||||
optionList := []PublishOption{
|
|
||||||
WithTitle("测试内容"),
|
|
||||||
WithPriority("5"),
|
|
||||||
WithMarkdown(),
|
|
||||||
}
|
|
||||||
|
|
||||||
deployPush := DeployPush{
|
|
||||||
Namespace: "uavcloud-dev",
|
|
||||||
AppName: "cmii-uav-platform",
|
|
||||||
Replicas: "1",
|
|
||||||
DeployStatus: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
deployPush.ParseCmiiDeployTemplate()
|
|
||||||
|
|
||||||
message, err := client.PublishDefault(deployPush.ParseCmiiDeployTemplate(), optionList)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.BeautifulPrint(message)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package message_pusher
|
|
||||||
|
|
||||||
var DefaultClientOp = NewDefaultClient()
|
|
||||||
|
|
||||||
var CmiiUpdatePushOptions = []PublishOption{
|
|
||||||
WithTitle("更新应用"),
|
|
||||||
WithPriority("3"),
|
|
||||||
}
|
|
||||||
|
|
||||||
func PushCmiiUpdateMessage(cmiiEnv, appName, newTag string, updateStatus bool) {
|
|
||||||
|
|
||||||
deployPush := DeployPush{
|
|
||||||
Namespace: cmiiEnv,
|
|
||||||
AppName: appName,
|
|
||||||
DeployStatus: updateStatus,
|
|
||||||
ToTag: newTag,
|
|
||||||
}
|
|
||||||
|
|
||||||
deployPush.ParseCmiiDeployTemplate()
|
|
||||||
|
|
||||||
_, err := DefaultClientOp.PublishDefault(deployPush.ParseCmiiDeployTemplate(), CmiiUpdatePushOptions)
|
|
||||||
if err != nil {
|
|
||||||
log.ErrorF("[PushCmiiUpdateMessage] - message push error ! %s", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package message_pusher
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
const cmiiDeployTemplate = `
|
|
||||||
{{if .DeployStatus}}
|
|
||||||
部署状态: 成功😍
|
|
||||||
{{- else }}
|
|
||||||
部署状态: 失败👿👿👿
|
|
||||||
{{- end}}
|
|
||||||
命名空间: {{.Namespace}}
|
|
||||||
应用名称: {{.AppName}}
|
|
||||||
副本数量: {{.Replicas}}
|
|
||||||
目标版本: {{.ToTag}}
|
|
||||||
`
|
|
||||||
|
|
||||||
type DeployPush struct {
|
|
||||||
Namespace string
|
|
||||||
AppName string
|
|
||||||
Replicas string
|
|
||||||
DeployStatus bool
|
|
||||||
ToTag string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d DeployPush) ParseCmiiDeployTemplate() bytes.Buffer {
|
|
||||||
// 解析模板
|
|
||||||
tmpl, err := template.New("cmiiDeployTemplate").Parse(cmiiDeployTemplate)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 应用数据并打印结果
|
|
||||||
var result bytes.Buffer
|
|
||||||
err = tmpl.Execute(&result, d)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package message_pusher
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDeployPush_ParseCmiiDeployTemplate(t *testing.T) {
|
|
||||||
deployPush := DeployPush{
|
|
||||||
Namespace: "casc",
|
|
||||||
AppName: "sdasdas",
|
|
||||||
Replicas: "dasdasd",
|
|
||||||
DeployStatus: false,
|
|
||||||
ToTag: "5.4.0",
|
|
||||||
}
|
|
||||||
|
|
||||||
template := deployPush.ParseCmiiDeployTemplate()
|
|
||||||
|
|
||||||
fmt.Println(template.String())
|
|
||||||
}
|
|
||||||
67
message_pusher/cmii/CmiiMessageBody.go
Normal file
67
message_pusher/cmii/CmiiMessageBody.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package cmii
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io.wdd.message_pusher/pusher"
|
||||||
|
"text/template"
|
||||||
|
"wdd.io/agent-common/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logger.Log
|
||||||
|
|
||||||
|
type MessageBody struct {
|
||||||
|
Namespace string
|
||||||
|
AppName string
|
||||||
|
ToTag string
|
||||||
|
Replicas string
|
||||||
|
DeployStatus bool
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmiiUpgradeTemplate = `
|
||||||
|
{{if .DeployStatus}}
|
||||||
|
部署状态: 成功😍
|
||||||
|
{{- else }}
|
||||||
|
部署状态: 失败👿👿👿
|
||||||
|
{{- end}}
|
||||||
|
命名空间: {{.Namespace}}
|
||||||
|
应用名称: {{.AppName}}
|
||||||
|
副本数量: {{.Replicas}}
|
||||||
|
目标版本: {{.ToTag}}
|
||||||
|
`
|
||||||
|
|
||||||
|
func (d *MessageBody) ParseCmiiUpgradeTemplate() bytes.Buffer {
|
||||||
|
// 解析模板
|
||||||
|
tmpl, err := template.New("cmiiUpgradeTemplate").Parse(cmiiUpgradeTemplate)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用数据并打印结果
|
||||||
|
var result bytes.Buffer
|
||||||
|
err = tmpl.Execute(&result, d)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var UpdatePushOptions = []pusher.PublishOption{
|
||||||
|
pusher.WithTitle("更新应用"),
|
||||||
|
pusher.WithPriority("3"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultPushUpgradeMessage 使用默认的Client 发布更新的消息
|
||||||
|
func (d *MessageBody) DefaultPushUpgradeMessage() *pusher.Message {
|
||||||
|
|
||||||
|
upgradeTemplate := d.ParseCmiiUpgradeTemplate()
|
||||||
|
|
||||||
|
result, err := pusher.DefaultPusherClient.PublishDefault(upgradeTemplate, UpdatePushOptions)
|
||||||
|
if err != nil {
|
||||||
|
log.ErrorF("[PushCmiiUpgradeMessage] - message push error ! %s", err.Error())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
}
|
||||||
20
message_pusher/cmii/CmiiMessageBody_test.go
Normal file
20
message_pusher/cmii/CmiiMessageBody_test.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package cmii
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"wdd.io/agent-common/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMessageBody_DefaultPushUpgradeMessage(t *testing.T) {
|
||||||
|
|
||||||
|
deployPush := &MessageBody{
|
||||||
|
Namespace: "uavcloud-dev",
|
||||||
|
AppName: "cmii-uav-platform",
|
||||||
|
Replicas: "1",
|
||||||
|
DeployStatus: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
message := deployPush.DefaultPushUpgradeMessage()
|
||||||
|
|
||||||
|
utils.BeautifulPrint(message)
|
||||||
|
}
|
||||||
40
message_pusher/go.mod
Normal file
40
message_pusher/go.mod
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
module io.wdd.message_pusher
|
||||||
|
|
||||||
|
go 1.22.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
|
||||||
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
wdd.io/agent-common v0.0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/sonic v1.9.1 // indirect
|
||||||
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
go.uber.org/multierr v1.10.0 // indirect
|
||||||
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
|
golang.org/x/crypto v0.22.0 // indirect
|
||||||
|
golang.org/x/net v0.24.0 // indirect
|
||||||
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace wdd.io/agent-common => ../agent-common
|
||||||
94
message_pusher/go.sum
Normal file
94
message_pusher/go.sum
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
|
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||||
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
|
||||||
|
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||||
|
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||||
|
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||||
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
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=
|
||||||
|
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||||
|
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||||
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
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=
|
||||||
|
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/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
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/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||||
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
|
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||||
|
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
|
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||||
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
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=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
25
message_pusher/main.go
Normal file
25
message_pusher/main.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io.wdd.message_pusher/router"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
engine := gin.Default()
|
||||||
|
|
||||||
|
// 强制日志颜色化
|
||||||
|
gin.ForceConsoleColor()
|
||||||
|
|
||||||
|
// 定义路由组
|
||||||
|
{
|
||||||
|
router.CMIIRouter(engine)
|
||||||
|
router.OctopusRouter(engine)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := engine.Run(":8080")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package message_pusher
|
package pusher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -13,8 +13,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topicRegex = regexp.MustCompile(`^[-_A-Za-z0-9]{1,64}$`) // Same as in server/server.go
|
topicRegex = regexp.MustCompile(`^[-_A-Za-z0-9]{1,64}$`) // Same as in server/server.go
|
||||||
log = logger.Log
|
log = logger.Log
|
||||||
|
DefaultPusherClient = NewDefaultClient()
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package message_pusher
|
package pusher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package message_pusher
|
package pusher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
32
message_pusher/router/CmiiRouter.go
Normal file
32
message_pusher/router/CmiiRouter.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io.wdd.message_pusher/cmii"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CMIIRouter(r *gin.Engine) {
|
||||||
|
|
||||||
|
cmiiGroup := r.Group("/cmii")
|
||||||
|
|
||||||
|
{
|
||||||
|
// 在这个组中添加你需要的路由器
|
||||||
|
cmiiGroup.GET("/", func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "Welcome to cmii route group"})
|
||||||
|
})
|
||||||
|
|
||||||
|
cmiiGroup.POST("/upgrade", func(c *gin.Context) {
|
||||||
|
// 获取请求中的参数
|
||||||
|
var messageBody cmii.MessageBody
|
||||||
|
if err := c.ShouldBindJSON(&messageBody); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 处理请求
|
||||||
|
upgradeMessage := messageBody.DefaultPushUpgradeMessage()
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"upgrade result are ": upgradeMessage})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
15
message_pusher/router/OctopusRouter.go
Normal file
15
message_pusher/router/OctopusRouter.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OctopusRouter(r *gin.Engine) {
|
||||||
|
octopusGroup := r.Group("/octopus")
|
||||||
|
{
|
||||||
|
octopusGroup.GET("/", func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "Welcome to octopus route group"})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
<version>1.5.5.Final</version>
|
<version>1.5.5.Final</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!--<dependency>
|
<!--<dependency>
|
||||||
<groupId>org.mapstruct</groupId>
|
<groupId>org.mapstruct</groupId>
|
||||||
<artifactId>mapstruct-processor</artifactId>
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
|||||||
33
server/src/main/java/io/wdd/pusher/NtfyClient.java
Normal file
33
server/src/main/java/io/wdd/pusher/NtfyClient.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package io.wdd.pusher;
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.model.ClientType;
|
||||||
|
import io.wdd.pusher.core.publish.PubClient;
|
||||||
|
import io.wdd.pusher.core.publish.PubClientImpl;
|
||||||
|
import io.wdd.pusher.core.publish.PubServiceImpl;
|
||||||
|
|
||||||
|
public final class NtfyClient {
|
||||||
|
|
||||||
|
private PubClient pubClient;
|
||||||
|
|
||||||
|
|
||||||
|
public NtfyClient(ClientType type) {
|
||||||
|
switch (type) {
|
||||||
|
case PUB:
|
||||||
|
PubServiceImpl pubService = new PubServiceImpl();
|
||||||
|
this.pubClient = new PubClientImpl(pubService);
|
||||||
|
break;
|
||||||
|
case SUB:
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid client type");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PubClient getClient() {
|
||||||
|
return pubClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package io.wdd.pusher.core.common;
|
||||||
|
|
||||||
|
public class NtfyConstants {
|
||||||
|
|
||||||
|
public static final String DEFAULT_URL = "https://ntfy.sh/";
|
||||||
|
public static final String POST = "POST";
|
||||||
|
public static final String CONTENT_TYPE = "Content-Type";
|
||||||
|
public static final String DEFAULT_HOST = "ntfy.sh";
|
||||||
|
public static final String NTFY_CONNECTION_ERROR_MSG = "Unable to connect to ntfy host";
|
||||||
|
public static final String CONNECTION_ERROR_MSG = "Unable to open connection";
|
||||||
|
public static final String HTTPS = "https://";
|
||||||
|
public static final String GET = "GET";
|
||||||
|
public static final String JSON = "json";
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package io.wdd.pusher.core.exception;
|
||||||
|
|
||||||
|
public class NtfyConnectionException extends Exception {
|
||||||
|
|
||||||
|
public NtfyConnectionException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyConnectionException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyConnectionException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyConnectionException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package io.wdd.pusher.core.exception;
|
||||||
|
|
||||||
|
|
||||||
|
public class NtfyException extends Exception {
|
||||||
|
public NtfyException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NtfyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package io.wdd.pusher.core.exception;
|
||||||
|
|
||||||
|
|
||||||
|
public class NtfyStreamingException extends Exception {
|
||||||
|
public NtfyStreamingException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyStreamingException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyStreamingException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NtfyStreamingException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NtfyStreamingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
server/src/main/java/io/wdd/pusher/core/model/ACTIONS.java
Normal file
19
server/src/main/java/io/wdd/pusher/core/model/ACTIONS.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
public enum ACTIONS {
|
||||||
|
|
||||||
|
VIEW("view"),
|
||||||
|
BROADCAST("broadcast"),
|
||||||
|
HTTP("http");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
ACTIONS(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
server/src/main/java/io/wdd/pusher/core/model/Action.java
Normal file
49
server/src/main/java/io/wdd/pusher/core/model/Action.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
public class Action {
|
||||||
|
private ACTIONS action;
|
||||||
|
private String label;
|
||||||
|
private String url;
|
||||||
|
private boolean clear;
|
||||||
|
private String body;
|
||||||
|
|
||||||
|
public ACTIONS getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAction(ACTIONS action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClear() {
|
||||||
|
return clear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClear(boolean clear) {
|
||||||
|
this.clear = clear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(String body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
public enum ClientType {
|
||||||
|
PUB, SUB, STREAM;
|
||||||
|
}
|
||||||
381
server/src/main/java/io/wdd/pusher/core/model/NtfyRequest.java
Normal file
381
server/src/main/java/io/wdd/pusher/core/model/NtfyRequest.java
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a message object for publishing/ sending notification message.
|
||||||
|
* It contains various properties related to the structure of the notification.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NtfyRequest {
|
||||||
|
/**
|
||||||
|
* The topic to which you are publishing the message.
|
||||||
|
*/
|
||||||
|
private String topic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual message content to be published. It can contain markdown as well.
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The host or source to which you are publishing.
|
||||||
|
*/
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title or subject of the message.
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The priority level of the message.
|
||||||
|
*/
|
||||||
|
private PRIORITY priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of tags associated with the message.
|
||||||
|
*/
|
||||||
|
private List<String> tags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL associated with the message.
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the message content is in Markdown format.
|
||||||
|
*/
|
||||||
|
private boolean isMarkdown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of actions related to the message.
|
||||||
|
*/
|
||||||
|
private List<Action> actions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An attachment associated with the message. This will be the url linked of the attachment file.
|
||||||
|
*/
|
||||||
|
private String attach;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This local file that needs to be attached with the message,
|
||||||
|
*/
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The icon image url that needs to be used in the notification
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
/**
|
||||||
|
* The email address to which the notification is to be sent.
|
||||||
|
*/
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phone number to which the notification will be read to via call.
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access token, generated in ntfy CLI
|
||||||
|
*/
|
||||||
|
private String accessToken;
|
||||||
|
/**
|
||||||
|
* Basic auth in format username:password
|
||||||
|
*/
|
||||||
|
private String authToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the auth token to authenticate to Server
|
||||||
|
*
|
||||||
|
* @return auth token as String
|
||||||
|
*/
|
||||||
|
public String getAuthToken() {
|
||||||
|
return this.authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the auth token (Base64 of username:password)
|
||||||
|
*
|
||||||
|
* @param userCombo username/password combo for generation of access token
|
||||||
|
*/
|
||||||
|
public void setAuthToken(String userCombo) {
|
||||||
|
this.authToken = Base64.getEncoder().encodeToString(userCombo.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the accessToken for Authentication
|
||||||
|
*
|
||||||
|
* @return access token
|
||||||
|
*/
|
||||||
|
public String getAccessToken() {
|
||||||
|
return this.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param accessToken The authToken from CLI
|
||||||
|
*/
|
||||||
|
public void setAccessToken(String accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the phone number to which the notification will be read via a call.
|
||||||
|
*
|
||||||
|
* @return The phone number as a String.
|
||||||
|
*/
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the phone number to which the notification will be read via a call.
|
||||||
|
*
|
||||||
|
* @param phone The phone number to set as a String.
|
||||||
|
*/
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the email address to which the notification is to be sent.
|
||||||
|
*
|
||||||
|
* @return The email address as a String.
|
||||||
|
*/
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the email address to which the notification is to be sent.
|
||||||
|
*
|
||||||
|
* @param email The email address to set as a String.
|
||||||
|
*/
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon image URL that needs to be used in the notification.
|
||||||
|
*
|
||||||
|
* @return The icon image URL as a String.
|
||||||
|
*/
|
||||||
|
public String getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the icon image URL that needs to be used in the notification.
|
||||||
|
*
|
||||||
|
* @param icon The icon image URL to set as a String.
|
||||||
|
*/
|
||||||
|
public void setIcon(String icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the local file that needs to be attached with the message.
|
||||||
|
*
|
||||||
|
* @return The file name as a String.
|
||||||
|
*/
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of the local file that needs to be attached with the message.
|
||||||
|
*
|
||||||
|
* @param fileName The file name to set as a String.
|
||||||
|
*/
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attachment url associated with the message.
|
||||||
|
*
|
||||||
|
* @return The attachment url as a String.
|
||||||
|
*/
|
||||||
|
public String getAttach() {
|
||||||
|
return attach;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the attachment url for the message.
|
||||||
|
*
|
||||||
|
* @param attach The attachment url to set as a String.
|
||||||
|
*/
|
||||||
|
public void setAttach(String attach) {
|
||||||
|
this.attach = attach;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of actions related to the message.
|
||||||
|
*
|
||||||
|
* @return A list of Action objects.
|
||||||
|
*/
|
||||||
|
public List<Action> getActions() {
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of actions for the message.
|
||||||
|
*
|
||||||
|
* @param actions A list of Action objects to set.
|
||||||
|
*/
|
||||||
|
public void setActions(List<Action> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the message content is in Markdown format.
|
||||||
|
*
|
||||||
|
* @return True if the message content is in Markdown, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isMarkdown() {
|
||||||
|
return isMarkdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the message content is in Markdown format.
|
||||||
|
*
|
||||||
|
* @param markdown True to set the message content as Markdown, false otherwise.
|
||||||
|
*/
|
||||||
|
public void setMarkdown(boolean markdown) {
|
||||||
|
isMarkdown = markdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL associated with the message.
|
||||||
|
*
|
||||||
|
* @return The URL as a String.
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the URL for the message.
|
||||||
|
*
|
||||||
|
* @param url The URL to set as a String.
|
||||||
|
*/
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the actual message content.
|
||||||
|
*
|
||||||
|
* @return The message content as a String.
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the message content.
|
||||||
|
*
|
||||||
|
* @param message The message content to set as a String.
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the host or source of the message.
|
||||||
|
*
|
||||||
|
* @return The host as a String.
|
||||||
|
*/
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the host or source of the message.
|
||||||
|
*
|
||||||
|
* @param host The host to set as a String.
|
||||||
|
*/
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title or subject of the message.
|
||||||
|
*
|
||||||
|
* @return The title as a String.
|
||||||
|
*/
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title or subject of the message.
|
||||||
|
*
|
||||||
|
* @param title The title to set as a String.
|
||||||
|
*/
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the priority level of the message.
|
||||||
|
*
|
||||||
|
* @return The priority level as a PRIORITY enum value.
|
||||||
|
*/
|
||||||
|
public PRIORITY getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the priority level of the message.
|
||||||
|
*
|
||||||
|
* @param priority The priority level to set as a PRIORITY enum value.
|
||||||
|
*/
|
||||||
|
public void setPriority(PRIORITY priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of tags associated with the message.
|
||||||
|
*
|
||||||
|
* @return A list of tags as Strings.
|
||||||
|
*/
|
||||||
|
public List<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of tags associated with the message.
|
||||||
|
*
|
||||||
|
* @param tags A list of tags to set as Strings.
|
||||||
|
*/
|
||||||
|
public void setTags(List<String> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the topic to which the message is published.
|
||||||
|
*
|
||||||
|
* @return The topic as a String.
|
||||||
|
*/
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the topic to which the message is published.
|
||||||
|
*
|
||||||
|
* @param topic The topic to set as a String.
|
||||||
|
*/
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
27
server/src/main/java/io/wdd/pusher/core/model/PRIORITY.java
Normal file
27
server/src/main/java/io/wdd/pusher/core/model/PRIORITY.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
public enum PRIORITY {
|
||||||
|
MAX("Max", 5),
|
||||||
|
HIGH("High", 4),
|
||||||
|
DEFAULT("Default", 3),
|
||||||
|
LOW("Low", 2),
|
||||||
|
MIN("Min", 1);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final int level;
|
||||||
|
|
||||||
|
PRIORITY(String name, int level) {
|
||||||
|
this.name = name;
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
public class PublishResponse {
|
||||||
|
}
|
||||||
117
server/src/main/java/io/wdd/pusher/core/model/RequestModel.java
Normal file
117
server/src/main/java/io/wdd/pusher/core/model/RequestModel.java
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RequestModel {
|
||||||
|
|
||||||
|
private String topic;
|
||||||
|
private String message;
|
||||||
|
private String title;
|
||||||
|
private List<String> tags;
|
||||||
|
private int priority;
|
||||||
|
private boolean markdown;
|
||||||
|
private List<Action> actions;
|
||||||
|
private String attach;
|
||||||
|
private String fileName;
|
||||||
|
private String icon;
|
||||||
|
private String email;
|
||||||
|
private String call;
|
||||||
|
|
||||||
|
public String getCall() {
|
||||||
|
return call;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCall(String call) {
|
||||||
|
this.call = call;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(String icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttach() {
|
||||||
|
return attach;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttach(String attach) {
|
||||||
|
this.attach = attach;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Action> getActions() {
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActions(List<Action> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(List<String> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMarkdown() {
|
||||||
|
return markdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarkdown(boolean markdown) {
|
||||||
|
this.markdown = markdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package io.wdd.pusher.core.model;
|
||||||
|
|
||||||
|
|
||||||
|
public class StreamRequest {
|
||||||
|
private String host;
|
||||||
|
private String topic;
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package io.wdd.pusher.core.publish;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.NtfyRequest;
|
||||||
|
|
||||||
|
public interface PubClient {
|
||||||
|
String sendNotification(NtfyRequest ntfyRequest) throws NtfyException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package io.wdd.pusher.core.publish;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.NtfyRequest;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class PubClientImpl implements PubClient {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(PubClientImpl.class.getName());
|
||||||
|
private final PubService pubService;
|
||||||
|
|
||||||
|
public PubClientImpl(PubService pubService) {
|
||||||
|
this.pubService = pubService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sendNotification(NtfyRequest ntfyRequest) throws NtfyException {
|
||||||
|
String response = pubService.publish(ntfyRequest);
|
||||||
|
if (null != response) {
|
||||||
|
logger.info("Response from server : " + response);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package io.wdd.pusher.core.publish;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.NtfyRequest;
|
||||||
|
|
||||||
|
public interface PubService {
|
||||||
|
String publish(NtfyRequest ntfyRequest) throws NtfyException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package io.wdd.pusher.core.publish;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.wdd.pusher.core.common.NtfyConstants;
|
||||||
|
import io.wdd.pusher.core.exception.NtfyConnectionException;
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.NtfyRequest;
|
||||||
|
import io.wdd.pusher.core.model.PRIORITY;
|
||||||
|
import io.wdd.pusher.core.model.RequestModel;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class PubServiceImpl implements PubService {
|
||||||
|
private static final Logger logger = Logger.getLogger(PubServiceImpl.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String publish(NtfyRequest request) throws NtfyException {
|
||||||
|
return publishMessage(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String publishMessage(NtfyRequest request) throws NtfyException {
|
||||||
|
String response = null;
|
||||||
|
try {
|
||||||
|
if (null == request.getHost()) {
|
||||||
|
request.setUrl(NtfyConstants.DEFAULT_URL);
|
||||||
|
request.setHost(NtfyConstants.DEFAULT_HOST);
|
||||||
|
} else {
|
||||||
|
request.setUrl(NtfyConstants.HTTPS + request.getHost() + "/");
|
||||||
|
}
|
||||||
|
if (null == request.getPriority()) {
|
||||||
|
request.setPriority(PRIORITY.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
response = sendPublishRequest(request);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.severe(NtfyConstants.CONNECTION_ERROR_MSG);
|
||||||
|
throw new NtfyException(e);
|
||||||
|
} catch (NtfyConnectionException e) {
|
||||||
|
logger.severe(NtfyConstants.NTFY_CONNECTION_ERROR_MSG);
|
||||||
|
throw new NtfyException(e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sendPublishRequest(NtfyRequest request) throws Exception {
|
||||||
|
try {
|
||||||
|
URL obj = new URL(request.getUrl());
|
||||||
|
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
|
||||||
|
|
||||||
|
|
||||||
|
con.setRequestMethod(NtfyConstants.POST);
|
||||||
|
con.setConnectTimeout(10000);
|
||||||
|
con.setRequestProperty(NtfyConstants.CONTENT_TYPE, "application/json");
|
||||||
|
|
||||||
|
//handle authentication (if supplied)
|
||||||
|
if (request.getAccessToken() != null) {
|
||||||
|
con.setRequestProperty("Authorization", "Bearer " + request.getAccessToken());
|
||||||
|
} else if (request.getAuthToken() != null) {
|
||||||
|
con.setRequestProperty("Authorization", "Basic " + request.getAuthToken());
|
||||||
|
}
|
||||||
|
// Enable input/output streams
|
||||||
|
con.setDoOutput(true);
|
||||||
|
|
||||||
|
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
|
||||||
|
wr.writeBytes(new ObjectMapper().writeValueAsString(createPublishRequest(request)));
|
||||||
|
wr.flush();
|
||||||
|
}
|
||||||
|
// Get the response from the server
|
||||||
|
int responseCode = con.getResponseCode();
|
||||||
|
|
||||||
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
try (java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(con.getInputStream()))) {
|
||||||
|
String inputLine;
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
response.append(inputLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.toString();
|
||||||
|
} else {
|
||||||
|
throw new NtfyConnectionException(NtfyConstants.NTFY_CONNECTION_ERROR_MSG + " : " + responseCode + " " + con.getResponseMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new NtfyConnectionException(NtfyConstants.CONNECTION_ERROR_MSG, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestModel createPublishRequest(NtfyRequest request) {
|
||||||
|
RequestModel model = new RequestModel();
|
||||||
|
model.setTopic(request.getTopic());
|
||||||
|
model.setMessage(request.getMessage());
|
||||||
|
model.setTitle(request.getTitle());
|
||||||
|
model.setTags(request.getTags());
|
||||||
|
model.setMarkdown(request.isMarkdown());
|
||||||
|
model.setPriority(request.getPriority().getLevel());
|
||||||
|
model.setActions(request.getActions());
|
||||||
|
model.setAttach(request.getAttach());
|
||||||
|
model.setFileName(request.getFileName());
|
||||||
|
model.setIcon(request.getIcon());
|
||||||
|
model.setEmail(request.getEmail());
|
||||||
|
model.setCall(request.getPhone());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package io.wdd.pusher.core.stream;
|
||||||
|
|
||||||
|
public interface StreamingDataListener {
|
||||||
|
void onDataReceived(String data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package io.wdd.pusher.core.stream;
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.common.NtfyConstants;
|
||||||
|
import io.wdd.pusher.core.exception.NtfyStreamingException;
|
||||||
|
import io.wdd.pusher.core.model.StreamRequest;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class StreamingService {
|
||||||
|
private final String streamingUrl;
|
||||||
|
private boolean running;
|
||||||
|
private StreamingDataListener dataListener;
|
||||||
|
|
||||||
|
public StreamingService(StreamRequest request) {
|
||||||
|
this.streamingUrl = NtfyConstants.HTTPS + request.getHost() + "/" +
|
||||||
|
request.getTopic() + "/" + NtfyConstants.JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws NtfyStreamingException {
|
||||||
|
try {
|
||||||
|
running = true;
|
||||||
|
Thread streamThread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
URL url = new URL(streamingUrl);
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
|
connection.setRequestMethod(NtfyConstants.GET);
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line != null) {
|
||||||
|
if (dataListener != null) {
|
||||||
|
dataListener.onDataReceived(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
connection.disconnect();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
streamThread.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new NtfyStreamingException(NtfyConstants.CONNECTION_ERROR_MSG, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDataListener(StreamingDataListener listener) {
|
||||||
|
this.dataListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package io.wdd.pusher.example;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.pusher.NtfyClient;
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.*;
|
||||||
|
import io.wdd.pusher.core.publish.PubClient;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PublishExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws NtfyException {
|
||||||
|
PubClient client = new NtfyClient(ClientType.PUB).getClient();
|
||||||
|
NtfyRequest request = new NtfyRequest();
|
||||||
|
request.setTopic("test_ntfy2");
|
||||||
|
request.setMessage("Look ma, **bold text**, *italics*, ...");
|
||||||
|
request.setTitle("This is the obj msg");
|
||||||
|
request.setPriority(PRIORITY.MAX);
|
||||||
|
request.setAttach("https://media.licdn.com/dms/image/D4E03AQEZTNXuX3kG7g/profile-displayphoto-shrink_400_400/0/1669618932666?e=1699488000&v=beta&t=q2z_UDFvwTZa02SligKZqgwk66BjuXQZxWtQF_K1Jqw");
|
||||||
|
request.setFileName("Screenshot.png");
|
||||||
|
request.setIcon("https://styles.redditmedia.com/t5_32uhe/styles/communityIcon_xnt6chtnr2j21.png");
|
||||||
|
request.setEmail("mahesh.b.pec@gmail.com");
|
||||||
|
request.setPhone("");
|
||||||
|
|
||||||
|
Action action = new Action();
|
||||||
|
action.setAction(ACTIONS.VIEW);
|
||||||
|
action.setLabel("Open github");
|
||||||
|
action.setUrl("https://github.com/MaheshBabu11/ntfy-java");
|
||||||
|
action.setClear(true);
|
||||||
|
|
||||||
|
List<Action> actions = new ArrayList<>(List.of(action));
|
||||||
|
List<String> tags = new ArrayList<>(List.of("+1", "warning"));
|
||||||
|
request.setTags(tags);
|
||||||
|
request.setMarkdown(true);
|
||||||
|
request.setActions(actions);
|
||||||
|
client.sendNotification(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package io.wdd.pusher.example;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.exception.NtfyStreamingException;
|
||||||
|
import io.wdd.pusher.core.model.StreamRequest;
|
||||||
|
import io.wdd.pusher.core.stream.StreamingService;
|
||||||
|
|
||||||
|
public class StreamingExample {
|
||||||
|
public static void main(String[] args) throws NtfyStreamingException {
|
||||||
|
|
||||||
|
StreamRequest request = new StreamRequest();
|
||||||
|
request.setHost("ntfy.sh");
|
||||||
|
request.setTopic("test_ntfy2");
|
||||||
|
|
||||||
|
StreamingService streamingConnection = new StreamingService(request);
|
||||||
|
streamingConnection.setDataListener(data -> {
|
||||||
|
// Process the incoming data here
|
||||||
|
System.out.println("Received data: " + data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start the streaming connection
|
||||||
|
streamingConnection.start();
|
||||||
|
|
||||||
|
// Keep the connection open and receive data indefinitely
|
||||||
|
// To stop the connection, call streamingConnection.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
34
server/src/test/java/io/wdd/pusher/PusherTest.java
Normal file
34
server/src/test/java/io/wdd/pusher/PusherTest.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package io.wdd.pusher;
|
||||||
|
|
||||||
|
import io.wdd.pusher.core.exception.NtfyException;
|
||||||
|
import io.wdd.pusher.core.model.ClientType;
|
||||||
|
import io.wdd.pusher.core.model.NtfyRequest;
|
||||||
|
import io.wdd.pusher.core.model.PRIORITY;
|
||||||
|
import io.wdd.pusher.core.publish.PubClient;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class PusherTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
PubClient client = new NtfyClient(ClientType.PUB).getClient();
|
||||||
|
|
||||||
|
NtfyRequest ntfyRequest = new NtfyRequest();
|
||||||
|
ntfyRequest.setHost("push.107421.xyz");
|
||||||
|
ntfyRequest.setTopic("octopus");
|
||||||
|
ntfyRequest.setTitle("来自Java的测试推送");
|
||||||
|
ntfyRequest.setPriority(PRIORITY.HIGH);
|
||||||
|
ntfyRequest.setAccessToken("tk_zvdb67fwj1hrjivkq3ga9z7u63av5");
|
||||||
|
ntfyRequest.setMessage("这是一条来自Java的测试推送");
|
||||||
|
ntfyRequest.setAuthToken("tk_zvdb67fwj1hrjivkq3ga9z7u63av5");
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.sendNotification(ntfyRequest);
|
||||||
|
} catch (NtfyException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,7 +44,7 @@ public class TestImageSyncScheduler {
|
|||||||
ArrayList<String> ImageFullNameList = new ArrayList<>(List.of(
|
ArrayList<String> ImageFullNameList = new ArrayList<>(List.of(
|
||||||
// "harbor.cdcyy.com.cn/cmii/cmii-live-operator:5.2.0",
|
// "harbor.cdcyy.com.cn/cmii/cmii-live-operator:5.2.0",
|
||||||
// "harbor.cdcyy.com.cn/cmii/cmii/srs:v5.0.195"
|
// "harbor.cdcyy.com.cn/cmii/cmii/srs:v5.0.195"
|
||||||
"harbor.cdcyy.com.cn/cmii/cmii-uav-platform:5.3.0-cqly-042202"
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-industrial-portfolio:54.0-cqly-042301"
|
||||||
));
|
));
|
||||||
|
|
||||||
Boolean downloadAndCompressOnly = false;
|
Boolean downloadAndCompressOnly = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user