From c4172ac1f81582c9af7dbe11849034e89848d5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Fri, 30 Jan 2026 13:40:42 +0200 Subject: [PATCH] working commit --- app/config/config.go | 23 ++++++++-------- app/server/server.go | 37 +++++++++++++++++--------- app/server/server_test.go | 56 +++++++++++++++++++++++++++++++++++++++ app/service/service.go | 39 +++++++++++++++------------ pkg/client/client.go | 50 +++++++++++++++++++++++++++++++++- 5 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 app/server/server_test.go diff --git a/app/config/config.go b/app/config/config.go index 7666ebe..9ab8fe1 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -26,17 +26,17 @@ type Storage struct { } type Config struct { - Service Service `json:"service" yaml:"service"` + Service Service `json:"service"` Database Database `json:"database" yaml:"database"` Storage Storage `json:"storage" yaml:"storage"` AsDaemon bool `json:"asDaemon" yaml:"asDaemon"` Logpath string `json:"logpath" yaml:"logpath"` Runpath string `json:"runpath" yaml:"runpath"` Version string `json:"version" yaml:"version"` - Certpath string `json:"certpath" yaml:"certath"` - Keypath string `json:"keypath" yaml:"keypath"` - X509Cert string `json:"X509cert" yaml:"X509cert"` - X509Key string `json:"X509key" yaml:"X509key"` + Certpath string `json:"certpath,omitempty" yaml:"certath"` + Keypath string `json:"keypath,omitempty" yaml:"keypath"` + X509Cert string `json:"-" yaml:"-"` + X509Key string `json:"-" yaml:"-"` } func NewConfig() *Config { @@ -46,11 +46,11 @@ func NewConfig() *Config { runfile := fmt.Sprintf("%s.run", srvname) runpath := filepath.Join(rundir, runfile) - certpath := fmt.Sprintf("%s.crt", srvname) - certpath = filepath.Join(confdir, certpath) + //certpath := fmt.Sprintf("%s.crt", srvname) + //certpath = filepath.Join(confdir, certpath) - keypath := fmt.Sprintf("%s.crt", srvname) - keypath = filepath.Join(confdir, keypath) + //keypath := fmt.Sprintf("%s.crt", srvname) + //keypath = filepath.Join(confdir, keypath) return &Config{ Service: Service{ @@ -67,8 +67,9 @@ func NewConfig() *Config { Logpath: logpath, Runpath: runpath, Version: version, - Certpath: certpath, - Keypath: keypath, + + //Certpath: certpath, + //Keypath: keypath, } } diff --git a/app/server/server.go b/app/server/server.go index 5d0f422..1918863 100644 --- a/app/server/server.go +++ b/app/server/server.go @@ -44,7 +44,7 @@ func (srv *Server) Handler() *handler.Handler { func (srv *Server) Configure() error { var err error - srv.logg.Infof("Server configure") + srv.logg.Infof("Configuration server") srv.conf = config.NewConfig() if err != nil { return err @@ -54,6 +54,11 @@ func (srv *Server) Configure() error { //srv.logg.Warningf("Error loading config file: %v", err) //return err } + err = srv.conf.ReadX509Cert() + if err != nil { + return err + } + err = srv.conf.ReadOptions() if err != nil { return err @@ -83,7 +88,7 @@ func (srv *Server) Build() error { } } - // Database create + // Creating database dbdir := srv.conf.Database.Basepath srv.logg.Infof("Create database directory %s ", dbdir) err = os.MkdirAll(dbdir, 0750) @@ -104,19 +109,20 @@ func (srv *Server) Build() error { } srv.mdb = mdb - // Storage create + // Creating storage srv.logg.Infof("Create storage directory") datadir := srv.conf.Database.Basepath err = os.MkdirAll(datadir, 0750) if err != nil { return err } - srv.logg.Infof("Create storage") + + srv.logg.Infof("Creating storage") store := storage.NewStorage(datadir) srv.stor = store - // Operator create - srv.logg.Infof("Create operator") + // Creating operator + srv.logg.Infof("Creating operator") operatorParams := &operator.OperatorParams{ MainDB: srv.mdb, Store: srv.stor, @@ -125,8 +131,8 @@ func (srv *Server) Build() error { if err != nil { return err } - // Handler create - srv.logg.Infof("Create handler") + // Creating handler + srv.logg.Infof("Creating handler") handlerParams := &handler.HandlerParams{ Operator: srv.oper, } @@ -134,16 +140,20 @@ func (srv *Server) Build() error { if err != nil { return err } - // Service create + // Creating service serviceParams := &service.ServiceParams{ - Handler: srv.hand, + Handler: srv.hand, + X509Cert: srv.conf.X509Cert, + X509Key: srv.conf.X509Key, + Address: srv.conf.Service.Address, + Portnum: srv.conf.Service.Port, } - srv.logg.Infof("Create service") + srv.logg.Infof("Creating service") srv.svc, err = service.NewService(serviceParams) if err != nil { return err } - // Service build + // Building service err = srv.svc.Build() if err != nil { return err @@ -161,7 +171,6 @@ func (srv *Server) Run() error { } srv.logg.Infof("Server run as user %s", currUser.Username) - sigs := make(chan os.Signal, 1) svcDone := make(chan error, 1) // Service run @@ -175,6 +184,8 @@ func (srv *Server) Run() error { } go startService(srv.svc, svcDone) + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) var signal os.Signal diff --git a/app/server/server_test.go b/app/server/server_test.go new file mode 100644 index 0000000..dd738cc --- /dev/null +++ b/app/server/server_test.go @@ -0,0 +1,56 @@ +package server + +import ( + "context" + "sync" + "testing" + "time" + + "mstore/pkg/client" + + "github.com/stretchr/testify/require" +) + +func TestService(t *testing.T) { + srv, err := NewServer() + require.NoError(t, err) + { + err = srv.Configure() + require.NoError(t, err) + + err = srv.Build() + require.NoError(t, err) + + var svcWG sync.WaitGroup + errPipe := make(chan error, 5) + + startFunc := func() { + err := srv.svc.Run() + errPipe <- err + svcWG.Done() + } + + stopFunc := func() { + srv.svc.Stop() + svcWG.Wait() + err = <-errPipe + require.NoError(t, err) + } + defer stopFunc() + + svcWG.Add(1) + go startFunc() + time.Sleep(1 * time.Second) + } + + { + cli := client.NewClient() + + ctx := context.Background() + ctx, _ = context.WithTimeout(ctx, 1*time.Second) + + helloRes, err := cli.ServiceHello(ctx, "127.0.0.1:1025/hello") + require.NoError(t, err) + require.True(t, helloRes) + } +} diff --git a/app/service/service.go b/app/service/service.go index a5c5e65..b5793c0 100644 --- a/app/service/service.go +++ b/app/service/service.go @@ -2,6 +2,7 @@ package service import ( "context" + "crypto/tls" "fmt" "net" "net/http" @@ -16,8 +17,8 @@ const protocol = "tcp" type ServiceParams struct { Handler *handler.Handler - X509Cert []byte - X509Key []byte + X509Cert string + X509Key string Portnum int64 Address string } @@ -40,10 +41,10 @@ func NewService(params *ServiceParams) (*Service, error) { var err error svc := &Service{ hand: params.Handler, - x509cert: conf.X509Cert, - x509key: conf.X509Key, - portnum: conf.Portnum, - address: conf.Address, + x509cert: []byte(params.X509Cert), + x509key: []byte(params.X509Key), + portnum: params.Portnum, + address: params.Address, } svc.logg = logger.NewLogger("service") return svc, err @@ -81,23 +82,19 @@ func (svc *Service) Build() error { } listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) - svc.listen, err = tls.Listen(svc.protocol, listenAddress, &tlsConfig) + svc.listen, err = tls.Listen(protocol, listenAddress, &tlsConfig) if err != nil { return err } } else { listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) - svc.listen, err = net.Listen(svc.protocol, listenAddress) + svc.listen, err = net.Listen(protocol, listenAddress) if err != nil { return err } } - //listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) - //svc.listen, err = net.Listen(protocol, listenAddress) - - svc.log.Infof("Service listening at %v", svc.listen.Addr()) - + svc.logg.Infof("Service listening at %v", svc.listen.Addr()) svc.hsrv = &http.Server{ Handler: svc.rout, } @@ -108,6 +105,10 @@ func (svc *Service) Run() error { var err error svc.logg.Infof("Service run") err = svc.hsrv.Serve(svc.listen) + if err == http.ErrServerClosed { + svc.logg.Warningf("Service Closed") + err = nil + } if err != nil { return err } @@ -115,10 +116,14 @@ func (svc *Service) Run() error { } func (svc *Service) Stop() { - svc.logg.Infof("Service stop") if svc.hsrv != nil { - downWaiting := 5 * time.Second - ctx, _ := context.WithTimeout(context.Background(), downWaiting) - svc.hsrv.Shutdown(ctx) + svc.logg.Infof("Service stop") + downWaiting := 10 * time.Second + ctx, cancel := context.WithTimeout(context.Background(), downWaiting) + defer cancel() + err := svc.hsrv.Shutdown(ctx) + if err != nil { + svc.logg.Errorf("Error service shutdown: %v", err) + } } } diff --git a/pkg/client/client.go b/pkg/client/client.go index d555834..a5cd061 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -15,6 +15,7 @@ import ( ) const fileAPI = "/v3/api/file/" +const serviceAPI = "/v3/api/service/" type Client struct{} @@ -22,6 +23,38 @@ func NewClient() *Client { return &Client{} } +func (cli *Client) ServiceHello(ctx context.Context, ref string) (bool, error) { + var res bool + var err error + + ref, err = convertServiceLink(ref) + if err != nil { + return res, err + } + req, err := http.NewRequestWithContext(ctx, "GET", ref, nil) + if err != nil { + return res, err + } + + transport := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + client := &http.Client{ + Transport: transport, + } + resp, err := client.Do(req) + if err != nil { + return res, err + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + res = true + } + return res, err +} + func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) { var res bool var err error @@ -34,7 +67,6 @@ func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) { if err != nil { return res, err } - authValue := createBasicAuthPair transport := &http.Transport{ TLSClientConfig: &tls.Config{ @@ -76,6 +108,22 @@ func convertFileLink(ref string) (string, error) { return res, err } +func convertServiceLink(ref string) (string, error) { + var err error + var res string + if !strings.Contains(ref, "://") { + ref = "https://" + ref + } + url, err := url.Parse(ref) + if err != nil { + return res, err + } + url.Path = path.Join(serviceAPI, url.Path) + url.User = nil + res = url.String() + return res, err +} + func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { var err error ref, err = convertFileLink(ref)