diff --git a/adaptors/司南GNSS_MySql库to安心云.go b/adaptors/司南GNSS_MySql库to安心云.go index e7034e5..2fbf5f0 100644 --- a/adaptors/司南GNSS_MySql库to安心云.go +++ b/adaptors/司南GNSS_MySql库to安心云.go @@ -5,9 +5,10 @@ import ( "fmt" "goInOut/consumers/SinoGnssMySQL" "strconv" + "time" ) -// Adaptor_SINOMYSQL_AXYMQTT 数据 转换 +// Adaptor_SINOMYSQL_AXYMQTT 数据 转换 江苏农村公路桥梁监测系统 type Adaptor_SINOMYSQL_AXYMQTT struct { } @@ -19,7 +20,7 @@ func (the Adaptor_SINOMYSQL_AXYMQTT) Transform(gnssDataList []SinoGnssMySQL.Gnss OnceDxFiles = append(OnceDxFiles, SinoGnssMySQL.DxFile{ Module: gnssData.StationName, Channel: 1, - Timespan: gnssData.Time.UnixMilli(), + Timespan: gnssData.Time.Add(8 * time.Hour).UnixMilli(), //file_mqtt协议里面只解析RV, m=> mm RawValue: []float64{gnssData.X * 1000, gnssData.Y * 1000, gnssData.H * 1000}, LimitValue: []float64{}, diff --git a/adaptors/知物云es主题特征to河北公路设施监测.go b/adaptors/知物云es主题特征to河北公路设施监测.go new file mode 100644 index 0000000..fc23f07 --- /dev/null +++ b/adaptors/知物云es主题特征to河北公路设施监测.go @@ -0,0 +1,185 @@ +package adaptors + +import ( + "encoding/json" + "fmt" + "goInOut/consumers/HBJCAS" + "goInOut/consumers/HBJCAS/protoFiles_hb" + "goInOut/dbOperate" + "goInOut/models" + "google.golang.org/protobuf/proto" + "log" + "math" + "strconv" + "strings" + "time" +) + +// Adaptor_ZWYES_HBGL 知物云的测点数据 同步到 河北省公路基础设施健康监测平台 +type Adaptor_ZWYES_HBGL struct { + //传感器code转换信息 + PointInfo map[int64]map[int64]int64 + StructInfo map[int64]int64 + //一些必要信息 + Info map[string]string + Redis *dbOperate.RedisHelper +} + +func (the Adaptor_ZWYES_HBGL) Transform(structId int64, factorId int, rawMsg string) []NeedPush { + esAggDateHistogram := HBJCAS.EsThemeAggDateHistogram{} + var needPush []NeedPush + err := json.Unmarshal([]byte(rawMsg), &esAggDateHistogram) + if err != nil { + return nil + } + + Payload := the.EsAggTopToHBJCAS(structId, factorId, esAggDateHistogram) + if len(Payload) == 0 { + return needPush + } + + needPush = append(needPush, NeedPush{ + Payload: Payload, + }) + return needPush +} + +func (the Adaptor_ZWYES_HBGL) EsAggTopToHBJCAS(structId int64, factorId int, esAggs HBJCAS.EsThemeAggDateHistogram) (result []byte) { + buckets := esAggs.Aggregations.GroupSensor.Buckets + if len(buckets) == 0 { + log.Printf("[s=%d,f=%d] ,es agg数据数量==0", structId, factorId) + return + } + //设施唯一编码(省平台) + uniqueCode := the.getUniqueCode(structId) + if uniqueCode == 0 { + log.Printf("structId=%d,无匹配省平台uniqueCode", structId) + return + } + //数据汇总 + complexData := &protoFiles_hb.ComplexData{} + for _, sensorBucket := range buckets { + sensorId := sensorBucket.Key + for _, dateBucket := range sensorBucket.GroupDate.Buckets { + //优先redis获取 + station := models.Station{} + k1 := fmt.Sprintf("station:%d", sensorId) + errRedis := the.Redis.GetObj(k1, &station) + if errRedis != nil { + log.Printf("redis 获取[s:%d,f:%d]测点[%d]标签异常", structId, factorId, sensorId) + continue + } + monitorCode := the.getPointCodeFromLabel(station.Labels) + if monitorCode == 0 { + log.Printf("redis 获取[s:%d,f:%d]测点[%d]标签,信息转换int64异常,跳过", structId, factorId, sensorId) + continue + } + + dataDefinition := &protoFiles_hb.DataDefinition{ + DataType: protoFiles_hb.DataType_STATISTICS, + UniqueCode: fmt.Sprintf("%d", uniqueCode), + DataBody: the.EsAgg2StatisticData(factorId, monitorCode, dateBucket), + } + complexData.SensorData = append(complexData.SensorData, dataDefinition) + } + } + v, _ := json.Marshal(complexData) + log.Printf("[s:%d,f:%d] 特征数据=> %s", structId, factorId, v) + result, _ = proto.Marshal(complexData) + return result +} + +func (the Adaptor_ZWYES_HBGL) getMonitorTypeByFactorId(factorId int) protoFiles_hb.MonitoryType { + //拱顶沉降 102 桥墩转角 1914 挠度 1917 横向加速度 1919 纵向加速度 1920 + switch factorId { + case 102: + return protoFiles_hb.MonitoryType_GDCJ + case 1914: + return protoFiles_hb.MonitoryType_INC + case 1917: + return protoFiles_hb.MonitoryType_HPT + case 1919: + return protoFiles_hb.MonitoryType_VIB + case 1920: + return protoFiles_hb.MonitoryType_VIB + default: + log.Printf("factorId=%d,无匹配的MonitorType", factorId) + return protoFiles_hb.MonitoryType_CMM + } +} + +func (the Adaptor_ZWYES_HBGL) EsAgg2StatisticData(factorId int, monitorCode int64, dateBucket HBJCAS.BucketsXY) *protoFiles_hb.DataDefinition_StatisticData { + Atime := dateBucket.KeyAsString.Add(-8 * time.Hour).UnixMilli() + maxAbsoluteValueX := max(math.Abs(dateBucket.X.Max), math.Abs(dateBucket.X.Min)) + avgValueX := dateBucket.X.Avg + rootMeanSquareX := math.Sqrt(dateBucket.X.SumOfSquares / float64(dateBucket.X.Count)) + + maxAbsoluteValueY := max(math.Abs(dateBucket.Y.Max), math.Abs(dateBucket.Y.Min)) + avgValueY := dateBucket.Y.Avg + rootMeanSquareY := math.Sqrt(dateBucket.Y.SumOfSquares / float64(dateBucket.Y.Count)) + + monitoryType := the.getMonitorTypeByFactorId(factorId) + dataDefinitionStatisticData := &protoFiles_hb.DataDefinition_StatisticData{ + StatisticData: &protoFiles_hb.StatisticData{ + MonitorType: monitoryType, + MonitorCode: monitorCode, //测点唯一编码 + EventTime: Atime, + Interval: 60 * 1000, + }, + } + + //拱顶沉降 102 桥墩转角 1914 挠度 1917 横向加速度 1919 纵向加速度 1920 + switch factorId { + case 102: //拱顶沉降 + dataDefinitionStatisticData.StatisticData.DataBody = &protoFiles_hb.StatisticData_Gdcj{Gdcj: &protoFiles_hb.GDCJStatistic{ + MaxAbsoluteValue: float32(maxAbsoluteValueX), + AvgValue: float32(avgValueX), + RootMeanSquare: float32(rootMeanSquareX), + TotalAbsoluteValue: float32(dateBucket.X.Max - dateBucket.X.Min), + }} + case 1914: //桥墩转角 + dataDefinitionStatisticData.StatisticData.DataBody = &protoFiles_hb.StatisticData_Inc{Inc: &protoFiles_hb.INCStatistic{ + MaxAbsoluteValueX: float32(maxAbsoluteValueX), + AvgValueX: float32(avgValueX), + RootMeanSquareX: float32(rootMeanSquareX), + MaxAbsoluteValueY: float32(maxAbsoluteValueY), + AvgValueY: float32(avgValueY), + RootMeanSquareY: float32(rootMeanSquareY), + }} + case 1917: //挠度 + dataDefinitionStatisticData.StatisticData.DataBody = &protoFiles_hb.StatisticData_Hpt{Hpt: &protoFiles_hb.HPTStatistic{ + MaxAbsoluteValue: float32(maxAbsoluteValueX), + AvgValue: float32(avgValueX), + RootMeanSquare: float32(rootMeanSquareX), + }} + case 1919, 1920: //振动 + dataDefinitionStatisticData.StatisticData.DataBody = &protoFiles_hb.StatisticData_Vib{Vib: &protoFiles_hb.VIBStatistic{ + MaxAbsoluteValue: float32(maxAbsoluteValueX), + RootMeanSquare: float32(rootMeanSquareY), + }} + } + return dataDefinitionStatisticData +} + +func (the Adaptor_ZWYES_HBGL) getUniqueCode(structId int64) (uniqueCode int64) { + if v, ok := the.StructInfo[structId]; ok { + uniqueCode = v + } + return uniqueCode +} + +func (the Adaptor_ZWYES_HBGL) getPointCodeFromLabel(label string) int64 { + //解析label {13010600001} + pointUniqueCode := int64(0) + if len(label) > 2 { + newLabel := strings.TrimLeft(label, "{") + str := strings.TrimRight(newLabel, "}") + codeInt64, err := strconv.ParseInt(str, 10, 64) + if err != nil { + log.Printf("测点标签转换异常[%s]", label) + } + pointUniqueCode = codeInt64 + } + + return pointUniqueCode +} diff --git a/configFiles/config_河北省公路基础设施监测_知物云_轻量化特征数据.yaml b/configFiles/config_河北省公路基础设施监测_知物云_轻量化特征数据.yaml new file mode 100644 index 0000000..4e73687 --- /dev/null +++ b/configFiles/config_河北省公路基础设施监测_知物云_轻量化特征数据.yaml @@ -0,0 +1,106 @@ +consumer: consumerZWYHBJCAS +ioConfig: + in: + http: + url: https://esproxy.anxinyun.cn/savoir_themes/_search + out: + mqtt: + host: 123.249.81.52 + port: 8883 + userName: bs1321 + password: 9$TyND#ec$aZFfcl + clientId: zhangjiakouJTYS + topics: + - t/province/1321 +monitor: + #振动是触发式,数据迟缓 cron10min也改成1小时一次 最多上报6条,不进行10min实时上报 + cron10min: 6/10 * * * * + #普通类型 特征数据 + cron1hour: 45 0/1 * * * + #推送摄像机状态 1小时 + camera1hour: 0 0/1 * * * + #普推送健康度 24小时,每天8点执行 + health24hour: 0 8 * * * +info: + urlIndex: https://hbjcas.hebitt.com/pms/api/v2/bsi/ + secretKey: CrAd7tkSDXKt7dyk6ueY4OeWRnSHJhUa + rc4key: CrAd7tkSDXKt7dyk6ueY4OeWRnSHJhUa3Al3 +systemID: 1321 +queryComponent: + redis: + address: 10.8.30.160:30379 +#结构物id对应 +structInfo: + 8926: 130830 + 8928: 130831 + 8929: 130832 + 8930: 130833 + 8921: 130834 + 8922: 130835 + 8923: 130836 + 8931: 130837 + 8932: 130838 + 8936: 136137 + 8940: 136139 + 8939: 136141 + 8938: 136142 + 8935: 136144 +#点位id对应信息 +pointInfo: #测点类型支持 桥墩倾斜 15 裂缝18 支座位移20 桥面振动28 +#定义http接口用于对外调用 +httpServer: 0.0.0.0:8425 +#需要上报健康度的(桥梁|隧道|边坡)唯一编码 +codeInfo: + - 130830 + - 130831 + - 130832 + - 130833 + - 130834 + - 130835 + - 130836 + - 130837 + - 130838 + - 136137 + - 136138 + - 136139 + - 136140 + - 136141 + - 136142 + - 136143 + - 136144 + - 136145 +cameraInfo: + - 13083099901 + - 13083099902 + - 13083199903 + - 13083199904 + - 13083299905 + - 13083299906 + - 13083399907 + - 13083399908 + - 13083499909 + - 13083599910 + - 13083699911 + - 13083699912 + - 13083799913 + - 13083799914 + - 13083899915 + - 13083899916 + - 13613799917 + - 13613799918 + - 13613899919 + - 13613899920 + - 13613999921 + - 13613999922 + - 13614099923 + - 13614099924 + - 13614199925 + - 13614199926 + - 13614299927 + - 13614299928 + - 13614399929 + - 13614399930 + - 13614499931 + - 13614499932 + - 13614599933 + - 13614599934 \ No newline at end of file diff --git a/configFiles/弃用备份/config_安心云测点特征数据_广东省平台.yaml b/configFiles/弃用备份/config_安心云测点特征数据_广东省平台.yaml new file mode 100644 index 0000000..10bf9e5 --- /dev/null +++ b/configFiles/弃用备份/config_安心云测点特征数据_广东省平台.yaml @@ -0,0 +1,37 @@ +consumer: consumerAXYES2GDJKJC +ioConfig: + in: + http: + url: https://esproxy.anxinyun.cn/anxincloud_themes/_search + out: + http: + url: https://bmsapi.gdjkjc.cn:13579/Data/AddStatData + method: "post" +monitor: + #振动是触发式,数据迟缓 cron10min也改成1小时一次 最多上报6条,不进行10min实时上报 + cron10min: 25 0/1 * * * #6/10 * * * * + #普通类型 特征数据 + cron1hour: 53 0/1 * * * +info: + 5450: #隆江大桥 + appKey: db43bc5d74534348 + appSecret: 162c0a92f089464eaf9349358af4a830 + 5455: #螺河特大桥 + appKey: 11b8f81901134570 + appSecret: 1505ef9480e4491bb578e2d7d9781620 + 5456: #螺河东大桥 + appKey: d20477c3247b4012 + appSecret: 3d9bfb809be545bba11af17a88c81eb3 +queryComponent: + redis: + address: 10.8.30.160:30379 +#结构物id对应 +structInfo: + bridge: + 5450: G15445224L1120/G15445224R1119 #隆江大桥 + #5455: G15441581L1320/G15441581R1321 #螺河特大桥 + #5456: G15441581L1310/G15441581R1311 #螺河东大桥 + slope: #隧道无特征数据 预留 + #5452: project11223- + + diff --git a/consumers/HBJCAS/config.go b/consumers/HBJCAS/config.go index 30f18fe..e505bde 100644 --- a/consumers/HBJCAS/config.go +++ b/consumers/HBJCAS/config.go @@ -5,8 +5,12 @@ import "goInOut/config" type ConfigFile struct { IoConfig ioConfig `yaml:"ioConfig"` OtherInfo map[string]string `yaml:"info"` + SystemId string `yaml:"systemID"` PointInfo map[int64]map[int64]int64 `yaml:"pointInfo"` StructInfo map[int64]int64 `yaml:"structInfo"` + CameraInfo []int64 `yaml:"cameraInfo"` + CodeInfo []int `yaml:"codeInfo"` + HttpServer string `yaml:"httpServer"` Monitor map[string]string `yaml:"monitor"` QueryComponent queryComponent `yaml:"queryComponent"` } diff --git a/consumers/HBJCAS/interfaceBody.go b/consumers/HBJCAS/interfaceBody.go new file mode 100644 index 0000000..dba6a46 --- /dev/null +++ b/consumers/HBJCAS/interfaceBody.go @@ -0,0 +1,97 @@ +package HBJCAS + +type UploadBody struct { + Data []interface{} `json:"data"` +} + +//摄像机状态 +type CameraInfo struct { + PointUniqueCode int64 `json:"pointUniqueCode"` + Online int `json:"online"` +} + +//桥梁/隧道健康度 +type HealthInfo struct { + UniqueCode int `json:"uniqueCode"` + EntireHealthLevel int `json:"entireHealthLevel"` + ComponentHealthLevel int `json:"componentHealthLevel"` + EvaluateTime int64 `json:"evaluateTime"` + Remark string `json:"remark,omitempty"` +} + +//报警信息内容 +type WarningInfo struct { + AlarmId string `json:"alarmId"` + UniqueCode int `json:"uniqueCode"` + PointUniqueCode int64 `json:"pointUniqueCode"` + AlarmLevel int `json:"alarmLevel"` + MonitorValue string `json:"monitorValue"` + Unit string `json:"unit"` + AlarmStartTime int64 `json:"alarmStartTime"` + ReportToProvinceTime int64 `json:"reportToProvinceTime"` + ReportToProvinceUser string `json:"reportToProvinceUser"` + ReportToProvinceUserTel string `json:"reportToProvinceUserTel"` + AlarmStatus string `json:"alarmStatus"` + HandleTime int64 `json:"handleTime,omitempty"` + HandleUser string `json:"handleUser,omitempty"` + HandleUserTel string `json:"handleUserTel,omitempty"` + HandleContent string `json:"handleContent,omitempty"` + Test bool `json:"test,omitempty"` +} + +//特殊事件信息 +type SpecialEventInfo struct { + SpecialEventId string `json:"specialEventId"` + UniqueCode int `json:"uniqueCode"` + EventType string `json:"eventType"` + EventName string `json:"eventName"` + EventContent string `json:"eventContent"` + EventOccurTime int64 `json:"eventOccurTime"` + ReportToProvinceTime int64 `json:"reportToProvinceTime"` + ReportToProvinceUser string `json:"reportToProvinceUser"` + ReportToProvinceUserTel string `json:"reportToProvinceUserTel"` + Status string `json:"status"` + HandleTime int64 `json:"handleTime,omitempty"` + HandleUser string `json:"handleUser,omitempty"` + HandleUserTel string `json:"handleUserTel,omitempty"` + HandleContent string `json:"handleContent,omitempty"` + Test bool `json:"test,omitempty"` +} + +//特殊事件预案信息 +type SpecialEventPlanInfo struct { + UniqueCode int `json:"uniqueCode"` + File interface{} `json:"file"` + PlanContactsUser string `json:"planContactsUser"` + PlanContactsUserTel string `json:"planContactsUserTel"` + PlanContent string `json:"planContent,omitempty"` + PlanCreateTime int64 `json:"planCreateTime"` + PlanName string `json:"planName"` + PlanRemark string `json:"planRemark,omitempty"` + PlanType string `json:"planType"` + ReportToProvinceTime int64 `json:"reportToProvinceTime"` + ReportToProvinceUser string `json:"reportToProvinceUser"` + ReportToProvinceUserTel string `json:"reportToProvinceUserTel"` + Test bool `json:"test,omitempty"` +} + +//特殊事件预案信息删除 +type EventPlanDel struct { + UniqueCode int `json:"uniqueCode"` + PlanType string `json:"planType"` +} + +//报告信息 +type ReportInfo struct { + UniqueCode int `json:"uniqueCode"` + File interface{} `json:"file"` + ReportName string `json:"reportName"` + SpecialEventId string `json:"specialEventId,omitempty"` + ReportTime int64 `json:"reportTime"` + ReportToProvinceTime int64 `json:"reportToProvinceTime"` + ReportToProvinceUser string `json:"reportToProvinceUser"` + ReportToProvinceUserTel string `json:"reportToProvinceUserTel"` + ReportType string `json:"reportType"` + UploadType string `json:"uploadType,omitempty"` + Test bool `json:"test,omitempty"` +} diff --git a/consumers/consumerHBJCAS.go b/consumers/consumerHBJCAS.go index 8babaa7..563705e 100644 --- a/consumers/consumerHBJCAS.go +++ b/consumers/consumerHBJCAS.go @@ -161,7 +161,7 @@ func (the *consumerHBJCAS) getEs10minAggData() { //utils.GetTimeRangeBy10min() 由于振动数据实时性问题 改用一小时统一上报 start, end := utils.GetTimeRangeByHour(-1) log.Printf("查询10min数据时间范围 %s - %s", start, end) - factorIds := []int{28, 592} //监测因素 592 -> 结构物[5222]隧道河北承德广仁岭隧道(上行) 的加速度三项监测 + factorIds := []int{28, 592} structIds := the.getStructIds() for _, structId := range structIds { for _, factorId := range factorIds { diff --git a/consumers/consumerZWYHBJCAS.go b/consumers/consumerZWYHBJCAS.go new file mode 100644 index 0000000..4774110 --- /dev/null +++ b/consumers/consumerZWYHBJCAS.go @@ -0,0 +1,561 @@ +package consumers + +import ( + "crypto/hmac" + "crypto/rc4" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/tjfoc/gmsm/sm3" + "goInOut/adaptors" + "goInOut/consumers/HBJCAS" + "goInOut/dbOperate" + "goInOut/monitors" + "goInOut/utils" + "gopkg.in/yaml.v3" + "io" + "io/ioutil" + "log" + "net/http" + "strings" + "time" +) + +type consumerZWYHBJCAS struct { + //数据缓存管道 + ch chan []adaptors.NeedPush + //具体配置 + Info HBJCAS.ConfigFile + Seq int64 + SeqDate string + InHttp *dbOperate.HttpHelper + outMqtt *dbOperate.MqttHelper + monitor *monitors.CommonMonitor + infoRedis *dbOperate.RedisHelper +} + +func (the *consumerZWYHBJCAS) LoadConfigJson(cfgStr string) { + // 将 yaml 格式的数据解析到结构体中 + err := yaml.Unmarshal([]byte(cfgStr), &the.Info) + if err != nil { + log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error()) + panic(err) + } +} + +func (the *consumerZWYHBJCAS) Initial(cfg string) error { + the.LoadConfigJson(cfg) + err := the.InputInitial() + if err != nil { + return err + } + err = the.OutputInitial() + if err != nil { + return err + } + err = the.infoComponentInitial() + return err +} +func (the *consumerZWYHBJCAS) InputInitial() error { + the.ch = make(chan []adaptors.NeedPush, 200) + //数据入口 + the.InHttp = &dbOperate.HttpHelper{Url: the.Info.IoConfig.In.Http.Url, Token: ""} + the.monitor = &monitors.CommonMonitor{ + MonitorHelper: &monitors.MonitorHelper{}, + } + the.Seq = 0 + the.SeqDate = time.Now().Format("2006-01-02") + the.monitor.Start() + for taskName, cron := range the.Info.Monitor { + switch taskName { + case "cron10min": + the.monitor.RegisterTask(cron, the.getEs10minAggData) + case "cron1hour": + the.monitor.RegisterTask(cron, the.getEs1HourAggData) + case "camera1hour": + the.monitor.RegisterTask(cron, the.UploadCamInfo) + case "health24hour": + the.monitor.RegisterTask(cron, the.UploadHeaInfo) + default: + log.Printf("定时任务[%s],cron=[%s] 无匹配", taskName, cron) + } + } + return nil +} +func (the *consumerZWYHBJCAS) OutputInitial() error { + //数据出口 + the.outMqtt = dbOperate.MqttInitial( + the.Info.IoConfig.Out.Mqtt.Host, + the.Info.IoConfig.Out.Mqtt.Port, + the.Info.IoConfig.Out.Mqtt.ClientId, + the.Info.IoConfig.Out.Mqtt.UserName, + the.Info.IoConfig.Out.Mqtt.Password, + true, //按照具体项目来 + "consumers/HBJCAS/ssl/cacert.pem", + "consumers/HBJCAS/ssl/client-cert.pem", + "consumers/HBJCAS/ssl/client-key.pem") + return nil +} + +func (the *consumerZWYHBJCAS) infoComponentInitial() error { + //数据出口 + addr := the.Info.QueryComponent.Redis.Address + the.infoRedis = dbOperate.NewRedisHelper("", addr) + return nil +} +func (the *consumerZWYHBJCAS) Work() { + go func() { + for { + needPushList := <-the.ch + if len(the.ch) > 0 { + log.Printf("取出ch数据,剩余[%d] ", len(the.ch)) + } + + for _, push := range needPushList { + if push.Topic != "" { + the.outMqtt.Publish(push.Topic, push.Payload) + continue + } + + //没有标记topic 的 按照配置文件里面的推送 + for _, topic := range the.Info.IoConfig.Out.Mqtt.Topics { + the.outMqtt.Publish(topic, push.Payload) + } + + } + + time.Sleep(100 * time.Millisecond) + } + }() + go func() { + if the.Info.HttpServer != "" { + log.Printf("打开本地http接口服务[%s]\n", the.Info.HttpServer) + the.StartHttp() + } + }() +} + +func (the *consumerZWYHBJCAS) getAdaptor() (adaptor adaptors.Adaptor_ZWYES_HBGL) { + + return adaptors.Adaptor_ZWYES_HBGL{ + Redis: the.infoRedis, + } +} + +func (the *consumerZWYHBJCAS) getStructIds() []int64 { + var structIds []int64 + for strutId, _ := range the.Info.StructInfo { + structIds = append(structIds, strutId) + } + return structIds +} + +func (the *consumerZWYHBJCAS) getEs1HourAggData() { + start, end := utils.GetTimeRangeByHour(-1) + log.Printf("查询数据时间范围 %s - %s", start, end) + hourFactorIds := []int{15, 18, 20} + structIds := the.getStructIds() + for _, structId := range structIds { + for _, factorId := range hourFactorIds { + esQuery := the.getESQueryStrByHour(structId, factorId, start, end) + auth := map[string]string{"Authorization": "Bear 85a441d4-022b-4613-abba-aaa8e2693bf7"} + esAggResultStr := the.InHttp.HttpGetWithHeader(esQuery, auth) + + adaptor := the.getAdaptor() + adaptor.PointInfo = the.Info.PointInfo + adaptor.StructInfo = the.Info.StructInfo + needPushes := adaptor.Transform(structId, factorId, esAggResultStr) + for i := range needPushes { + needPushes[i].Payload = the.crc16rc4(needPushes[i].Payload) + } + + if len(needPushes) > 0 { + the.ch <- needPushes + } + } + } + +} + +func (the *consumerZWYHBJCAS) getEs10minAggData() { + //utils.GetTimeRangeBy10min() 由于振动数据实时性问题 改用一小时统一上报 + start, end := utils.GetTimeRangeByHour(-1) + log.Printf("查询10min数据时间范围 %s - %s", start, end) + factorIds := []int{28, 592} + structIds := the.getStructIds() + for _, structId := range structIds { + for _, factorId := range factorIds { + esQuery := the.getESQueryStrBy10min(structId, factorId, start, end) + auth := map[string]string{"Authorization": "Bear 85a441d4-022b-4613-abba-aaa8e2693bf7"} + esAggResultStr := the.InHttp.HttpGetWithHeader(esQuery, auth) + + adaptor := the.getAdaptor() + adaptor.PointInfo = the.Info.PointInfo + adaptor.StructInfo = the.Info.StructInfo + needPushes := adaptor.Transform(structId, factorId, esAggResultStr) + for i := range needPushes { + needPushes[i].Payload = the.crc16rc4(needPushes[i].Payload) + log.Printf("topic[%s],Payload=> %s", needPushes[i].Topic, hex.EncodeToString(needPushes[i].Payload)) + } + + if len(needPushes) > 0 { + the.ch <- needPushes + } + } + } + +} + +func (the *consumerZWYHBJCAS) crc16rc4(transBytes []byte) []byte { + resultByCrc16 := utils.NewCRC16CCITT().GetWCRCin(transBytes) + needRC4 := append(transBytes, resultByCrc16...) + rc4KeyStr, ok := the.Info.OtherInfo["rc4key"] + if !ok { + log.Panicf("未配置 rc4key") + } + rc4Key := []byte(rc4KeyStr) //the.RC4Key + // 加密操作 + dest1 := make([]byte, len(needRC4)) + rc4.NewCipher(rc4Key) + cipher1, _ := rc4.NewCipher(rc4Key) + cipher1.XORKeyStream(dest1, needRC4) + return dest1 +} + +func (the *consumerZWYHBJCAS) getESQueryStrByHour(structureId int64, factorId int, start, end string) string { + aggSubSql := utils.GetEsAggSubSqlByAxyFactorId(factorId) + esQuery := fmt.Sprintf(` +{ + "size": 0, + "query": { + "bool": { + "must": [ + { + "term": { + "structure": { + "value": %d + } + } + }, + { + "term": { + "factor": { + "value": %d + } + } + }, + { + "range": { + "collect_time": { + "gte": "%s", + "lt": "%s" + } + } + } + ] + } + }, + "aggs": { + "groupSensor": { + "terms": { + "field": "sensor" + }, + "aggs": { + "groupDate": { + "date_histogram": { + "field": "collect_time", + "interval": "1h", + "time_zone": "Asia/Shanghai", + "min_doc_count": 1 + }, + "aggs": %s + } + } + } + } +} +`, structureId, factorId, start, end, aggSubSql) + + return esQuery +} + +func (the *consumerZWYHBJCAS) getESQueryStrBy10min(structureId int64, factorId int, start, end string) string { + aggSubSql := utils.GetEsAggSubSqlByAxyFactorId(factorId) + esQuery := fmt.Sprintf(` +{ + "size": 0, + "query": { + "bool": { + "must": [ + { + "term": { + "structure": { + "value": %d + } + } + }, + { + "term": { + "factor": { + "value": %d + } + } + }, + { + "range": { + "collect_time": { + "gte": "%s", + "lte": "%s" + } + } + } + ] + } + }, + "aggs": { + "groupSensor": { + "terms": { + "field": "sensor" + }, + "aggs": { + "groupDate": { + "date_histogram": { + "field": "collect_time", + "interval": "10m", + "time_zone": "Asia/Shanghai", + "min_doc_count": 1 + }, + "aggs": %s + } + } + } + } +} +`, structureId, factorId, start, end, aggSubSql) + + return esQuery +} + +func (the *consumerZWYHBJCAS) getStructureId() string { + structureId, ok := the.Info.OtherInfo["structureId"] + if !ok { + log.Panicf("无法识别有效的structureId") + } + return structureId +} + +//获取配置在yaml文件中的cameraInfo对应的摄像机的状态 +func (the *consumerZWYHBJCAS) getCameraStatus() []interface{} { + cameraArr := the.Info.CameraInfo + cameras := make([]interface{}, 0) + for _, cameraId := range cameraArr { + //增加根据cameraId获取对应摄像机状态 + camera := HBJCAS.CameraInfo{ + PointUniqueCode: cameraId, + Online: 1, + } + cameras = append(cameras, camera) + } + return cameras +} + +//获取配置在yaml文件中的codeInfo对应的需要上报健康度的(桥梁|隧道|边坡)的健康度 +func (the *consumerZWYHBJCAS) getCodeStatus() []interface{} { + infoArr := the.Info.CodeInfo + res := make([]interface{}, 0) + for _, info := range infoArr { + //增加根据code码获取对应摄像机状态 + nInfo := HBJCAS.HealthInfo{ + UniqueCode: info, + EntireHealthLevel: 0, + ComponentHealthLevel: 0, + EvaluateTime: time.Now().UnixNano() / 1e6, + } + res = append(res, nInfo) + } + return res +} + +// JWT头部 +type Header struct { + Typ string `json:"typ"` + Alg string `json:"alg"` +} + +// JWT载荷 +type Payload struct { + SystemID string `json:"systemId"` + Seq int64 `json:"seq"` + Timestamp int64 `json:"timestamp"` +} + +type Resp struct { + Code int `json:"code"` + Msg string `json:"msg"` +} + +func (the *consumerZWYHBJCAS) GenerateJWT() (string, error) { + // 创建头部 + header := Header{ + Typ: "JWT", + Alg: "SM3", + } + headerBytes, _ := json.Marshal(header) + headerBase64 := base64.StdEncoding.EncodeToString(headerBytes) + seq := int64(0) + if the.Seq != 0 { + if time.Now().Format("2006-01-02") != the.SeqDate { + the.Seq = 0 + } + } + seq = the.Seq + // 创建载荷 + payload := Payload{ + SystemID: the.Info.SystemId, + Seq: seq, + Timestamp: time.Now().UnixNano() / 1e6, // 当前时间戳,单位毫秒 + } + payloadBytes, _ := json.Marshal(payload) + payloadBase64 := base64.StdEncoding.EncodeToString(payloadBytes) + + // 创建签名 + message := headerBase64 + "." + payloadBase64 + var signatureBase64 string + h := sm3.New() + h.Write([]byte(message)) + secretKeyStr, ok := the.Info.OtherInfo["secretKey"] + if !ok { + log.Println("未配置 secretKey") + secretKeyStr = "" + } + secretKey := []byte(secretKeyStr) + signature := hmac.New(sm3.New, secretKey) + signature.Write([]byte(message)) + signatureBytes := signature.Sum(nil) + signatureBase64 = base64.StdEncoding.EncodeToString(signatureBytes) + // 组装JWT + jwt := message + "." + signatureBase64 + return jwt, nil +} + +func (the *consumerZWYHBJCAS) UploadInfo(uploadType string) { + urlIndex, ok := the.Info.OtherInfo["urlIndex"] + if !ok { + log.Println("未配置省平台业务数据接口=============") + return + } + url := "" + var bodyInfo []interface{} + switch uploadType { + case "cameraInfo": + url = urlIndex + "cameraInfo/statusReport" + bodyInfo = the.getCameraStatus() + if len(bodyInfo) == 0 { + return + } + case "healthInfo": + url = urlIndex + "healthInfo/sync" + bodyInfo = the.getCodeStatus() + if len(bodyInfo) == 0 { + return + } + default: + return + } + tBody := HBJCAS.UploadBody{ + Data: bodyInfo, + } + jsonData, masErr := json.Marshal(tBody) + if masErr != nil { + fmt.Println(masErr) + return + } + payLoadStr := string(jsonData) + err := the.postInfo(url, payLoadStr) + if err != nil { + log.Printf("数据上报失败,err=%v\n", err) + } + +} +func (the *consumerZWYHBJCAS) UploadCamInfo() { + the.UploadInfo("cameraInfo") +} + +func (the *consumerZWYHBJCAS) UploadHeaInfo() { + the.UploadInfo("healthInfo") +} + +func (the *consumerZWYHBJCAS) postInfo(url, payloadStr string) error { + payload := strings.NewReader(payloadStr) + client := &http.Client{} + req, requestErr := http.NewRequest("POST", url, payload) + if requestErr != nil { + return requestErr + } + jwtRes, jwtErr := the.GenerateJWT() + if jwtErr != nil { + return jwtErr + } + auth := fmt.Sprintf("Bearer %s", jwtRes) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Authorization", auth) + res, clientErr := client.Do(req) + if clientErr != nil { + return clientErr + } + defer res.Body.Close() + + body, respErr := ioutil.ReadAll(res.Body) + if respErr != nil { + return respErr + } + var resp Resp + err := yaml.Unmarshal(body, &resp) + if err != nil { + log.Printf("接口返回[%s]转换失败 err=%v", string(body), err) + return err + } + the.Seq++ + if resp.Code != 100 { + log.Printf("接口[%s]返回非成功状态 code=%d,msg=[%s]", url, resp.Code, resp.Msg) + } + return nil +} + +func (the *consumerZWYHBJCAS) StartHttp() { + http.HandleFunc("/ping", RespHandle) + http.ListenAndServe(the.Info.HttpServer, nil) +} + +func RespHandle(w http.ResponseWriter, r *http.Request) { + _, err := ioutil.ReadAll(r.Body) + if err != nil && err != io.EOF { + fmt.Printf("read body content failed, err:[%s]\n", err.Error()) + return + } + fmt.Fprint(w, "Pong!") + +} + +func downloadFile(url string) ([]byte, error) { + // 发送GET请求下载文件 + response, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to download file[%s],err=%v", url, err) + } + defer response.Body.Close() + + // 检查响应状态 + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("down file[%s] server returned: %v", url, response.Status) + } + + // 读取文件内容 + fileContent, err := io.ReadAll(response.Body) + if err != nil { + return nil, fmt.Errorf("failed to read file[%s] content: %v", url, err) + } + + return fileContent, nil +} diff --git a/go.mod b/go.mod index e140131..509a2e3 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect golang.org/x/crypto v0.26.0 // indirect diff --git a/go.sum b/go.sum index 9f192c1..cd1da61 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA= github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= @@ -10,8 +12,11 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -28,15 +33,33 @@ github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQ github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= github.com/elastic/go-elasticsearch/v6 v6.8.10 h1:2lN0gJ93gMBXvkhwih5xquldszpm8FlUwqG5sPzr6a8= github.com/elastic/go-elasticsearch/v6 v6.8.10/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= @@ -97,6 +120,7 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= @@ -117,6 +141,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= @@ -124,24 +150,42 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -164,12 +208,30 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= @@ -185,3 +247,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=