Merge branch 'refs/heads/local-ss' into main
This commit is contained in:
@@ -71,7 +71,7 @@ func (c *CmiiUpdateMessage) SendMessage() (message Message) {
|
|||||||
var m Message
|
var m Message
|
||||||
err = json.Unmarshal(bodyBytes, &m)
|
err = json.Unmarshal(bodyBytes, &m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorF("Error unmarshaling response body to JSON:", err)
|
log.ErrorF("Error unmarshaling response body to JSON: %s", err.Error())
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package pusher
|
package pusher
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
"wdd.io/agent-common/utils"
|
||||||
|
)
|
||||||
|
|
||||||
func TestCmiiUpdateMessage_SendMessage(t *testing.T) {
|
func TestCmiiUpdateMessage_SendMessage(t *testing.T) {
|
||||||
c := &CmiiUpdateMessage{
|
c := &CmiiUpdateMessage{
|
||||||
@@ -12,5 +15,7 @@ func TestCmiiUpdateMessage_SendMessage(t *testing.T) {
|
|||||||
DeployStatus: false,
|
DeployStatus: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils.BeautifulPrint(c)
|
||||||
|
|
||||||
c.SendMessage()
|
c.SendMessage()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ type AgentServerInfo struct {
|
|||||||
ServerIPInV4 string `json:"serverIpInV4" yaml:"serverIpInV4"`
|
ServerIPInV4 string `json:"serverIpInV4" yaml:"serverIpInV4"`
|
||||||
ServerIPPbV6 string `json:"serverIpPbV6" yaml:"serverIpPbV6"`
|
ServerIPPbV6 string `json:"serverIpPbV6" yaml:"serverIpPbV6"`
|
||||||
ServerIPInV6 string `json:"serverIpInV6" yaml:"serverIpInV6"`
|
ServerIPInV6 string `json:"serverIpInV6" yaml:"serverIpInV6"`
|
||||||
|
City string `json:"city" yaml:"city"`
|
||||||
|
Region string `json:"region" yaml:"region"`
|
||||||
|
Country string `json:"country" yaml:"country"`
|
||||||
|
Organization string `json:"organization" yaml:"organization"`
|
||||||
|
TimeZone string `json:"timeZone" yaml:"timeZone"`
|
||||||
Location string `json:"location" yaml:"location"`
|
Location string `json:"location" yaml:"location"`
|
||||||
Provider string `json:"provider" yaml:"provider"`
|
Provider string `json:"provider" yaml:"provider"`
|
||||||
ManagePort string `json:"managePort" yaml:"managePort"`
|
ManagePort string `json:"managePort" yaml:"managePort"`
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
image2 "wdd.io/agent-common/image"
|
image2 "wdd.io/agent-common/image"
|
||||||
"wdd.io/agent-common/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var k8sConfigFilePath = "/root/wdd/kube_config_cluster.yml"
|
var k8sConfigFilePath = "/root/wdd/kube_config_cluster.yml"
|
||||||
@@ -142,36 +141,51 @@ func K8sDeploymentUpdateTag(supreme, appName, newTag string) (bool, string) {
|
|||||||
updateResultLog := ""
|
updateResultLog := ""
|
||||||
|
|
||||||
containers := deployment.Spec.Template.Spec.Containers
|
containers := deployment.Spec.Template.Spec.Containers
|
||||||
if len(containers) == 1 {
|
|
||||||
// only update this kind
|
// 只支持container的数量为1的形式
|
||||||
container := containers[0]
|
container := containers[0]
|
||||||
|
|
||||||
oldName := container.Image
|
oldName := container.Image
|
||||||
|
|
||||||
split := strings.Split(container.Image, ":")
|
split := strings.Split(container.Image, ":")
|
||||||
if strings.HasPrefix(container.Image, image2.CmiiHarborPrefix) {
|
if strings.HasPrefix(container.Image, image2.CmiiHarborPrefix) {
|
||||||
// harbor
|
// harbor
|
||||||
container.Image = split[0] + ":" + newTag
|
container.Image = split[0] + ":" + newTag
|
||||||
} else if strings.Contains(container.Image, "8033") {
|
} else if strings.Contains(container.Image, "8033") {
|
||||||
// 192.168.6.6:8033/rancher/k8s-dns-sidecar:v1.0.2
|
// 192.168.6.6:8033/rancher/k8s-dns-sidecar:v1.0.2
|
||||||
|
// 重新拼接
|
||||||
container.Image = split[0] + ":" + split[1] + ":" + newTag
|
container.Image = split[0] + ":" + split[1] + ":" + newTag
|
||||||
}
|
}
|
||||||
|
log.DebugF("[DeploymentUpdateTag] - update [%s] [%s] from [%s] to [%s]", deployment.Namespace, appName, oldName, container.Image)
|
||||||
|
|
||||||
updateResultLog = fmt.Sprintf(" [%s] [%s] [%s] from [%s] to [%s]", utils.TimeSplitFormatString(), supreme, appName, oldName, container.Image)
|
// 更新Cmii BIZ_GROUP
|
||||||
log.Info(updateResultLog)
|
tagVersion := newTag
|
||||||
|
if strings.Contains(newTag, "-") {
|
||||||
|
tagVersion = strings.Split(newTag, "-")[0]
|
||||||
|
}
|
||||||
|
envList := container.Env
|
||||||
|
for _, envVar := range envList {
|
||||||
|
if envVar.Name == "IMAGE_VERSION" {
|
||||||
|
envVar.Value = tagVersion
|
||||||
|
}
|
||||||
|
if envVar.Name == "BIZ_CONFIG_GROUP" {
|
||||||
|
envVar.Value = tagVersion
|
||||||
|
}
|
||||||
|
if envVar.Name == "SYS_CONFIG_GROUP" {
|
||||||
|
envVar.Value = tagVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.DebugF("[DeploymentUpdateTag] - update env IMAGE_VERSION to [%s]", tagVersion)
|
||||||
|
|
||||||
// re assign
|
// 赋值回去 很关键
|
||||||
deployment.Spec.Template.Spec.Containers[0] = container
|
deployment.Spec.Template.Spec.Containers[0] = container
|
||||||
|
|
||||||
// update
|
// update
|
||||||
_, err := k8sClient.AppsV1().Deployments(deployment.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
|
_, err := k8sClient.AppsV1().Deployments(deployment.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorF("[K8sDeploymentUpdateTag] - update [%s] [%s] from [%s] to [%s] error ! %s", supreme, appName, split[1], container.Image, err.Error())
|
sprintf := fmt.Sprintf("[DeploymentUpdateTag] - update [%s] [%s] from [%s] to [%s] error ! %s", deployment.Namespace, appName, split[1], container.Image, err.Error())
|
||||||
return false, ""
|
log.Error(sprintf)
|
||||||
}
|
return false, sprintf
|
||||||
} else if len(containers) == 2 {
|
|
||||||
log.ErrorF("[K8sDeploymentUpdateTag] - cant update app with 2 containers !")
|
|
||||||
return false, ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, updateResultLog
|
return true, updateResultLog
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ func INIT(octopusAgentConfigFileName string) chan bool {
|
|||||||
agentInfo := a_status.ReportAgentInfo()
|
agentInfo := a_status.ReportAgentInfo()
|
||||||
refreshAgentInfoByStatusInfo(agentInfo, agentServerInfo)
|
refreshAgentInfoByStatusInfo(agentInfo, agentServerInfo)
|
||||||
|
|
||||||
|
// 如果从在本机文件,那么会使用手动写入的环境变量 进行覆盖
|
||||||
if utils.FileExistAndNotNull(AgentServerInfoLocalFilePath) {
|
if utils.FileExistAndNotNull(AgentServerInfoLocalFilePath) {
|
||||||
|
|
||||||
// 获取系统的环境变量
|
// 获取系统的环境变量
|
||||||
@@ -246,15 +247,10 @@ func buildOctopusTCPConnect(agentConfig *viper.Viper) *rabbitmq.RabbitTCPConnect
|
|||||||
|
|
||||||
func refreshAgentInfoByStatusInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) {
|
func refreshAgentInfoByStatusInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) {
|
||||||
|
|
||||||
// host info
|
|
||||||
agentServerInfo.ServerName = agentInfo.HostInfo.Hostname
|
|
||||||
agentServerInfo.MachineID = agentInfo.HostInfo.HostID
|
|
||||||
|
|
||||||
// cpu part
|
// cpu part
|
||||||
agentServerInfo.CPUCore = strconv.FormatInt(int64(agentInfo.CPUInfo.NumCores), 10)
|
agentServerInfo.CPUCore = strconv.FormatInt(int64(agentInfo.CPUInfo.NumCores), 10)
|
||||||
if len(agentInfo.CPUInfo.CPUInfo) > 0 {
|
if len(agentInfo.CPUInfo.CPUInfo) > 0 {
|
||||||
marshal, _ := json.Marshal(agentInfo.CPUInfo.CPUInfo[0].ModelName)
|
agentServerInfo.CPUBrand = agentInfo.CPUInfo.CPUInfo[0].ModelName
|
||||||
agentServerInfo.CPUBrand = string(marshal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// os info
|
// os info
|
||||||
@@ -288,16 +284,162 @@ func refreshAgentInfoByStatusInfo(agentInfo *a_status.AgentInfo, agentServerInfo
|
|||||||
// network part
|
// network part
|
||||||
refreshAgentNetworkInfo(agentInfo, agentServerInfo)
|
refreshAgentNetworkInfo(agentInfo, agentServerInfo)
|
||||||
|
|
||||||
|
// host info
|
||||||
|
agentServerInfo.ServerName = uniformAgentServerName(agentInfo, agentServerInfo)
|
||||||
|
agentServerInfo.MachineID = agentInfo.HostInfo.HostID
|
||||||
|
|
||||||
|
// io test
|
||||||
|
agentServerInfo.IoSpeed = testDiskIO()
|
||||||
|
|
||||||
log.DebugF("[refreshAgentInfoByStatusInfo] - ok !")
|
log.DebugF("[refreshAgentInfoByStatusInfo] - ok !")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func uniformAgentServerName(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) string {
|
||||||
|
|
||||||
|
hostname := agentInfo.HostInfo.Hostname
|
||||||
|
// Shanghai-amd64-01
|
||||||
|
if strings.Count(hostname, "-") == 2 {
|
||||||
|
split := strings.Split(hostname, "-")
|
||||||
|
if split[1] == getMachineType(agentInfo.HostInfo.KernelArch) {
|
||||||
|
// 第二位是 amd64 arm64
|
||||||
|
return hostname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不是标准的AgentName格式
|
||||||
|
city := agentServerInfo.City
|
||||||
|
city = strings.Title(city)
|
||||||
|
if strings.Contains(city, " ") {
|
||||||
|
city = strings.Join(strings.Split(city, " "), "")
|
||||||
|
}
|
||||||
|
// uniform city format
|
||||||
|
agentServerInfo.City = city
|
||||||
|
|
||||||
|
// linux host architecture
|
||||||
|
arch := getMachineType(agentInfo.HostInfo.KernelArch)
|
||||||
|
|
||||||
|
var numS string
|
||||||
|
if agentServerInfo.ServerIPInV4 != "" {
|
||||||
|
split := strings.Split(agentServerInfo.ServerIPInV4, ".")
|
||||||
|
numS = split[3]
|
||||||
|
} else {
|
||||||
|
// Seed the random number generator
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
|
// Generate a random number between 1 and 999
|
||||||
|
num := rand.Intn(999) + 1
|
||||||
|
|
||||||
|
// Format the number as a string with leading zeros
|
||||||
|
numS = fmt.Sprintf("%03d", num)
|
||||||
|
}
|
||||||
|
|
||||||
|
return city + "-" + arch + "-" + numS
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDiskIO() string {
|
||||||
|
log.InfoF("testDiskIO - start !")
|
||||||
|
|
||||||
|
// Create a temporary file to test disk I/O
|
||||||
|
f, err := os.CreateTemp("", "test_disk_io")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
os.Remove(f.Name())
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Write data to the file
|
||||||
|
data := make([]byte, 10240*10240) // 10MB
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
_, err = f.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read data from the file
|
||||||
|
startTime := time.Now()
|
||||||
|
buf := make([]byte, 10240*10240) // 10MB
|
||||||
|
for {
|
||||||
|
n, err := f.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsedTime := time.Since(startTime).Seconds()
|
||||||
|
|
||||||
|
// Calculate the disk I/O speed in MB/s
|
||||||
|
speed := float64(len(data)) / (elapsedTime * 10240 * 10240)
|
||||||
|
|
||||||
|
sprintf := fmt.Sprintf("%.2f MB/s", speed)
|
||||||
|
|
||||||
|
log.InfoF("testDiskIO - end io speed are => %s", sprintf)
|
||||||
|
return sprintf
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMachineType(arch string) string {
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case strings.HasSuffix(arch, "386") || arch == "i386":
|
||||||
|
return "ia32"
|
||||||
|
case strings.HasSuffix(arch, "amd64") || arch == "x86_64":
|
||||||
|
return "amd64"
|
||||||
|
case arch == "armv5tel":
|
||||||
|
return "arm32"
|
||||||
|
case arch == "armv6l":
|
||||||
|
return "arm32"
|
||||||
|
case arch == "armv7" || arch == "armv7l":
|
||||||
|
return "arm32"
|
||||||
|
case arch == "armv8" || arch == "aarch64":
|
||||||
|
return "arm64"
|
||||||
|
case arch == "mips":
|
||||||
|
return "mips32"
|
||||||
|
case arch == "mipsle":
|
||||||
|
return "mips32le"
|
||||||
|
case arch == "mips64":
|
||||||
|
return "mips64"
|
||||||
|
case arch == "mips64le":
|
||||||
|
return "mips64le"
|
||||||
|
case arch == "ppc64":
|
||||||
|
return "ppc64"
|
||||||
|
case arch == "ppc64le":
|
||||||
|
return "ppc64le"
|
||||||
|
case arch == "riscv64":
|
||||||
|
return "riscv64"
|
||||||
|
case arch == "s390x":
|
||||||
|
return "s390x"
|
||||||
|
default:
|
||||||
|
fmt.Println("error: The architecture is not supported.")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func refreshAgentNetworkInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) {
|
func refreshAgentNetworkInfo(agentInfo *a_status.AgentInfo, agentServerInfo *a_agent.AgentServerInfo) {
|
||||||
|
|
||||||
// 测试网卡名称
|
// 获取Agent的公网服务信息
|
||||||
//testCases := []string{"ens33", "eno1", "enp0s3", "enp1s2", "eth0", "enp2s5", "enx1234567890ab", "ens1234567890ab", "enp1234567890ab", "enp1234567890ab", "enp1", "lo","","docker0", "virbr0", "veth0",}
|
publicNetworkInfo := a_status.PublicNetworkInfo{}
|
||||||
//for _, tc := range testCases {
|
publicNetworkInfo.GetPublicNetworkInfo()
|
||||||
// fmt.Printf("Network interface '%s' is %s\n", tc, fmt.Sprintf("%v", isNetworkInterface(tc)))
|
|
||||||
//}
|
marshal, _ := json.Marshal(publicNetworkInfo)
|
||||||
|
log.InfoF("refreshAgentNetworkInfo - public network info is %s", marshal)
|
||||||
|
|
||||||
|
if publicNetworkInfo.IP != "" {
|
||||||
|
agentServerInfo.ServerIPPbV4 = publicNetworkInfo.IP
|
||||||
|
agentServerInfo.Region = publicNetworkInfo.Region
|
||||||
|
agentServerInfo.City = publicNetworkInfo.City
|
||||||
|
agentServerInfo.Country = publicNetworkInfo.Country
|
||||||
|
agentServerInfo.Location = publicNetworkInfo.Loc
|
||||||
|
agentServerInfo.Organization = publicNetworkInfo.Org
|
||||||
|
agentServerInfo.TimeZone = publicNetworkInfo.Timezone
|
||||||
|
}
|
||||||
|
|
||||||
// inner ip v4 v6
|
// inner ip v4 v6
|
||||||
for _, networkInfo := range agentInfo.NetworkInfo {
|
for _, networkInfo := range agentInfo.NetworkInfo {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shirou/gopsutil/v3/net"
|
"github.com/shirou/gopsutil/v3/net"
|
||||||
|
"io"
|
||||||
net2 "net"
|
net2 "net"
|
||||||
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -20,6 +22,53 @@ type NetworkMetric struct {
|
|||||||
RecvSpeed float64
|
RecvSpeed float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PublicNetworkInfo struct {
|
||||||
|
IP string `json:"ip,omitempty"`
|
||||||
|
City string `json:"city,omitempty"`
|
||||||
|
Region string `json:"region,omitempty"`
|
||||||
|
Country string `json:"country,omitempty"`
|
||||||
|
Loc string `json:"loc,omitempty"`
|
||||||
|
Org string `json:"org,omitempty"`
|
||||||
|
Postal string `json:"postal,omitempty"`
|
||||||
|
Timezone string `json:"timezone,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pn *PublicNetworkInfo) GetPublicNetworkInfo() {
|
||||||
|
|
||||||
|
url := "https://ipinfo.io"
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", "Bearer 6ecb0db9bd8f19")
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 5 * time.Second, // set timeout to 10 seconds
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, &pn)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//utils.BeautifulPrint(pn)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
type NetworkInfo struct {
|
type NetworkInfo struct {
|
||||||
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
|
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
|
||||||
MTU int `json:"mtu"` // maximum transmission unit
|
MTU int `json:"mtu"` // maximum transmission unit
|
||||||
|
|||||||
@@ -42,3 +42,9 @@ func TestGetNetworkInfo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPublicNetworkInfo_GetPublicNetworkInfo(t *testing.T) {
|
||||||
|
p := &PublicNetworkInfo{}
|
||||||
|
|
||||||
|
p.GetPublicNetworkInfo()
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
image2 "wdd.io/agent-common/image"
|
image2 "wdd.io/agent-common/image"
|
||||||
@@ -9,9 +10,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var DefaultCmiiOperator = CmiiK8sOperator{}
|
var DefaultCmiiOperator = CmiiK8sOperator{}
|
||||||
|
var updateLogPath = "/home/wdd/IdeaProjects/ProjectOctopus/agent-operator/log/cmii-update-log.txt"
|
||||||
|
|
||||||
// var updateLogPath = "C:\\Users\\wddsh\\Documents\\IdeaProjects\\ProjectOctopus\\cmii_operator\\log\\cmii-update-log.txt"
|
func init() {
|
||||||
var updateLogPath = "/home/wdd/IdeaProjects/ProjectOctopus/cmii_operator/log/cmii-update-log.txt"
|
switch runtime.GOOS {
|
||||||
|
case "linux":
|
||||||
|
updateLogPath = "/home/wdd/IdeaProjects/ProjectOctopus/agent-operator/log/cmii-update-log.txt"
|
||||||
|
case "windows":
|
||||||
|
updateLogPath = "C:\\Users\\wddsh\\Documents\\IdeaProjects\\ProjectOctopus\\agent-operator\\log\\cmii-update-log.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FindAppNotHealthyOrRestartCountGreaterThanN 重启次数大于N的所有Deployment
|
// FindAppNotHealthyOrRestartCountGreaterThanN 重启次数大于N的所有Deployment
|
||||||
func FindAppNotHealthyOrRestartCountGreaterThanN(cmiiEnv string, restartCount int32) []CmiiDeploymentInterface {
|
func FindAppNotHealthyOrRestartCountGreaterThanN(cmiiEnv string, restartCount int32) []CmiiDeploymentInterface {
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ func TestUpdateCmiiDeploymentImageTag(t *testing.T) {
|
|||||||
|
|
||||||
// 计算20:00的时间
|
// 计算20:00的时间
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
targetTime := time.Date(now.Year(), now.Month(), now.Day(), 12, 03, 00, 0, now.Location())
|
targetTime := time.Date(now.Year(), now.Month(), now.Day(), 12, 14, 00, 0, now.Location())
|
||||||
|
|
||||||
duration := time.Duration(0)
|
duration := time.Duration(0)
|
||||||
|
|
||||||
@@ -275,10 +275,9 @@ func TestUpdateCmiiDeploymentImageTag(t *testing.T) {
|
|||||||
|
|
||||||
appNameTagMap := map[string]string{
|
appNameTagMap := map[string]string{
|
||||||
//"cmii-uav-multilink": "5.5.0",
|
//"cmii-uav-multilink": "5.5.0",
|
||||||
"cmii-uav-platform-cms-portal": "5.5.0-042801",
|
//"cmii-uav-mqtthandler": "5.5.0",
|
||||||
"cmii-uav-platform": "5.5.0-042801",
|
//"cmii-uav-mission": "5.5.0-042901",
|
||||||
"cmii-uav-platform-oms": "5.5.0-042801",
|
"cmii-uav-surveillance": "5.5.0-042901",
|
||||||
"cmii-uav-user": "5.5.0-042801",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for appName, newTag := range appNameTagMap {
|
for appName, newTag := range appNameTagMap {
|
||||||
|
|||||||
@@ -443,6 +443,8 @@ func (op *CmiiK8sOperator) DeploymentUpdateTag(cmiiEnv, appName, newTag string)
|
|||||||
// 更新Cmii BIZ_GROUP
|
// 更新Cmii BIZ_GROUP
|
||||||
tagVersion := newTag
|
tagVersion := newTag
|
||||||
if strings.Contains(newTag, "-") {
|
if strings.Contains(newTag, "-") {
|
||||||
|
// 5.0.0-1243
|
||||||
|
// 5.0.0-1243-1234
|
||||||
tagVersion = strings.Split(newTag, "-")[0]
|
tagVersion = strings.Split(newTag, "-")[0]
|
||||||
}
|
}
|
||||||
envList := container.Env
|
envList := container.Env
|
||||||
|
|||||||
@@ -1,119 +1,33 @@
|
|||||||
2024-01-10-14-54-51 uavcloud-demo cmii-uav-platform 5.2.0-011002 5.2.0-011003
|
2024-04-18-17-20-00 uavcloud-demo cmii-uav-integration 5.5.0 5.5.0-0418
|
||||||
2024-01-10-14-59-07 uavcloud-devflight cmii-uav-depotautoreturn 123sdsa45678 12345678
|
2024-04-19-09-30-00 uavcloud-demo cmii-uav-platform-open 5.5.0 5.5.0-0419
|
||||||
2024-01-10-15-09-29 uavcloud-demo cmii-uav-platform 5.2.0-011003 5.2.0-011004
|
2024-04-22-09-18-00 uavcloud-demo cmii-uav-airspace 5.5.0 5.5.0-0422
|
||||||
2024-01-10-17-15-04 uavcloud-test cmii-suav-supervision 5.2.0-validation 5.2.0-011001
|
2024-04-22-14-20-00 uavcloud-demo cmii-uav-airspace 5.5.0-0422 5.5.0-042201
|
||||||
2024-01-11-11-06-10 uavcloud-demo cmii-uav-platform 5.2.0-011004 5.2.0-011101
|
2024-04-22-16-57-00 uavcloud-demo cmii-uav-airspace 5.5.0-042201 5.5.0-042202
|
||||||
2024-01-11-11-36-56 uavcloud-demo cmii-uav-waypoint 5.2.0 5.2.0-011101
|
2024-04-23-09-27-00 uavcloud-demo cmii-uav-device 5.5.0 5.5.0-042301
|
||||||
2024-01-11-11-58-15 uavcloud-uavms uavms-lowaltitude-platform 5.1.0 5.2.0-011101
|
2024-04-23-11-15-00 uavcloud-demo cmii-uav-platform 5.5.0 5.5.0-042301
|
||||||
2024-01-11-14-00-34 uavcloud-uavms uavms-lowaltitude-platform 5.1.0-011102 5.1.0-011103
|
2024-04-23-11-17-00 uavcloud-demo cmii-suav-platform-supervision 5.5.0 5.5.0-042301
|
||||||
2024-01-11-14-49-53 uavcloud-demo cmii-uav-waypoint 5.2.0-011101 5.2.0-011102
|
2024-04-23-16-28-06 uavcloud-dev cmii-suav-platform-supervision 5.2.0-test 5.5.0-042301
|
||||||
2024-01-11-15-32-28 uavcloud-demo cmii-uav-platform 5.2.0-011101 5.2.0-011102
|
2024-04-23-17-35-00 uavcloud-dev cmii-uav-platform-armypeople 5.5.0-validation 5.5.0-042301
|
||||||
2024-01-11-17-09-44 uavcloud-feature cmii-uav-platform 5.2.0-validation 5.2.0-011102
|
2024-04-23-17-36-00 uavcloud-demo cmii-uav-platform-armypeople 5.5.0-042201 5.5.0-042301
|
||||||
2024-01-11-17-35-47 uavcloud-uavms cmii-uav-surveillance 5.1.0-LAIN05A 5.1.0-011101
|
2024-04-24-12-00-00 uavcloud-demo cmii-uav-platform 5.5.0-042301 5.5.0-042401
|
||||||
2024-01-11-17-38-06 uavcloud-uavms uavms-lowaltitude-platform 5.1.0-011103 5.1.0-011102
|
2024-04-24-12-00-07 uavcloud-demo cmii-uav-airspace 5.5.0-042202 5.5.0-042401
|
||||||
2024-01-11-17-49-09 uavcloud-uavms uavms-lowaltitude-platform 5.1.0-011102 5.1.0-011104
|
2024-04-24-12-01-47 uavcloud-demo cmii-uav-industrial-portfolio 5.5.0-042201 5.5.0-042401
|
||||||
2024-01-12-10-38-30 uavcloud-uavms uavms-lowaltitude-platform 5.1.0-011105 5.2.0-011201
|
2024-04-24-12-03-14 uavcloud-demo cmii-uav-surveillance 5.5.0 5.5.0-042401
|
||||||
2024-01-12-12-09-59 uavcloud-uavms uavms-lowaltitude-platform 5.2.0-011201 5.2.0-011202
|
2024-04-24-17-30-00 uavcloud-demo cmii-uav-platform 5.5.0-042401 5.5.0-042402
|
||||||
2024-01-12-17-13-32 uavcloud-test cmii-suav-supervision 5.2.0-011001 5.2.0-011201
|
2024-04-24-17-30-07 uavcloud-demo cmii-uav-cloud-live 5.5.0 5.5.0-042401
|
||||||
2024-01-12-17-22-47 uavcloud-demo cmii-uav-platform 5.2.0-011102 5.2.0-011201
|
2024-04-24-17-31-51 uavcloud-demo cmii-uav-mission 5.5.0 5.5.0-042401
|
||||||
2024-01-15-11-56-33 uavcloud-test cmii-suav-supervision 5.2.0-011201 5.2.0-011501
|
2024-04-25-09-36-00 uavcloud-demo cmii-uav-platform 5.5.0-042402 5.5.0-042501
|
||||||
2024-01-16-10-22-02 uavcloud-test cmii-suav-supervision 5.2.0-011501 5.2.0-011601
|
2024-04-25-09-37-12 uavcloud-demo cmii-uav-industrial-portfolio 5.5.0-042401 5.5.0-042501
|
||||||
2024-01-16-11-40-31 uavcloud-uavms uavms-lowaltitude-platform 5.2.0-011202 5.2.0-snapshot
|
2024-04-25-17-42-00 uavcloud-demo cmii-uav-platform 5.5.0-042501 5.5.0-042503
|
||||||
2024-01-16-11-58-30 uavcloud-test cmii-suav-supervision 5.2.0-011601 5.2.0-011602
|
2024-04-25-17-42-06 uavcloud-demo cmii-uav-platform-splice 5.5.0 5.5.0-042501
|
||||||
2024-01-16-13-55-32 uavcloud-test cmii-suav-supervision 5.2.0-011602 5.2.0-011603
|
2024-04-25-17-45-00 uavcloud-demo cmii-uav-data-post-process 5.5.0 5.5.0-042501
|
||||||
2024-01-16-14-51-05 uavcloud-test cmii-suav-supervision 5.2.0-011603 5.2.0-011604
|
2024-04-26-17-55-00 uavcloud-demo cmii-uav-platform-splice 5.5.0-042501 5.5.0-042601
|
||||||
2024-01-17-16-13-39 uavcloud-test cmii-suav-supervision 5.2.0-011604 5.2.0-0117
|
2024-04-28-12-03-00 uavcloud-demo cmii-uav-platform-cms-portal 5.5.0 5.5.0-042801
|
||||||
2024-01-19-14-17-03 uavcloud-test cmii-suav-supervision 5.2.0-0117 5.2.0-011901
|
2024-04-28-12-03-05 uavcloud-demo cmii-uav-platform 5.5.0-042503 5.5.0-042801
|
||||||
2024-02-23-09-31-21 uavcloud-demo cmii-uav-device 5.4.0 5.4.0-26906
|
2024-04-28-12-03-10 uavcloud-demo cmii-uav-platform-oms 5.5.0 5.5.0-042801
|
||||||
2024-02-23-10-55-14 uavcloud-demo cmii-uav-device 5.4.0-26906 5.4.0-26906-01
|
2024-04-28-12-03-13 uavcloud-demo cmii-uav-user 5.5.0 5.5.0-042801
|
||||||
2024-02-23-14-32-05 uavcloud-devflight cmii-uav-device 5.2.0-validation 5.4.0-26906-01
|
2024-04-29-11-25-00 uavcloud-demo cmii-uav-platform 5.5.0-042801 5.5.0-042901
|
||||||
2024-02-28-17-09-55 uavcloud-demo cmii-uav-device 5.4.0 5.4.0-26905
|
2024-04-29-12-08-01 uavcloud-demo cmii-uav-mqtthandler 5.5.0 5.5.0-042901
|
||||||
2024-03-04-17-33-02 uavcloud-demo cmii-uav-platform 5.4.0-25263 5.4.0-hotfix
|
2024-04-29-12-13-03 uavcloud-demo cmii-uav-mission 5.5.0-042401 5.5.0-042901
|
||||||
2024-03-08-12-02-18 zyga cmii-uav-oauth 8033/cmii/cmii-uav-oauth5.4.0
|
2024-04-29-12-14-37 uavcloud-demo cmii-uav-surveillance 5.5.0-042401 5.5.0-042901
|
||||||
2024-03-08-12-02-19 zyga cmii-uav-user 8033/cmii/cmii-uav-user5.4.0
|
2024-04-29-12-14-38 uavcloud-demo cmii-uav-mqtthandler 5.5.0-042901 5.5.0
|
||||||
2024-03-08-12-02-21 zyga cmii-uav-cms 8033/cmii/cmii-uav-cms5.3.0
|
|
||||||
2024-03-08-12-02-22 zyga cmii-uav-industrial-portfolio 8033/cmii/cmii-uav-industrial-portfolio5.4.0-27348-1
|
|
||||||
2024-03-08-12-02-23 zyga cmii-uav-surveillance 8033/cmii/cmii-uav-surveillance5.4.0-25916
|
|
||||||
2024-03-08-12-02-24 zyga cmii-uav-mission 8033/cmii/cmii-uav-mission5.4.0-26462-0307
|
|
||||||
2024-03-08-12-02-26 zyga cmii-admin-gateway 8033/cmii/cmii-admin-gateway5.4.0
|
|
||||||
2024-03-08-12-02-27 zyga cmii-uav-alarm 8033/cmii/cmii-uav-alarm5.4.0
|
|
||||||
2024-03-08-12-02-28 zyga cmii-uav-emergency 8033/cmii/cmii-uav-emergency5.3.0
|
|
||||||
2024-03-08-12-02-30 zyga cmii-uav-material-warehouse 8033/cmii/cmii-uav-material-warehouse5.4.0
|
|
||||||
2024-03-08-12-02-31 zyga cmii-uav-airspace 8033/cmii/cmii-uav-airspace5.4.0
|
|
||||||
2024-03-08-12-02-33 zyga cmii-uav-brain 8033/cmii/cmii-uav-brain5.4.0
|
|
||||||
2024-03-08-12-02-34 zyga cmii-uav-process 8033/cmii/cmii-uav-process5.4.0
|
|
||||||
2024-03-08-12-02-36 zyga cmii-uav-notice 8033/cmii/cmii-uav-notice5.4.0
|
|
||||||
2024-03-08-12-02-37 zyga cmii-uav-waypoint 8033/cmii/cmii-uav-waypoint5.4.0-26768
|
|
||||||
2024-03-08-12-02-38 zyga cmii-uav-autowaypoint 8033/cmii/cmii-uav-autowaypoint4.1.6-cm
|
|
||||||
2024-03-08-12-02-40 zyga cmii-uav-data-post-process 8033/cmii/cmii-uav-data-post-process5.4.0
|
|
||||||
2024-03-08-12-02-41 zyga cmii-admin-data 8033/cmii/cmii-admin-data5.4.0
|
|
||||||
2024-03-08-12-02-42 zyga cmii-uav-cloud-live 8033/cmii/cmii-uav-cloud-live5.4.0
|
|
||||||
2024-03-08-12-02-43 zyga cmii-uav-gateway 8033/cmii/cmii-uav-gateway5.4.0
|
|
||||||
2024-03-08-12-02-45 zyga cmii-uav-logger 8033/cmii/cmii-uav-logger5.4.0
|
|
||||||
2024-03-08-12-02-46 zyga cmii-uav-mqtthandler 8033/cmii/cmii-uav-mqtthandler5.4.0-25916
|
|
||||||
2024-03-08-12-02-47 zyga cmii-admin-user 8033/cmii/cmii-admin-user5.4.0
|
|
||||||
2024-03-08-12-02-54 zyga cmii-suav-supervision 8033/cmii/cmii-suav-supervision5.2.0
|
|
||||||
2024-03-08-12-02-55 zyga cmii-uav-developer 8033/cmii/cmii-uav-developer5.4.0
|
|
||||||
2024-03-08-12-02-57 zyga cmii-uav-integration 8033/cmii/cmii-uav-integration5.4.0-25916
|
|
||||||
2024-03-08-12-02-58 zyga cmii-open-gateway 8033/cmii/cmii-open-gateway5.4.0
|
|
||||||
2024-03-08-12-02-59 zyga cmii-uav-device 8033/cmii/cmii-uav-device5.4.0-25916
|
|
||||||
2024-03-08-14-06-05 zyga cmii-uav-cloud-live 8033/cmii/cmii-uav-cloud-live5.4.0
|
|
||||||
2024-03-08-14-06-07 zyga cmii-uav-mqtthandler 8033/cmii/cmii-uav-mqtthandler5.4.0-25916
|
|
||||||
2024-03-08-14-11-26 zyga cmii-uav-industrial-portfolio 8033/cmii/cmii-uav-industrial-portfolio5.4.0-27348-1
|
|
||||||
2024-03-08-14-11-29 zyga cmii-open-gateway 8033/cmii/cmii-open-gateway5.4.0
|
|
||||||
2024-03-08-14-11-31 zyga cmii-uav-developer 8033/cmii/cmii-uav-developer5.4.0
|
|
||||||
2024-03-08-14-11-33 zyga cmii-admin-user 8033/cmii/cmii-admin-user5.4.0
|
|
||||||
2024-03-08-14-11-35 zyga cmii-uav-mqtthandler 8033/cmii/cmii-uav-mqtthandler5.4.0-25916
|
|
||||||
2024-03-08-14-11-37 zyga cmii-uav-user 8033/cmii/cmii-uav-user5.4.0
|
|
||||||
2024-03-08-14-11-40 zyga cmii-uav-airspace 8033/cmii/cmii-uav-airspace5.4.0
|
|
||||||
2024-03-08-14-11-42 zyga cmii-uav-logger 8033/cmii/cmii-uav-logger5.4.0
|
|
||||||
2024-03-08-14-11-44 zyga cmii-uav-process 8033/cmii/cmii-uav-process5.4.0
|
|
||||||
2024-03-08-14-11-48 zyga cmii-uav-notice 8033/cmii/cmii-uav-notice5.4.0
|
|
||||||
2024-03-08-14-11-55 zyga cmii-uav-surveillance 8033/cmii/cmii-uav-surveillance5.4.0-25916
|
|
||||||
2024-03-08-14-12-04 zyga cmii-uav-waypoint 8033/cmii/cmii-uav-waypoint5.4.0-26768
|
|
||||||
2024-03-08-14-12-13 zyga cmii-uav-brain 8033/cmii/cmii-uav-brain5.4.0
|
|
||||||
2024-03-08-14-12-20 zyga cmii-uav-cms 8033/cmii/cmii-uav-cms5.3.0
|
|
||||||
2024-03-08-14-12-22 zyga cmii-uav-material-warehouse 8033/cmii/cmii-uav-material-warehouse5.4.0
|
|
||||||
2024-03-08-14-12-24 zyga cmii-admin-gateway 8033/cmii/cmii-admin-gateway5.4.0
|
|
||||||
2024-03-08-14-12-26 zyga cmii-uav-emergency 8033/cmii/cmii-uav-emergency5.3.0
|
|
||||||
2024-03-08-14-12-28 zyga cmii-uav-gateway 8033/cmii/cmii-uav-gateway5.4.0
|
|
||||||
2024-03-08-14-12-31 zyga cmii-uav-integration 8033/cmii/cmii-uav-integration5.4.0-25916
|
|
||||||
2024-03-08-14-12-37 zyga cmii-admin-data 8033/cmii/cmii-admin-data5.4.0
|
|
||||||
2024-03-08-14-12-40 zyga cmii-suav-supervision 8033/cmii/cmii-suav-supervision5.2.0
|
|
||||||
2024-03-08-14-12-42 zyga cmii-uav-autowaypoint 8033/cmii/cmii-uav-autowaypoint4.1.6-cm
|
|
||||||
2024-03-08-14-12-44 zyga cmii-uav-cloud-live 8033/cmii/cmii-uav-cloud-live5.4.0
|
|
||||||
2024-03-08-14-12-46 zyga cmii-uav-mission 8033/cmii/cmii-uav-mission5.4.0-26462-0307
|
|
||||||
2024-03-08-14-12-48 zyga cmii-uav-oauth 8033/cmii/cmii-uav-oauth5.4.0
|
|
||||||
2024-03-08-14-12-50 zyga cmii-uav-alarm 8033/cmii/cmii-uav-alarm5.4.0
|
|
||||||
2024-03-08-14-12-53 zyga cmii-uav-data-post-process 8033/cmii/cmii-uav-data-post-process5.4.0
|
|
||||||
2024-03-08-14-12-55 zyga cmii-uav-device 8033/cmii/cmii-uav-device5.4.0-25916
|
|
||||||
2024-03-08-14-12-57 zyga cmii-uav-platform-cms-portal 8033/cmii/cmii-uav-platform-cms-portal5.4.0
|
|
||||||
2024-03-08-14-13-01 zyga cmii-uav-platform-detection 8033/cmii/cmii-uav-platform-detection5.4.0
|
|
||||||
2024-03-08-14-13-15 zyga cmii-uav-platform-emergency-rescue 8033/cmii/cmii-uav-platform-emergency-rescue5.2.0
|
|
||||||
2024-03-08-14-13-19 zyga cmii-uav-platform-media 8033/cmii/cmii-uav-platform-media5.4.0
|
|
||||||
2024-03-08-14-13-32 zyga cmii-uav-platform-open 8033/cmii/cmii-uav-platform-open5.4.0
|
|
||||||
2024-03-08-14-13-37 zyga cmii-uav-platform-splice 8033/cmii/cmii-uav-platform-splice5.4.0
|
|
||||||
2024-03-08-14-13-50 zyga cmii-uav-platform 8033/cmii/cmii-uav-platform5.4.0-25263
|
|
||||||
2024-03-08-14-13-54 zyga cmii-uav-platform-ai-brain 8033/cmii/cmii-uav-platform-ai-brain5.4.0
|
|
||||||
2024-03-08-14-14-08 zyga cmii-uav-platform-armypeople 8033/cmii/cmii-uav-platform-armypeople5.4.0
|
|
||||||
2024-03-08-14-14-12 zyga cmii-uav-platform-oms 8033/cmii/cmii-uav-platform-oms5.4.0
|
|
||||||
2024-03-08-14-14-26 zyga cmii-uav-platform-base 8033/cmii/cmii-uav-platform-base5.4.0
|
|
||||||
2024-03-08-14-14-30 zyga cmii-uav-platform-mws 8033/cmii/cmii-uav-platform-mws5.4.0
|
|
||||||
2024-03-08-14-14-44 zyga cmii-uav-platform-visualization 8033/cmii/cmii-uav-platform-visualization5.2.0
|
|
||||||
2024-03-08-14-14-48 zyga cmii-suav-platform-supervision 8033/cmii/cmii-suav-platform-supervision5.4.0
|
|
||||||
2024-03-08-14-15-01 zyga cmii-uav-platform-logistics 8033/cmii/cmii-uav-platform-logistics5.4.0
|
|
||||||
2024-03-08-14-15-06 zyga cmii-uav-platform-securityh5 8033/cmii/cmii-uav-platform-securityh55.4.0
|
|
||||||
2024-03-08-14-15-19 zyga cmii-suav-platform-supervisionh5 8033/cmii/cmii-suav-platform-supervisionh55.4.0
|
|
||||||
2024-03-08-14-15-23 zyga cmii-uav-platform-security 8033/cmii/cmii-uav-platform-security4.1.6
|
|
||||||
2024-03-08-14-15-37 zyga cmii-uav-platform-seniclive 8033/cmii/cmii-uav-platform-seniclive5.2.0
|
|
||||||
2024-03-08-14-15-41 zyga cmii-uav-platform-share 8033/cmii/cmii-uav-platform-share5.4.0
|
|
||||||
2024-03-08-14-15-55 zyga cmii-uav-platform-multiterminal 8033/cmii/cmii-uav-platform-multiterminal5.4.0
|
|
||||||
2024-03-08-15-16-14 uavcloud-demo cmii-uav-platform 5.4.0-25263 5.4.0
|
|
||||||
2024-03-11-11-20-15 zyga cmii-uav-surveillance 5.4.0 5.4.0-leaflet
|
|
||||||
2024-03-11-15-42-15 uavcloud-demo cmii-uav-platform 5.4.0 5.4.0-25263-0311
|
|
||||||
2024-03-19-17-37-53 uavcloud-demo cmii-uav-tower 5.4.0 5.4.0-0319
|
|
||||||
2024-03-19-17-39-21 uavcloud-demo cmii-uav-airspace 5.4.0 5.4.0-0319
|
|
||||||
2024-03-20-09-11-35 uavcloud-demo cmii-uav-mqtthandler 5.4.0-25916-1 5.4.0-25916-032001
|
|
||||||
2024-03-20-09-12-29 uavcloud-demo cmii-uav-industrial-portfolio 5.4.0-27348-2 5.4.0-27348-032001
|
|
||||||
2024-03-20-09-14-23 uavcloud-demo cmii-uav-platform 5.4.0-031901 5.4.0-25263-ai-032001
|
|
||||||
2024-03-20-09-21-51 uavcloud-demo cmii-uav-platform 5.4.0-25263-ai-032001 5.4.0-031901
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
2024-04-18-17-20-00 uavcloud-demo cmii-uav-integration 5.5.0 5.5.0-0418
|
|
||||||
2024-04-19-09-30-00 uavcloud-demo cmii-uav-platform-open 5.5.0 5.5.0-0419
|
|
||||||
2024-04-22-09-18-00 uavcloud-demo cmii-uav-airspace 5.5.0 5.5.0-0422
|
|
||||||
2024-04-22-14-20-00 uavcloud-demo cmii-uav-airspace 5.5.0-0422 5.5.0-042201
|
|
||||||
2024-04-22-16-57-00 uavcloud-demo cmii-uav-airspace 5.5.0-042201 5.5.0-042202
|
|
||||||
2024-04-23-09-27-00 uavcloud-demo cmii-uav-device 5.5.0 5.5.0-042301
|
|
||||||
2024-04-23-11-15-00 uavcloud-demo cmii-uav-platform 5.5.0 5.5.0-042301
|
|
||||||
2024-04-23-11-17-00 uavcloud-demo cmii-suav-platform-supervision 5.5.0 5.5.0-042301
|
|
||||||
2024-04-23-16-28-06 uavcloud-dev cmii-suav-platform-supervision 5.2.0-test 5.5.0-042301
|
|
||||||
2024-04-23-17-35-00 uavcloud-dev cmii-uav-platform-armypeople 5.5.0-validation 5.5.0-042301
|
|
||||||
2024-04-23-17-36-00 uavcloud-demo cmii-uav-platform-armypeople 5.5.0-042201 5.5.0-042301
|
|
||||||
2024-04-24-12-00-00 uavcloud-demo cmii-uav-platform 5.5.0-042301 5.5.0-042401
|
|
||||||
2024-04-24-12-00-07 uavcloud-demo cmii-uav-airspace 5.5.0-042202 5.5.0-042401
|
|
||||||
2024-04-24-12-01-47 uavcloud-demo cmii-uav-industrial-portfolio 5.5.0-042201 5.5.0-042401
|
|
||||||
2024-04-24-12-03-14 uavcloud-demo cmii-uav-surveillance 5.5.0 5.5.0-042401
|
|
||||||
2024-04-24-17-30-00 uavcloud-demo cmii-uav-platform 5.5.0-042401 5.5.0-042402
|
|
||||||
2024-04-24-17-30-07 uavcloud-demo cmii-uav-cloud-live 5.5.0 5.5.0-042401
|
|
||||||
2024-04-24-17-31-51 uavcloud-demo cmii-uav-mission 5.5.0 5.5.0-042401
|
|
||||||
2024-04-25-09-36-00 uavcloud-demo cmii-uav-platform 5.5.0-042402 5.5.0-042501
|
|
||||||
2024-04-25-09-37-12 uavcloud-demo cmii-uav-industrial-portfolio 5.5.0-042401 5.5.0-042501
|
|
||||||
2024-04-25-17-42-00 uavcloud-demo cmii-uav-platform 5.5.0-042501 5.5.0-042503
|
|
||||||
2024-04-25-17-42-06 uavcloud-demo cmii-uav-platform-splice 5.5.0 5.5.0-042501
|
|
||||||
2024-04-25-17-45-00 uavcloud-demo cmii-uav-data-post-process 5.5.0 5.5.0-042501
|
|
||||||
2024-04-26-17-55-00 uavcloud-demo cmii-uav-platform-splice 5.5.0-042501 5.5.0-042601
|
|
||||||
2024-04-28-12-03-00 uavcloud-demo cmii-uav-platform-cms-portal 5.5.0 5.5.0-042801
|
|
||||||
2024-04-28-12-03-05 uavcloud-demo cmii-uav-platform 5.5.0-042503 5.5.0-042801
|
|
||||||
2024-04-28-12-03-10 uavcloud-demo cmii-uav-platform-oms 5.5.0 5.5.0-042801
|
|
||||||
2024-04-28-12-03-13 uavcloud-demo cmii-uav-user 5.5.0 5.5.0-042801
|
|
||||||
74
message_pusher/cmii/ImageSyncMessage.go
Normal file
74
message_pusher/cmii/ImageSyncMessage.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package cmii
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io.wdd.message_pusher/pusher"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImageSyncMessage struct {
|
||||||
|
ImageFullName string `json:"imageFullName"`
|
||||||
|
ProjectName string `json:"projectName"`
|
||||||
|
ProjectNameSpace string `json:"projectNameSpace"`
|
||||||
|
ProjectMasterIP string `json:"projectMasterIP"`
|
||||||
|
ProjectMasterTopicName string `json:"projectMasterTopicName"`
|
||||||
|
InnerWorkTopicName string `json:"innerWorkTopicName"`
|
||||||
|
CurrentProcedure string `json:"currentProcedure"`
|
||||||
|
IsSyncFinished bool `json:"isSyncFinished"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageSyncTemplate = `
|
||||||
|
{{if .IsSyncFinished}}
|
||||||
|
镜像更新状态: 成功😍
|
||||||
|
{{- else }}
|
||||||
|
镜像更新状态: 失败👿👿👿
|
||||||
|
{{- end}}
|
||||||
|
当前步骤: {{.CurrentProcedure}}
|
||||||
|
更新镜像: {{.ImageFullName}}
|
||||||
|
项目名称: {{.ProjectName}}
|
||||||
|
项目空间: {{.ProjectNameSpace}}
|
||||||
|
项目MasterIP: {{.ProjectMasterIP}}
|
||||||
|
项目Master名称: {{.ProjectMasterTopicName}}
|
||||||
|
中转节点名称: {{.InnerWorkTopicName}}
|
||||||
|
`
|
||||||
|
|
||||||
|
const ImageSyncTopicName = "imageSync"
|
||||||
|
|
||||||
|
var ImageSyncPushOptions = []pusher.PublishOption{
|
||||||
|
pusher.WithTitle("镜像同步更新"),
|
||||||
|
pusher.WithPriority("3"),
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *ImageSyncMessage) ParseTemplate() bytes.Buffer {
|
||||||
|
// 解析模板
|
||||||
|
tmpl, err := template.New("imageSyncTemplate").Parse(imageSyncTemplate)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用数据并打印结果
|
||||||
|
var result bytes.Buffer
|
||||||
|
err = tmpl.Execute(&result, d)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublishMessage 使用默认的Client 发布更新的消息
|
||||||
|
func (d *ImageSyncMessage) PublishMessage() *pusher.Message {
|
||||||
|
|
||||||
|
parseTemplate := d.ParseTemplate()
|
||||||
|
|
||||||
|
pusher.DefaultPusherClient.ChangeTopicName(ImageSyncTopicName)
|
||||||
|
|
||||||
|
result, err := pusher.DefaultPusherClient.PublishDefault(parseTemplate, ImageSyncPushOptions)
|
||||||
|
if err != nil {
|
||||||
|
log.ErrorF("[ImageSyncMessage] - message push error ! %s", err.Error())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ func main() {
|
|||||||
{
|
{
|
||||||
router.CMIIRouter(engine)
|
router.CMIIRouter(engine)
|
||||||
router.OctopusRouter(engine)
|
router.OctopusRouter(engine)
|
||||||
|
router.ImageSyncRouter(engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ func NewDefaultClient() *Client {
|
|||||||
return New(defaultConfig)
|
return New(defaultConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) ChangeTopicName(topicName string) {
|
||||||
|
c.config.DefaultTopic = topicName
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) PublishDefault(message bytes.Buffer, options []PublishOption) (*Message, error) {
|
func (c *Client) PublishDefault(message bytes.Buffer, options []PublishOption) (*Message, error) {
|
||||||
if c.config.DefaultTopic == "" {
|
if c.config.DefaultTopic == "" {
|
||||||
return nil, errors.New("[PublishDefault] - topic empty")
|
return nil, errors.New("[PublishDefault] - topic empty")
|
||||||
@@ -135,17 +139,17 @@ func (c *Client) expandTopicURL(topic string) (string, error) {
|
|||||||
if !topicRegex.MatchString(topic) {
|
if !topicRegex.MatchString(topic) {
|
||||||
return "", fmt.Errorf("invalid topic name: %s", topic)
|
return "", fmt.Errorf("invalid topic name: %s", topic)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/%s", c.config.DefaultHost, topic), nil
|
return fmt.Sprintf("%s/%s", c.config.Host, topic), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) parseConfigToOption(options []PublishOption) []PublishOption {
|
func (c *Client) parseConfigToOption(options []PublishOption) []PublishOption {
|
||||||
config := c.config
|
config := c.config
|
||||||
|
|
||||||
if config.DefaultToken != "" {
|
if config.Token != "" {
|
||||||
options = append(options, WithBearerAuth(config.DefaultToken))
|
options = append(options, WithBearerAuth(config.Token))
|
||||||
} else if config.DefaultUser != "" {
|
} else if config.User != "" {
|
||||||
if *config.DefaultPassword != "" {
|
if *config.Password != "" {
|
||||||
options = append(options, WithBasicAuth(config.DefaultUser, *config.DefaultPassword))
|
options = append(options, WithBasicAuth(config.User, *config.Password))
|
||||||
} else {
|
} else {
|
||||||
log.ErrorF("[parseConfigToOption] - default password is empty!")
|
log.ErrorF("[parseConfigToOption] - default password is empty!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ const (
|
|||||||
|
|
||||||
// Config is the config struct for a Client
|
// Config is the config struct for a Client
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DefaultHost string `yaml:"default-host"`
|
Host string `yaml:"default-host"`
|
||||||
DefaultUser string `yaml:"default-user"`
|
User string `yaml:"default-user"`
|
||||||
DefaultPassword *string `yaml:"default-password"`
|
Password *string `yaml:"default-password"`
|
||||||
DefaultToken string `yaml:"default-token"`
|
Token string `yaml:"default-token"`
|
||||||
DefaultCommand string `yaml:"default-command"`
|
DefaultCommand string `yaml:"default-command"`
|
||||||
DefaultTopic string `yaml:"default-topic"`
|
DefaultTopic string `yaml:"default-topic"`
|
||||||
Subscribe []Subscribe `yaml:"subscribe"`
|
Subscribe []Subscribe `yaml:"subscribe"`
|
||||||
@@ -38,10 +38,10 @@ type Subscribe struct {
|
|||||||
// NewDefaultConfig creates a new Config struct for a Client
|
// NewDefaultConfig creates a new Config struct for a Client
|
||||||
func NewDefaultConfig() *Config {
|
func NewDefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
DefaultHost: DefaultBaseURL,
|
Host: DefaultBaseURL,
|
||||||
DefaultUser: "",
|
User: "",
|
||||||
DefaultPassword: nil,
|
Password: nil,
|
||||||
DefaultToken: DefaultBaseToken,
|
Token: DefaultBaseToken,
|
||||||
DefaultTopic: DefaultTopic,
|
DefaultTopic: DefaultTopic,
|
||||||
DefaultCommand: "",
|
DefaultCommand: "",
|
||||||
Subscribe: nil,
|
Subscribe: nil,
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ package router
|
|||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io.wdd.message_pusher/cmii"
|
"io.wdd.message_pusher/cmii"
|
||||||
|
"io.wdd.message_pusher/pusher"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const CmiiUpdateTopicName = "cmii"
|
||||||
|
|
||||||
func CMIIRouter(r *gin.Engine) {
|
func CMIIRouter(r *gin.Engine) {
|
||||||
|
|
||||||
cmiiGroup := r.Group("/cmii")
|
cmiiGroup := r.Group("/cmii")
|
||||||
@@ -37,6 +40,8 @@ func CmiiUpdate(c *gin.Context) {
|
|||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pusher.DefaultPusherClient.ChangeTopicName(CmiiUpdateTopicName)
|
||||||
// 处理请求
|
// 处理请求
|
||||||
upgradeMessage := messageBody.DefaultPushUpgradeMessage()
|
upgradeMessage := messageBody.DefaultPushUpgradeMessage()
|
||||||
|
|
||||||
|
|||||||
38
message_pusher/router/ImageSyncRouter.go
Normal file
38
message_pusher/router/ImageSyncRouter.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io.wdd.message_pusher/cmii"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ImageSyncRouter(r *gin.Engine) {
|
||||||
|
octopusGroup := r.Group("/image")
|
||||||
|
{
|
||||||
|
octopusGroup.POST("/sync", ImageSync)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSync godoc
|
||||||
|
// @Summary 镜像同步消息
|
||||||
|
// @Schemes
|
||||||
|
// @Description response to cmii update notification
|
||||||
|
// @Tags ImageSync
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body cmii.ImageSyncMessage true "请求体"
|
||||||
|
// @Success 200 {object} pusher.Message
|
||||||
|
// @Router /image/sync [post]
|
||||||
|
func ImageSync(c *gin.Context) {
|
||||||
|
// 获取请求中的参数
|
||||||
|
var imageSyncMessage cmii.ImageSyncMessage
|
||||||
|
if err := c.ShouldBindJSON(&imageSyncMessage); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 处理请求
|
||||||
|
upgradeMessage := imageSyncMessage.PublishMessage()
|
||||||
|
|
||||||
|
// *pusher.Message
|
||||||
|
c.JSON(http.StatusOK, upgradeMessage)
|
||||||
|
}
|
||||||
@@ -40,7 +40,17 @@ public enum ImageFunctionEnum {
|
|||||||
UPDATE_IMAGE_TAG(
|
UPDATE_IMAGE_TAG(
|
||||||
"UPDATE_IMAGE_TAG",
|
"UPDATE_IMAGE_TAG",
|
||||||
"关闭防火墙"
|
"关闭防火墙"
|
||||||
|
),
|
||||||
|
|
||||||
|
FINISHED(
|
||||||
|
"FINISHED",
|
||||||
|
"同步更新完成"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 函数名
|
||||||
|
*/
|
||||||
String funcName;
|
String funcName;
|
||||||
|
|
||||||
String desc;
|
String desc;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.wdd.func.auto.beans;
|
package io.wdd.func.auto.beans;
|
||||||
|
|
||||||
|
import io.wdd.pusher.beans.ImageSyncMessage;
|
||||||
import io.wdd.server.beans.po.ProjectInfoPO;
|
import io.wdd.server.beans.po.ProjectInfoPO;
|
||||||
import io.wdd.server.beans.po.ServerInfoPO;
|
import io.wdd.server.beans.po.ServerInfoPO;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -32,4 +33,7 @@ public class ImageSyncContext {
|
|||||||
// 我方的 机器 默认值为 192.168.35.71
|
// 我方的 机器 默认值为 192.168.35.71
|
||||||
String innerWorkerAgentName;
|
String innerWorkerAgentName;
|
||||||
|
|
||||||
|
// 消息同步结构体
|
||||||
|
ImageSyncMessage imageSyncMessage;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package io.wdd.func.auto.service;
|
package io.wdd.func.auto.service;
|
||||||
|
|
||||||
import io.wdd.func.auto.beans.ImageSyncContext;
|
import io.wdd.func.auto.beans.ImageSyncContext;
|
||||||
|
import io.wdd.pusher.MessagePusher;
|
||||||
|
import io.wdd.pusher.beans.ImageSyncMessage;
|
||||||
|
import io.wdd.pusher.beans.NtfyReceiveMessage;
|
||||||
|
import io.wdd.pusher.beans.PushMessageType;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -22,6 +26,9 @@ public class ImageFuncScheduler {
|
|||||||
@Resource
|
@Resource
|
||||||
FuncService funcService;
|
FuncService funcService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
MessagePusher messagePusher;
|
||||||
|
|
||||||
public boolean runProcedure(ImageSyncContext imageSyncContext) {
|
public boolean runProcedure(ImageSyncContext imageSyncContext) {
|
||||||
|
|
||||||
// before run
|
// before run
|
||||||
@@ -55,16 +62,21 @@ public class ImageFuncScheduler {
|
|||||||
arrayList.add(imageSyncContext.getProjectInfoPO().getProjectNamespace());//namespace
|
arrayList.add(imageSyncContext.getProjectInfoPO().getProjectNamespace());//namespace
|
||||||
arrayList.add("");//targetImageFullName
|
arrayList.add("");//targetImageFullName
|
||||||
|
|
||||||
|
|
||||||
imageSyncContext.setImageSyncFuncArgs(arrayList);
|
imageSyncContext.setImageSyncFuncArgs(arrayList);
|
||||||
|
|
||||||
|
// 构建消息发送结构体
|
||||||
|
imageSyncContext.setImageSyncMessage(new ImageSyncMessage());
|
||||||
|
|
||||||
log.debug("beforeRunProcedure complete!");
|
log.debug("beforeRunProcedure complete!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void afterRunProcedure(ImageSyncContext imageSyncContext) {
|
private void afterRunProcedure(ImageSyncContext imageSyncContext) {
|
||||||
|
|
||||||
// message-pusher
|
// message-pusher
|
||||||
|
ImageSyncMessage imageSyncMessage = imageSyncContext.getImageSyncMessage();
|
||||||
|
NtfyReceiveMessage receiveMessage = messagePusher.Send(imageSyncMessage, PushMessageType.IMAGE_SYNC);
|
||||||
|
|
||||||
|
log.info("Image sync message push result => {}", receiveMessage.getRaw());
|
||||||
|
|
||||||
// 检查是否安装完成, 对安装环境进行判定
|
// 检查是否安装完成, 对安装环境进行判定
|
||||||
log.debug("afterRunProcedure complete!");
|
log.debug("afterRunProcedure complete!");
|
||||||
@@ -98,6 +110,7 @@ public class ImageFuncScheduler {
|
|||||||
|
|
||||||
log.info("prepare to update {} {} \n{}", imageSyncContext.getProjectInfoPO().getProjectNamespace(), imageSyncContext.getProjectMasterNode().getServerIpInV4(), realFullNameList);
|
log.info("prepare to update {} {} \n{}", imageSyncContext.getProjectInfoPO().getProjectNamespace(), imageSyncContext.getProjectMasterNode().getServerIpInV4(), realFullNameList);
|
||||||
|
|
||||||
|
|
||||||
String innerWorkerAgentName = imageSyncContext.getInnerWorkerAgentName();
|
String innerWorkerAgentName = imageSyncContext.getInnerWorkerAgentName();
|
||||||
Assert.notNull(innerWorkerAgentName, "inner worker agent name cant not be null !");
|
Assert.notNull(innerWorkerAgentName, "inner worker agent name cant not be null !");
|
||||||
|
|
||||||
@@ -105,17 +118,30 @@ public class ImageFuncScheduler {
|
|||||||
|
|
||||||
String outsideAgentTopicName = imageSyncContext.getProjectMasterNode().getTopicName();
|
String outsideAgentTopicName = imageSyncContext.getProjectMasterNode().getTopicName();
|
||||||
|
|
||||||
|
// 设置消息体
|
||||||
|
ImageSyncMessage imageSyncMessage = imageSyncContext.getImageSyncMessage();
|
||||||
|
imageSyncMessage.setIsSyncFinished(Boolean.FALSE);
|
||||||
|
imageSyncMessage.setProjectNameSpace(imageSyncContext.getProjectInfoPO().getProjectNamespace());
|
||||||
|
imageSyncMessage.setProjectName(imageSyncContext.getProjectInfoPO().getProjectName());
|
||||||
|
imageSyncMessage.setInnerWorkTopicName(imageSyncContext.getInnerWorkerAgentName());
|
||||||
|
imageSyncMessage.setProjectMasterTopicName(imageSyncContext.getProjectMasterNode().getTopicName());
|
||||||
|
imageSyncMessage.setProjectMasterIP(imageSyncContext.getProjectMasterNode().getServerIpInV4());
|
||||||
|
|
||||||
//
|
//
|
||||||
List<String> resultLog;
|
List<String> resultLog;
|
||||||
for (String fullName : realFullNameList) {
|
for (String imageFullName : realFullNameList) {
|
||||||
|
imageSyncMessage.setImageFullName(imageFullName);
|
||||||
|
|
||||||
// innerWorkerAgent
|
// innerWorkerAgent
|
||||||
imageSyncFuncArgs.set(0, fullName);
|
imageSyncFuncArgs.set(0, imageFullName);
|
||||||
resultLog = funcService.callImageFuncService(innerWorkerAgentName, DOWNLOAD_DOCKER_IMAGE, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(innerWorkerAgentName, DOWNLOAD_DOCKER_IMAGE, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(DOWNLOAD_DOCKER_IMAGE.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultLog = funcService.callImageFuncService(innerWorkerAgentName, COMPRESS_IMAGE_TO_GZIP, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(innerWorkerAgentName, COMPRESS_IMAGE_TO_GZIP, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(COMPRESS_IMAGE_TO_GZIP.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String gzipFileName = resultLog.get(0);
|
String gzipFileName = resultLog.get(0);
|
||||||
@@ -123,32 +149,42 @@ public class ImageFuncScheduler {
|
|||||||
imageSyncFuncArgs.set(2, gzipFileName);
|
imageSyncFuncArgs.set(2, gzipFileName);
|
||||||
resultLog = funcService.callImageFuncService(innerWorkerAgentName, UPLOAD_GZIP_TO_OSS, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(innerWorkerAgentName, UPLOAD_GZIP_TO_OSS, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(UPLOAD_GZIP_TO_OSS.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Image Sync Half Complete ! Gzip file name => {}", gzipFileName);
|
log.info("Image Sync Half Complete ! Gzip file name => {}", gzipFileName);
|
||||||
if (imageSyncContext.getDownloadAndCompressOnly()) {
|
if (imageSyncContext.getDownloadAndCompressOnly()) {
|
||||||
log.info("Image Sync download only !");
|
log.info("Image Sync download only !");
|
||||||
|
imageSyncMessage.setCurrentProcedure(FINISHED.getFuncName());
|
||||||
|
imageSyncMessage.setIsSyncFinished(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// outside agent
|
// outside agent
|
||||||
resultLog = funcService.callImageFuncService(outsideAgentTopicName, DOWNLOAD_GZIP_IMAGE_FILE, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(outsideAgentTopicName, DOWNLOAD_GZIP_IMAGE_FILE, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(DOWNLOAD_GZIP_IMAGE_FILE.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultLog = funcService.callImageFuncService(outsideAgentTopicName, LOAD_DOCKER_IMAGE_FROM_GZIP, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(outsideAgentTopicName, LOAD_DOCKER_IMAGE_FROM_GZIP, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(LOAD_DOCKER_IMAGE_FROM_GZIP.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultLog = funcService.callImageFuncService(outsideAgentTopicName, PUSH_IMAGE_TO_TARGET_HARBOR, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(outsideAgentTopicName, PUSH_IMAGE_TO_TARGET_HARBOR, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(PUSH_IMAGE_TO_TARGET_HARBOR.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultLog = funcService.callImageFuncService(outsideAgentTopicName, UPDATE_IMAGE_TAG, imageSyncFuncArgs);
|
resultLog = funcService.callImageFuncService(outsideAgentTopicName, UPDATE_IMAGE_TAG, imageSyncFuncArgs);
|
||||||
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
if (!JudgeSyncBaseCommandResult(resultLog)) {
|
||||||
|
imageSyncMessage.setCurrentProcedure(UPDATE_IMAGE_TAG.getFuncName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageSyncMessage.setCurrentProcedure(FINISHED.getFuncName());
|
||||||
|
imageSyncMessage.setIsSyncFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
80
server/src/main/java/io/wdd/pusher/MessagePusher.java
Normal file
80
server/src/main/java/io/wdd/pusher/MessagePusher.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package io.wdd.pusher;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.wdd.pusher.beans.NtfyReceiveMessage;
|
||||||
|
import io.wdd.pusher.beans.PushMessageType;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class MessagePusher {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
@Value("${octopus.notify.pusher_url}")
|
||||||
|
String pushServerUrl;
|
||||||
|
|
||||||
|
public NtfyReceiveMessage Send(Object sendMessage, PushMessageType pushMessageType) {
|
||||||
|
// Create a RestTemplate instance
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
|
||||||
|
// Define the URL to send the request to
|
||||||
|
if (pushServerUrl.endsWith("/")) {
|
||||||
|
pushServerUrl.substring(0, pushServerUrl.length() - 1);
|
||||||
|
}
|
||||||
|
String url = pushServerUrl + pushMessageType.getUri();
|
||||||
|
|
||||||
|
// Define the JSON payload
|
||||||
|
String jsonPayload = "";
|
||||||
|
try {
|
||||||
|
jsonPayload = objectMapper.writeValueAsString(sendMessage);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a HttpHeaders instance to add authentication information
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.add("Authorization", "Bearer tk_zvdb67fwj1hrjivkq3ga9z7u63av5");
|
||||||
|
|
||||||
|
// Create a MultiValueMap to add additional headers
|
||||||
|
// MultiValueMap<String, String> additionalHeaders = new LinkedMultiValueMap<>();
|
||||||
|
// additionalHeaders.add("X-Custom-Header", "Custom-Value");
|
||||||
|
// headers.putAll(additionalHeaders);
|
||||||
|
|
||||||
|
// Send the POST request
|
||||||
|
ResponseEntity<String> response = restTemplate.postForEntity(url, jsonPayload, String.class, headers);
|
||||||
|
|
||||||
|
// Check the response status code
|
||||||
|
NtfyReceiveMessage ntfyReceiveMessage = null;
|
||||||
|
if (response.getStatusCode().is2xxSuccessful()) {
|
||||||
|
// Process the response body (JSON)
|
||||||
|
String responseBody = response.getBody();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ntfyReceiveMessage = objectMapper.readValue(responseBody, NtfyReceiveMessage.class);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// ...
|
||||||
|
} else {
|
||||||
|
// Handle the error response
|
||||||
|
// ...
|
||||||
|
|
||||||
|
log.error("Error sending message: {} with code: {}", response.getStatusCode(), jsonPayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ntfyReceiveMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
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,27 @@
|
|||||||
|
package io.wdd.pusher.beans;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
public class CmiiUpdateMessage {
|
||||||
|
|
||||||
|
@JsonProperty("Namespace")
|
||||||
|
private String namespace;
|
||||||
|
@JsonProperty("AppName")
|
||||||
|
private String appName;
|
||||||
|
@JsonProperty("FromTag")
|
||||||
|
private String fromTag;
|
||||||
|
@JsonProperty("ToTag")
|
||||||
|
private String toTag;
|
||||||
|
@JsonProperty("Replicas")
|
||||||
|
private String replicas;
|
||||||
|
@JsonProperty("DeployStatus")
|
||||||
|
private Boolean deployStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package io.wdd.pusher.beans;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
public class ImageSyncMessage {
|
||||||
|
|
||||||
|
private String imageFullName;
|
||||||
|
|
||||||
|
private String projectName;
|
||||||
|
|
||||||
|
private String projectNameSpace;
|
||||||
|
|
||||||
|
private String projectMasterIP;
|
||||||
|
|
||||||
|
private String projectMasterTopicName;
|
||||||
|
|
||||||
|
private String innerWorkTopicName;
|
||||||
|
|
||||||
|
private String currentProcedure;
|
||||||
|
|
||||||
|
private Boolean isSyncFinished;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package io.wdd.pusher.beans;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
public class NtfyReceiveMessage {
|
||||||
|
|
||||||
|
@JsonProperty("ID")
|
||||||
|
private String id;
|
||||||
|
@JsonProperty("Event")
|
||||||
|
private String event;
|
||||||
|
@JsonProperty("Time")
|
||||||
|
private Integer time;
|
||||||
|
@JsonProperty("Topic")
|
||||||
|
private String topic;
|
||||||
|
@JsonProperty("Message")
|
||||||
|
private String message;
|
||||||
|
@JsonProperty("Title")
|
||||||
|
private String title;
|
||||||
|
@JsonProperty("Priority")
|
||||||
|
private Integer priority;
|
||||||
|
@JsonProperty("Tags")
|
||||||
|
private Object tags;
|
||||||
|
@JsonProperty("Click")
|
||||||
|
private String click;
|
||||||
|
@JsonProperty("Icon")
|
||||||
|
private String icon;
|
||||||
|
@JsonProperty("Attachment")
|
||||||
|
private Object attachment;
|
||||||
|
@JsonProperty("TopicURL")
|
||||||
|
private String topicURL;
|
||||||
|
@JsonProperty("SubscriptionID")
|
||||||
|
private String subscriptionID;
|
||||||
|
@JsonProperty("Raw")
|
||||||
|
private String raw;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package io.wdd.pusher.beans;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
public class NtfySendMessage {
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
private String id;
|
||||||
|
@JsonProperty("time")
|
||||||
|
private Integer time;
|
||||||
|
@JsonProperty("expires")
|
||||||
|
private Integer expires;
|
||||||
|
@JsonProperty("event")
|
||||||
|
private String event;
|
||||||
|
@JsonProperty("topic")
|
||||||
|
private String topic;
|
||||||
|
@JsonProperty("priority")
|
||||||
|
private Integer priority;
|
||||||
|
@JsonProperty("tags")
|
||||||
|
private List<String> tags;
|
||||||
|
@JsonProperty("click")
|
||||||
|
private String click;
|
||||||
|
@JsonProperty("attachment")
|
||||||
|
private AttachmentDTO attachment;
|
||||||
|
@JsonProperty("title")
|
||||||
|
private String title;
|
||||||
|
@JsonProperty("message")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public static class AttachmentDTO {
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
@JsonProperty("type")
|
||||||
|
private String type;
|
||||||
|
@JsonProperty("size")
|
||||||
|
private Integer size;
|
||||||
|
@JsonProperty("expires")
|
||||||
|
private Integer expires;
|
||||||
|
@JsonProperty("url")
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package io.wdd.pusher.beans;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum PushMessageType {
|
||||||
|
|
||||||
|
|
||||||
|
CMII_UPDATE(
|
||||||
|
"/cmii/update",
|
||||||
|
"更新CMII应用的消息通知类型"
|
||||||
|
),
|
||||||
|
|
||||||
|
IMAGE_SYNC(
|
||||||
|
"/image/sync",
|
||||||
|
"更新镜像同步的消类型"
|
||||||
|
);
|
||||||
|
|
||||||
|
String uri;
|
||||||
|
|
||||||
|
String description;
|
||||||
|
|
||||||
|
PushMessageType(String uri, String description) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
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";
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package io.wdd.pusher.core.model;
|
|
||||||
|
|
||||||
|
|
||||||
public enum ClientType {
|
|
||||||
PUB, SUB, STREAM;
|
|
||||||
}
|
|
||||||
@@ -1,381 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package io.wdd.pusher.core.model;
|
|
||||||
|
|
||||||
|
|
||||||
public class PublishResponse {
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package io.wdd.pusher.core.stream;
|
|
||||||
|
|
||||||
public interface StreamingDataListener {
|
|
||||||
void onDataReceived(String data);
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "octopus.notify.pusher_url",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "Description for octopus.notify.pusher_url."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -93,6 +93,11 @@ mybatis-plus:
|
|||||||
# mapper-locations: classpath*:/real-mappers/**/*.xml
|
# mapper-locations: classpath*:/real-mappers/**/*.xml
|
||||||
|
|
||||||
octopus:
|
octopus:
|
||||||
|
notify:
|
||||||
|
# 消息通知的URL地址
|
||||||
|
pusher_url: http://192.168.35.71:8080
|
||||||
|
# 发送消息的密钥 不需要使用
|
||||||
|
access_token: tk_zvdb67fwj1hrjivkq3ga9z7u63av5
|
||||||
message:
|
message:
|
||||||
# agent boot up default common exchange
|
# agent boot up default common exchange
|
||||||
init_exchange: InitExchange
|
init_exchange: InitExchange
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
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-industrial-portfolio:5.4.0-cqly-042802"
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-platform:5.3.0-cqly-042901"
|
||||||
));
|
));
|
||||||
|
|
||||||
Boolean downloadAndCompressOnly = false;
|
Boolean downloadAndCompressOnly = false;
|
||||||
@@ -102,7 +102,7 @@ public class TestImageSyncScheduler {
|
|||||||
));
|
));
|
||||||
|
|
||||||
ArrayList<String> ImageFullNameList = new ArrayList<>(List.of(
|
ArrayList<String> ImageFullNameList = new ArrayList<>(List.of(
|
||||||
"harbor.cdcyy.com.cn/cmii/cmii-uav-industrial-portfolio:5.4.0-cqly-042801"
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-platform:5.3.0-cqly-042901"
|
||||||
));
|
));
|
||||||
|
|
||||||
Boolean downloadAndCompressOnly = true;
|
Boolean downloadAndCompressOnly = true;
|
||||||
|
|||||||
51
server/src/test/java/io/wdd/server/pusher/PusherTest.java
Normal file
51
server/src/test/java/io/wdd/server/pusher/PusherTest.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package io.wdd.server.pusher;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.wdd.pusher.MessagePusher;
|
||||||
|
import io.wdd.pusher.beans.*;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class PusherTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
MessagePusher messagePusher;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
NtfySendMessage ntfySendMessage = NtfySendMessage.builder()
|
||||||
|
.title("来自Java的测试内容")
|
||||||
|
.priority(1)
|
||||||
|
.message("Hello World")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
CmiiUpdateMessage build = CmiiUpdateMessage.builder().appName("cmii-uav-gateway").namespace("uavcloud-dev").fromTag("1.0.0").toTag("5.0.0").replicas("1").deployStatus(Boolean.TRUE).build();
|
||||||
|
|
||||||
|
System.out.println("ntfySendMessage = " + ntfySendMessage);
|
||||||
|
|
||||||
|
|
||||||
|
NtfyReceiveMessage ntfyReceiveMessage = messagePusher.Send(build, PushMessageType.CMII_UPDATE);
|
||||||
|
|
||||||
|
System.out.println("ntfyReceiveMessage = " + ntfyReceiveMessage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Test
|
||||||
|
public void testImageSyncMessage() {
|
||||||
|
|
||||||
|
ImageSyncMessage imageSyncMessage = new ImageSyncMessage();
|
||||||
|
|
||||||
|
String s = objectMapper.writeValueAsString(imageSyncMessage);
|
||||||
|
|
||||||
|
System.out.println("imageSyncMessage = " + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user