diff --git a/edge-apis/clients.go b/edge-apis/clients.go index 1386ceb3..3d89cbe2 100644 --- a/edge-apis/clients.go +++ b/edge-apis/clients.go @@ -25,6 +25,7 @@ import ( "github.com/openziti/edge-api/rest_model" "github.com/pkg/errors" "net/url" + "sync/atomic" ) // ApiType is an interface constraint for generics. The underlying go-swagger types only have fields, which are @@ -40,13 +41,13 @@ type BaseClient[A ApiType] struct { API *A Components AuthInfoWriter runtime.ClientAuthInfoWriter - CurrentAPISessionDetail *rest_model.CurrentAPISessionDetail + CurrentAPISessionDetail atomic.Pointer[rest_model.CurrentAPISessionDetail] Credentials Credentials } // GetCurrentApiSession returns the ApiSession that is being used to authenticate requests. func (self *BaseClient[A]) GetCurrentApiSession() *rest_model.CurrentAPISessionDetail { - return self.CurrentAPISessionDetail + return self.CurrentAPISessionDetail.Load() } // Authenticate will attempt to use the provided credentials to authenticate via the underlying ApiType. On success @@ -58,7 +59,7 @@ func (self *BaseClient[A]) Authenticate(credentials Credentials, configTypes []s myAny := any(self.API) if a, ok := myAny.(AuthEnabledApi); ok { self.Credentials = nil - self.CurrentAPISessionDetail = nil + self.CurrentAPISessionDetail.Store(nil) if credCaPool := credentials.GetCaPool(); credCaPool != nil { self.HttpTransport.TLSClientConfig.RootCAs = credCaPool @@ -73,11 +74,11 @@ func (self *BaseClient[A]) Authenticate(credentials Credentials, configTypes []s } self.Credentials = credentials - self.CurrentAPISessionDetail = apiSession + self.CurrentAPISessionDetail.Store(apiSession) self.Runtime.DefaultAuthentication = runtime.ClientAuthInfoWriterFunc(func(request runtime.ClientRequest, registry strfmt.Registry) error { - if self.CurrentAPISessionDetail != nil && self.CurrentAPISessionDetail.Token != nil && *self.CurrentAPISessionDetail.Token != "" { - if err := request.SetHeaderParam("zt-session", *self.CurrentAPISessionDetail.Token); err != nil { + if currentSession := self.CurrentAPISessionDetail.Load(); currentSession != nil && currentSession.Token != nil && *currentSession.Token != "" { + if err := request.SetHeaderParam("zt-session", *currentSession.Token); err != nil { return err } } diff --git a/example/go.mod b/example/go.mod index 863495f5..6d23814d 100644 --- a/example/go.mod +++ b/example/go.mod @@ -76,7 +76,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openziti/channel/v2 v2.0.98 // indirect - github.com/openziti/edge-api v0.25.33 // indirect + github.com/openziti/edge-api v0.25.35 // indirect github.com/openziti/identity v1.0.62 // indirect github.com/openziti/metrics v1.2.34 // indirect github.com/openziti/secretstream v0.1.11 // indirect @@ -88,7 +88,7 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rs/cors v1.8.3 // indirect - github.com/shirou/gopsutil/v3 v3.23.7 // indirect + github.com/shirou/gopsutil/v3 v3.23.8 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/speps/go-hashids v2.0.0+incompatible // indirect github.com/spf13/afero v1.6.0 // indirect @@ -96,8 +96,8 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect diff --git a/example/go.sum b/example/go.sum index 0ca380eb..14ee9223 100644 --- a/example/go.sum +++ b/example/go.sum @@ -436,6 +436,7 @@ github.com/openziti/channel/v2 v2.0.98 h1:57mfdzsdvuH0NtZJJZ2go4q0860kpB5s3nDS6Q github.com/openziti/channel/v2 v2.0.98/go.mod h1:gvLNJgNOs07xPOwipNhWmL67/w/SugqNSpBkgojj+aQ= github.com/openziti/edge-api v0.25.33 h1:5XaQvUKeG8ZZ3WLhr/8xqZn56p53ZxWmFooR6I/xrvQ= github.com/openziti/edge-api v0.25.33/go.mod h1:T+g7OHoj2KQi3SrSdgbbFoQdknLrehEIlZRGxpTYObI= +github.com/openziti/edge-api v0.25.35/go.mod h1:WXTX3HwsfikNC6KQexxLP7jk3SiFxiPuuRi9rLkr9do= github.com/openziti/foundation/v2 v2.0.31 h1:Hu8z3AIkQUSY/ADG8NkUxORwUBMeH0H7h60MuHkXtYI= github.com/openziti/foundation/v2 v2.0.31/go.mod h1:KCQatGmkVDIZnfSLrohKwmQi7kg7vnECpNTkpuLNguc= github.com/openziti/identity v1.0.62 h1:DJwqpL7UheD/SuNw2ZllXPkYcEhBA8bz+kgs0cI8yEE= @@ -488,6 +489,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -542,8 +544,10 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -799,7 +803,9 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/example/influxdb-client-go/go.mod b/example/influxdb-client-go/go.mod index b23b82a4..69bf15eb 100644 --- a/example/influxdb-client-go/go.mod +++ b/example/influxdb-client-go/go.mod @@ -49,7 +49,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openziti/channel/v2 v2.0.98 // indirect - github.com/openziti/edge-api v0.25.33 // indirect + github.com/openziti/edge-api v0.25.35 // indirect github.com/openziti/foundation/v2 v2.0.31 // indirect github.com/openziti/identity v1.0.62 // indirect github.com/openziti/metrics v1.2.34 // indirect @@ -60,11 +60,11 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/shirou/gopsutil/v3 v3.23.7 // indirect + github.com/shirou/gopsutil/v3 v3.23.8 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/speps/go-hashids v2.0.0+incompatible // indirect - github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.mongodb.org/mongo-driver v1.12.1 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect diff --git a/example/influxdb-client-go/go.sum b/example/influxdb-client-go/go.sum index 3a92dfaf..eb6142ed 100644 --- a/example/influxdb-client-go/go.sum +++ b/example/influxdb-client-go/go.sum @@ -395,6 +395,7 @@ github.com/openziti/channel/v2 v2.0.98 h1:57mfdzsdvuH0NtZJJZ2go4q0860kpB5s3nDS6Q github.com/openziti/channel/v2 v2.0.98/go.mod h1:gvLNJgNOs07xPOwipNhWmL67/w/SugqNSpBkgojj+aQ= github.com/openziti/edge-api v0.25.33 h1:5XaQvUKeG8ZZ3WLhr/8xqZn56p53ZxWmFooR6I/xrvQ= github.com/openziti/edge-api v0.25.33/go.mod h1:T+g7OHoj2KQi3SrSdgbbFoQdknLrehEIlZRGxpTYObI= +github.com/openziti/edge-api v0.25.35/go.mod h1:WXTX3HwsfikNC6KQexxLP7jk3SiFxiPuuRi9rLkr9do= github.com/openziti/foundation/v2 v2.0.31 h1:Hu8z3AIkQUSY/ADG8NkUxORwUBMeH0H7h60MuHkXtYI= github.com/openziti/foundation/v2 v2.0.31/go.mod h1:KCQatGmkVDIZnfSLrohKwmQi7kg7vnECpNTkpuLNguc= github.com/openziti/identity v1.0.62 h1:DJwqpL7UheD/SuNw2ZllXPkYcEhBA8bz+kgs0cI8yEE= @@ -436,6 +437,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -478,8 +480,10 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -724,7 +728,9 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= diff --git a/ziti/client.go b/ziti/client.go index 94af4414..52643a56 100644 --- a/ziti/client.go +++ b/ziti/client.go @@ -78,7 +78,7 @@ func (self *CtrlClient) Refresh() (*time.Time, error) { return nil, rest_util.WrapErr(err) } - self.CurrentAPISessionDetail = resp.Payload.Data + self.CurrentAPISessionDetail.Store(resp.Payload.Data) expiresAt := time.Time(*resp.Payload.Data.ExpiresAt) return &expiresAt, nil diff --git a/ziti/ziti.go b/ziti/ziti.go index 9668b472..93c7be17 100644 --- a/ziti/ziti.go +++ b/ziti/ziti.go @@ -639,24 +639,25 @@ func (context *ContextImpl) runSessionRefresh() { svcUpdateTick := time.NewTicker(context.options.RefreshInterval) defer svcUpdateTick.Stop() - expireTime := time.Time(*context.CtrlClt.GetCurrentApiSession().ExpiresAt) - sleepDuration := time.Until(expireTime) - (10 * time.Second) + refreshAt := time.Now().Add(30 * time.Second) + if currentApiSession := context.CtrlClt.GetCurrentApiSession(); currentApiSession != nil && currentApiSession.ExpiresAt != nil { + refreshAt = time.Time(*currentApiSession.ExpiresAt).Add(-10 * time.Second) + } for { select { case <-context.closeNotify: return - case <-time.After(sleepDuration): + case <-time.After(time.Until(refreshAt)): exp, err := context.CtrlClt.Refresh() if err != nil { log.Errorf("could not refresh apiSession: %v", err) - sleepDuration = 5 * time.Second + refreshAt = time.Now().Add(5 * time.Second) } else { - expireTime = *exp - sleepDuration = time.Until(expireTime) - (10 * time.Second) - log.Debugf("apiSession refreshed, new expiration[%s]", expireTime) + refreshAt = exp.Add(-10 * time.Second) + log.Debugf("apiSession refreshed, new expiration[%s]", *exp) } case <-svcUpdateTick.C: @@ -696,10 +697,9 @@ func (context *ContextImpl) GetCurrentIdentity() (*rest_model.IdentityDetail, er } func (context *ContextImpl) setUnauthenticated() { - willEmit := context.CtrlClt.CurrentAPISessionDetail != nil - prevApiSession := context.CtrlClt.CurrentAPISessionDetail + prevApiSession := context.CtrlClt.CurrentAPISessionDetail.Swap(nil) + willEmit := prevApiSession != nil - context.CtrlClt.CurrentAPISessionDetail = nil context.CtrlClt.ApiSessionCertificate = nil context.CloseAllEdgeRouterConns() @@ -734,11 +734,11 @@ func (context *ContextImpl) authenticate() error { return nil } - return context.onFullAuth() + return context.onFullAuth(apiSession) } func (context *ContextImpl) Reauthenticate() error { - context.CtrlClt.CurrentAPISessionDetail = nil + context.CtrlClt.CurrentAPISessionDetail.Store(nil) context.CtrlClt.ApiSessionCertificate = nil return context.authenticate() @@ -771,7 +771,7 @@ func (context *ContextImpl) CloseAllEdgeRouterConns() { } } -func (context *ContextImpl) onFullAuth() error { +func (context *ContextImpl) onFullAuth(apiSession *rest_model.CurrentAPISessionDetail) error { var doOnceErr error context.firstAuthOnce.Do(func() { if context.options.OnContextReady != nil { @@ -780,13 +780,13 @@ func (context *ContextImpl) onFullAuth() error { go context.runSessionRefresh() metricsTags := map[string]string{ - "srcId": context.CtrlClt.GetCurrentApiSession().Identity.ID, + "srcId": apiSession.Identity.ID, } - context.metrics = metrics.NewRegistry(context.CtrlClt.GetCurrentApiSession().Identity.Name, metricsTags) + context.metrics = metrics.NewRegistry(apiSession.Identity.Name, metricsTags) }) - context.Emit(EventAuthenticationStateFull, context.CtrlClt.GetCurrentApiSession()) + context.Emit(EventAuthenticationStateFull, apiSession) // get services if err := context.RefreshServices(); err != nil { @@ -809,8 +809,8 @@ func (context *ContextImpl) authenticateMfa(code string) error { return err } - if context.CtrlClt.CurrentAPISessionDetail != nil && len(context.CtrlClt.CurrentAPISessionDetail.AuthQueries) == 0 { - return context.onFullAuth() + if currentApiSession := context.CtrlClt.GetCurrentApiSession(); currentApiSession != nil && len(currentApiSession.AuthQueries) == 0 { + return context.onFullAuth(currentApiSession) } return nil @@ -1125,7 +1125,13 @@ func (context *ContextImpl) connectEdgeRouter(routerName, ingressUrl string, ret return } - pfxlog.Logger().Debugf("connection to edge router using api session token %v", *context.CtrlClt.GetCurrentApiSession().Token) + currentApiSession := context.CtrlClt.GetCurrentApiSession() + if currentApiSession == nil { + retF(&edgeRouterConnResult{routerUrl: ingressUrl, err: errors.New("not authenticated to controller")}) + return + } + + pfxlog.Logger().Debugf("connection to edge router using api session token %v", *currentApiSession.Token) id, err := context.CtrlClt.GetIdentity() if err != nil { @@ -1133,7 +1139,7 @@ func (context *ContextImpl) connectEdgeRouter(routerName, ingressUrl string, ret } dialer := channel.NewClassicDialer(identity.NewIdentity(id), ingAddr, map[int32][]byte{ - edge.SessionTokenHeader: []byte(*context.CtrlClt.GetCurrentApiSession().Token), + edge.SessionTokenHeader: []byte(*currentApiSession.Token), }) start := time.Now().UnixNano() @@ -1288,6 +1294,16 @@ func (context *ContextImpl) createSessionWithBackoff(service *rest_model.Service var session *rest_model.SessionDetail operation := func() error { + latestSvc, _ := context.services.Get(*service.Name) + if latestSvc != nil && *latestSvc.ID != *service.ID { + pfxlog.Logger(). + WithField("serviceName", *service.Name). + WithField("oldServiceId", *service.ID). + WithField("newServiceId", *latestSvc.ID). + Info("service id changed, service was recreated") + service = latestSvc + } + s, err := context.createSession(service, sessionType) if err != nil { return err @@ -1321,6 +1337,14 @@ func (context *ContextImpl) createSession(service *rest_model.ServiceDetail, ses return nil, err } } + + target = &rest_session.CreateSessionNotFound{} + if errors.As(err, &target) { + if refreshErr := context.refreshServices(false); refreshErr != nil { + logger.WithError(refreshErr).Info("failed to refresh services after create session returned 404 (likely for service)") + } + } + return nil, err } elapsed := time.Since(start) @@ -1614,6 +1638,16 @@ func (mgr *listenerManager) refreshSession() { } func (mgr *listenerManager) createSessionWithBackoff() { + latestSvc, _ := mgr.context.services.Get(*mgr.service.Name) + if latestSvc != nil && *latestSvc.ID != *mgr.service.ID { + pfxlog.Logger(). + WithField("serviceName", *mgr.service.Name). + WithField("oldServiceId", *mgr.service.ID). + WithField("newServiceId", *latestSvc.ID). + Info("service id changed, service was recreated") + mgr.service = latestSvc + } + session, err := mgr.context.createSessionWithBackoff(mgr.service, SessionType(SessionBind), mgr.options) if session != nil { mgr.session = session