chore: 初始开源发布

iotlcm-upstream-chan:运营商上游通道适配服务(统一 /sim/* 协议)。

- 内联原私有依赖:yunze-public → internal/pub/(10 包 18 文件),
  yunze-pb/pb → internal/pb/(9 文件);Consul 注册改用官方
  gogf/gf/contrib/registry/consul/v2(API 兼容)
- Go module:yz-svr → git.5iot.com/iotlcm-public/iotlcm-upstream-chan
- 修复 mingqian 包测试:实现重构后 `adapter.operations` 字段已移除,
  测试断言按当前实现语义重写(不改产品行为)
- 凭据与内部标识脱敏:MySQL/Redis/Consul 凭据、私网与生产 IP、
  内网域名、真实手机号、注释里的真实 token/transid
- 移除内部资产:CI 触发器、生产通道种子 SQL、真实凭据测试资源文档
- Dockerfile 改用公共基础镜像,移除写死的 registry 凭据
- 补 Apache-2.0 LICENSE,重写 README,LF 行尾 + .gitattributes
This commit is contained in:
MiFaZhan
2026-10-22 15:42:29 +08:00
commit 96b1edff45
191 changed files with 30805 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
package upstreamimpl
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"git.5iot.com/iotlcm-public/iotlcm-upstream-chan/internal/model"
"github.com/gogf/gf/v2/frame/g"
)
const (
defaultUpstreamHTTPTimeout = 10 * time.Second
upstreamHTTPTimeoutKey = "dependencies.upstream_http.timeout"
)
func templateConfigJSON(channelConfig *model.SimChannelConfigItemCache) string {
if channelConfig == nil || channelConfig.Template == nil {
return ""
}
return channelConfig.Template.TempConfig
}
// parseUpstreamDuration accepts Go duration strings and positive numeric
// seconds so template and application configuration use the same contract.
func parseUpstreamDuration(raw json.RawMessage, field string) (time.Duration, error) {
if len(raw) == 0 || string(raw) == "null" {
return 0, fmt.Errorf("%s is empty", field)
}
var value any
if err := json.Unmarshal(raw, &value); err != nil {
return 0, fmt.Errorf("invalid %s: %w", field, err)
}
switch v := value.(type) {
case float64:
if v <= 0 || v != float64(int64(v)) {
return 0, fmt.Errorf("invalid %s: expected positive seconds", field)
}
return time.Duration(v) * time.Second, nil
case string:
value := strings.TrimSpace(v)
if value == "" {
return 0, fmt.Errorf("invalid %s: empty value", field)
}
duration, err := time.ParseDuration(value)
if err != nil || duration <= 0 {
return 0, fmt.Errorf("invalid %s: expected positive duration", field)
}
return duration, nil
default:
return 0, fmt.Errorf("invalid %s: expected duration or seconds", field)
}
}
func parseUpstreamConfigDuration(value any, field string) (time.Duration, error) {
raw, err := json.Marshal(value)
if err != nil {
return 0, fmt.Errorf("encode %s: %w", field, err)
}
return parseUpstreamDuration(raw, field)
}
func loadDefaultUpstreamHTTPTimeout(ctx context.Context) time.Duration {
value := g.Cfg().MustGet(ctx, upstreamHTTPTimeoutKey, defaultUpstreamHTTPTimeout.String()).Val()
timeout, err := parseUpstreamConfigDuration(value, upstreamHTTPTimeoutKey)
if err != nil {
g.Log().Warningf(ctx, "%v, fallback to %s", err, defaultUpstreamHTTPTimeout)
return defaultUpstreamHTTPTimeout
}
return timeout
}
// resolveUpstreamHTTPTimeout applies the single timeout override for a
// template. Missing or invalid template values fall back to application
// configuration and finally the code default.
func resolveUpstreamHTTPTimeout(ctx context.Context, tempConfig string) time.Duration {
defaultTimeout := loadDefaultUpstreamHTTPTimeout(ctx)
if strings.TrimSpace(tempConfig) == "" {
return defaultTimeout
}
var raw struct {
HTTP struct {
Timeout json.RawMessage `json:"timeout"`
} `json:"http"`
}
if err := json.Unmarshal([]byte(tempConfig), &raw); err != nil {
g.Log().Warningf(ctx, "parse upstream template config failed: %v, fallback to %s", err, defaultTimeout)
return defaultTimeout
}
if len(raw.HTTP.Timeout) == 0 || string(raw.HTTP.Timeout) == "null" {
return defaultTimeout
}
timeout, err := parseUpstreamDuration(raw.HTTP.Timeout, "http.timeout")
if err != nil {
g.Log().Warningf(ctx, "%v, fallback to %s", err, defaultTimeout)
return defaultTimeout
}
return timeout
}