package auth import ( "context" "fmt" "sync" "git.loafle.net/commons/configuration-go" cdr "git.loafle.net/commons/di-go/registry" logging "git.loafle.net/commons/logging-go" occi "git.loafle.net/overflow/commons-go/core/interfaces" ocnc "git.loafle.net/overflow/commons-go/noauthprobe/config" "git.loafle.net/overflow/probe/auth/annotation" "git.loafle.net/overflow/probe/auth/service" "git.loafle.net/overflow/probe/config" ) type Authenticator struct { authConfig ocnc.Auth services []interface{} endChan chan error stopChan chan struct{} stopWg sync.WaitGroup } func (a *Authenticator) EndableStart() (<-chan error, error) { if a.stopChan != nil { return nil, fmt.Errorf("already running. Stop it before starting it again") } conf := configuration.New() if configuration.Exists(config.NoAuthProbeConfigFilePath()) { if err := conf.Load(&a.authConfig, config.NoAuthProbeConfigFilePath()); nil != err { logging.Logger().Errorf("%s %v", err) return nil, fmt.Errorf("loading of auth config file[%s] failed", config.NoAuthProbeConfigFilePath()) } } if nil != a.authConfig.DeniedDate { return nil, fmt.Errorf("cannot start because this probe have been denied from overFlow at %s", a.authConfig.DeniedDate.String()) } cdr.RegisterResource("AuthConfig", &a.authConfig) authDoneChan := make(chan error) cdr.RegisterResource("AuthDoneChan", authDoneChan) services, err := cdr.GetInstancesByAnnotationType(annotation.AuthRPCServiceAnnotationType) if nil != err { return nil, err } a.services = services if err := occi.ExecServices(a.services, occi.ServiceMethodInit, service.OrderedServices, false); nil != err { return nil, err } a.endChan = make(chan error) a.stopChan = make(chan struct{}) a.stopWg.Add(1) go a.handleAuthenticator(authDoneChan) return a.endChan, nil } func (a *Authenticator) Stop(ctx context.Context) error { if a.stopChan == nil { return nil } close(a.stopChan) a.stopWg.Wait() occi.ExecServices(a.services, occi.ServiceMethodDestroy, service.OrderedServices, true) a.stopChan = nil close(a.endChan) return nil } func (a *Authenticator) handleAuthenticator(authDoneChan chan error) { var err error defer func() { a.stopWg.Done() a.endChan <- err }() err = occi.ExecServices(a.services, occi.ServiceMethodStart, service.OrderedServices, false) if nil != err { return } LOOP: for { select { case err = <-authDoneChan: break LOOP case <-a.stopChan: break LOOP } } occi.ExecServices(a.services, occi.ServiceMethodStop, service.OrderedServices, true) }