From 97e94587007de214c29fa9742bab1c02775c8ad4 Mon Sep 17 00:00:00 2001 From: lorsan Date: Wed, 15 Apr 2026 17:55:34 +0300 Subject: [PATCH] feat: new hub service in hub --- internal/agent/utils/settings/settings.go | 24 +++++++++----------- internal/domain/mapper.go | 18 +++++++++------ internal/hub/app/app.go | 16 ++++++++------ internal/hub/rpc/server.go | 14 +++++++----- internal/hub/service/hub_service/hub.go | 19 +++++++++++++++- internal/hub/utils/hasher/id.go | 27 +++++++++++++++++++++++ 6 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 internal/hub/utils/hasher/id.go diff --git a/internal/agent/utils/settings/settings.go b/internal/agent/utils/settings/settings.go index 9be1cb0..1632780 100644 --- a/internal/agent/utils/settings/settings.go +++ b/internal/agent/utils/settings/settings.go @@ -30,31 +30,29 @@ func ReadSettings(path string) (*Settings, error) { err = nil } - file, err := os.Create(path + "/settings.json") - if err != nil { - if !errors.Is(err, os.ErrExist) { - return nil, err - } - err = nil - } - defer file.Close() - + settingsPath := filepath.Join(path, "settings.json") var settings Settings - err = json.NewDecoder(file).Decode(&settings) + file, err := os.Open(settingsPath) if err != nil { - if !errors.Is(err, io.EOF) { + if !errors.Is(err, os.ErrNotExist) { + return nil, err + } + } else { + defer file.Close() + err = json.NewDecoder(file).Decode(&settings) + if err != nil && !errors.Is(err, io.EOF) { return nil, err } } - settings.path = path + "/settings.json" + settings.path = settingsPath return &settings, nil } func (s *Settings) Insert(sett Settings) error { - file, err := os.OpenFile(s.path, os.O_RDWR, 0755) + file, err := os.OpenFile(s.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return err } diff --git a/internal/domain/mapper.go b/internal/domain/mapper.go index 9f7a128..2812e8e 100644 --- a/internal/domain/mapper.go +++ b/internal/domain/mapper.go @@ -4,12 +4,12 @@ import ( pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" ) -func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentData { +func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentRequest { if request == nil { - return RegisterAgentData{} + return RegisterAgentRequest{} } - return RegisterAgentData{ + return RegisterAgentRequest{ AgentId: request.AgentId, AgentName: request.AgentName, Host: HostInfo{ @@ -21,12 +21,12 @@ func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentData { } } -func ToDomainAgentResponse(response *pb.RegisterAgentResponse) RegisterAgentDataResponse { +func ToDomainAgentResponse(response *pb.RegisterAgentResponse) RegisterAgentResponse { if response == nil { - return RegisterAgentDataResponse{} + return RegisterAgentResponse{} } - return RegisterAgentDataResponse{ + return RegisterAgentResponse{ AgentID: response.AgentId, Heartbeat: int(response.HeartbeatIntervalSecond), } @@ -51,7 +51,7 @@ func ToDomainCapabilities(capability []*pb.Capability) []Capability { return caps } -func ToGRPCAgentRequest(request RegisterAgentData) pb.RegisterAgentRequest { +func ToGRPCAgentRequest(request RegisterAgentRequest) pb.RegisterAgentRequest { return pb.RegisterAgentRequest{ AgentId: request.AgentId, AgentName: request.AgentName, @@ -65,6 +65,10 @@ func ToGRPCAgentRequest(request RegisterAgentData) pb.RegisterAgentRequest { } } +func ToGRPCAgentResponse(response RegisterAgentResponse) *pb.RegisterAgentResponse { + return &pb.RegisterAgentResponse{AgentId: response.AgentID, HeartbeatIntervalSecond: int64(response.Heartbeat)} +} + func ToGRPCCapability(caps []Capability) []*pb.Capability { var capability []*pb.Capability for _, capi := range caps { diff --git a/internal/hub/app/app.go b/internal/hub/app/app.go index 6f2ac61..86ab0ef 100644 --- a/internal/hub/app/app.go +++ b/internal/hub/app/app.go @@ -6,15 +6,15 @@ import ( "net" grpcserv "github.com/lorsanstand/HomeOps-Hub/internal/hub/rpc" + "github.com/lorsanstand/HomeOps-Hub/internal/hub/service/hub_service" "github.com/lorsanstand/HomeOps-Hub/internal/shared/config" "github.com/lorsanstand/HomeOps-Hub/internal/shared/log" "github.com/rs/zerolog" ) type App struct { - cfg *config.Config - log zerolog.Logger - server *grpcserv.HubHandler + cfg *config.Config + log zerolog.Logger } func NewApp() *App { @@ -25,9 +25,7 @@ func NewApp() *App { logger := log.NewLogger(cfg) - server := grpcserv.NewHubHandler(logger) - - return &App{cfg: cfg, log: logger, server: server} + return &App{cfg: cfg, log: logger} } func (a *App) Run() { @@ -41,12 +39,16 @@ func (a *App) hubServe() error { address := fmt.Sprintf("0.0.0.0:%v", a.cfg.Port) a.log.Info().Str("address", "http://"+address).Msg("start GRPC server") + hub := hub_service.NewHubService(a.log) + + server := grpcserv.NewHubHandler(hub, a.log) + lis, err := net.Listen("tcp", address) if err != nil { return err } - err = a.server.GrpcServer.Serve(lis) + err = server.GrpcServer.Serve(lis) if err != nil { return err } diff --git a/internal/hub/rpc/server.go b/internal/hub/rpc/server.go index 218f1ea..29fac52 100644 --- a/internal/hub/rpc/server.go +++ b/internal/hub/rpc/server.go @@ -2,7 +2,6 @@ package rpc import ( "context" - "fmt" pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" "github.com/lorsanstand/HomeOps-Hub/internal/domain" @@ -11,14 +10,19 @@ import ( "google.golang.org/protobuf/types/known/emptypb" ) +type HubService interface { + RegisterAgent(data domain.RegisterAgentRequest) domain.RegisterAgentResponse +} + type HubHandler struct { pb.UnimplementedHubServer log zerolog.Logger GrpcServer *grpc.Server + hub HubService } -func NewHubHandler(logger zerolog.Logger) *HubHandler { - hub := &HubHandler{log: logger} +func NewHubHandler(HubServ HubService, logger zerolog.Logger) *HubHandler { + hub := &HubHandler{log: logger, hub: HubServ} grpcServer := grpc.NewServer() pb.RegisterHubServer(grpcServer, hub) @@ -35,6 +39,6 @@ func (h *HubHandler) Ping(ctx context.Context, _ *emptypb.Empty) (*pb.PongRespon func (h *HubHandler) RegisterAgent(ctx context.Context, request *pb.RegisterAgentRequest) (*pb.RegisterAgentResponse, error) { data := domain.ToDomainAgentRequest(request) - fmt.Println(data) - return &pb.RegisterAgentResponse{}, nil + resp := h.hub.RegisterAgent(data) + return domain.ToGRPCAgentResponse(resp), nil } diff --git a/internal/hub/service/hub_service/hub.go b/internal/hub/service/hub_service/hub.go index 15e89d5..712c3a2 100644 --- a/internal/hub/service/hub_service/hub.go +++ b/internal/hub/service/hub_service/hub.go @@ -2,6 +2,7 @@ package hub_service import ( "github.com/lorsanstand/HomeOps-Hub/internal/domain" + "github.com/lorsanstand/HomeOps-Hub/internal/hub/utils/hasher" "github.com/rs/zerolog" ) @@ -9,4 +10,20 @@ type HubService struct { log zerolog.Logger } -func NewHubService(request domain.RegisterAgentRequest) +func NewHubService(logger zerolog.Logger) *HubService { + return &HubService{log: logger} +} + +func (h *HubService) RegisterAgent(data domain.RegisterAgentRequest) domain.RegisterAgentResponse { + AgentID := data.AgentId + if data.AgentId == "" { + var err error + AgentID, err = hasher.MakeID(data.Host, data.AgentName) + if err != nil { + h.log.Error().Err(err).Msg("failed create agent id") + AgentID = "" + } + } + + return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: 5} +} diff --git a/internal/hub/utils/hasher/id.go b/internal/hub/utils/hasher/id.go new file mode 100644 index 0000000..e28b504 --- /dev/null +++ b/internal/hub/utils/hasher/id.go @@ -0,0 +1,27 @@ +package hasher + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "fmt" + + "github.com/lorsanstand/HomeOps-Hub/internal/domain" +) + +func newSalt(n int) ([]byte, error) { + b := make([]byte, n) + _, err := rand.Read(b) + return b, err +} + +func MakeID(info domain.HostInfo, AgentName string) (string, error) { + salt, err := newSalt(10) + if err != nil { + return "", err + } + + s := fmt.Sprintf("v1|host=%s|distro=%s|name=%s|", info.Hostname, info.Arch, AgentName) + h := sha256.Sum256(append([]byte(s), salt...)) + return hex.EncodeToString(h[:16]), nil +}