package extension import ( "context" "git.perx.ru/perxis/perxis-go/pkg/actionurl" "git.perx.ru/perxis/perxis-go/pkg/errors" pb "git.perx.ru/perxis/perxis-go/proto/extensions" ) type Server struct { services map[string]Extension pb.UnimplementedExtensionServer } func NewServer(svc ...Extension) *Server { srv := &Server{ services: make(map[string]Extension, len(svc)), } for _, s := range svc { srv.services[s.GetDescriptor().Extension] = s } return srv } func getResult(ext string, err error) *RequestResult { res := new(RequestResult) res.Extension = ext res.State = RequestOK if err != nil { res.State = RequestError res.Error = err.Error() errs := errors.GetErrors(err) if errs == nil { errs = append(errs, err) } for _, e := range errs { res.Msg += errors.GetDetail(e) + "\n" } } return res } func (srv *Server) getResults(extensions []string, fn func(svc Extension) error) []*RequestResult { var results []*RequestResult for _, e := range extensions { svc, ok := srv.services[e] if !ok { results = append(results, getResult(e, ErrUnknownExtension)) continue } err := fn(svc) results = append(results, getResult(e, err)) } return results } func (srv *Server) Install(ctx context.Context, request *InstallRequest) (*InstallResponse, error) { res := srv.getResults(request.Extensions, func(svc Extension) error { return svc.Install(ctx, request) }) return &InstallResponse{Results: res}, nil } func (srv *Server) Check(ctx context.Context, request *CheckRequest) (*CheckResponse, error) { res := srv.getResults(request.Extensions, func(svc Extension) error { return svc.Check(ctx, request) }) return &CheckResponse{Results: res}, nil } func (srv *Server) Uninstall(ctx context.Context, request *UninstallRequest) (*UninstallResponse, error) { res := srv.getResults(request.Extensions, func(svc Extension) error { return svc.Uninstall(ctx, request) }) return &UninstallResponse{Results: res}, nil } func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateResponse, error) { res := srv.getResults(request.Extensions, func(svc Extension) error { return svc.Update(ctx, request) }) return &UpdateResponse{Results: res}, nil } func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) { ext := in.Extension if ext == "" { actionURL, err := actionurl.New(in.Action) if err != nil { return nil, err } ext = actionURL.Extension() } svc, ok := srv.services[ext] if !ok { return nil, ErrUnknownExtension } out, err := svc.Action(ctx, in) if out == nil { out = &ActionResponse{} } if err != nil { out.State = ResponseError out.Error = err.Error() out.Msg += errors.GetDetail(err) } return out, nil } func (srv *Server) Start() error { var errs []error for _, svc := range srv.services { if r, ok := svc.(Runnable); ok { if err := r.Start(); err != nil { errs = append(errs, err) } } } if len(errs) > 0 { return errors.WithErrors(ErrStart, errs...) } return nil } func (srv *Server) Stop() error { var errs []error for _, svc := range srv.services { if r, ok := svc.(Runnable); ok { if err := r.Stop(); err != nil { errs = append(errs, err) } } } if len(errs) > 0 { return errors.WithErrors(ErrStop, errs...) } return nil }