From 80708aa2578f3598fc8abd4d08e576947da22872 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Fri, 9 Mar 2018 17:28:43 +0100 Subject: [PATCH] Added api to list and reconnect a XDS-Server. Added following routes: /servers => list all known XDS-Server /servers/:id => get info of a XDS-Server /servers/:id/reconnect => force reconnection of a XDS-Server Signed-off-by: Sebastien Douheret --- lib/agent/apiv1-servers.go | 93 +++++++++++++++++++++++++++++++++++++++++++++ lib/agent/apiv1.go | 39 +++++++++++++++++-- lib/agent/xdsserver.go | 20 +++++++++- lib/xdsconfig/configfile.go | 1 + 4 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 lib/agent/apiv1-servers.go diff --git a/lib/agent/apiv1-servers.go b/lib/agent/apiv1-servers.go new file mode 100644 index 0000000..72c3a1b --- /dev/null +++ b/lib/agent/apiv1-servers.go @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author Sebastien Douheret + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package agent + +import ( + "net/http" + "time" + + "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent/lib/xaapiv1" + common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib" + "github.com/gin-gonic/gin" +) + +// getServersList Return the list of XDS Servers +func (s *APIService) getServersList(c *gin.Context) { + confMut.Lock() + defer confMut.Unlock() + + svrList := []xaapiv1.ServerCfg{} + for _, svr := range s.xdsServers { + svrList = append(svrList, svr.GetConfig()) + } + + c.JSON(http.StatusOK, svrList) +} + +// getServer Return info of a XDS Servers +func (s *APIService) getServer(c *gin.Context) { + + id := s.ParamGetIndex(c) + if id == "" { + common.APIError(c, "invalid parameter, id must be set") + return + } + + confMut.Lock() + defer confMut.Unlock() + + svr := s.GetXdsServerFromURLIndex(id) + if svr == nil { + common.APIError(c, "unknown id") + return + } + + c.JSON(http.StatusOK, svr.GetConfig()) +} + +// reconnectServer Force reconnection of a XDS Server +func (s *APIService) reconnectServer(c *gin.Context) { + + id := s.ParamGetIndex(c) + if id == "" { + common.APIError(c, "invalid parameter, id must be set") + return + } + + svr := s.GetXdsServerFromURLIndex(id) + if svr == nil { + common.APIError(c, "unknown id") + return + } + + s.Log.Debugf("Reconnect XDS Server id %v", svr.ID) + + if err := svr.Close(); err != nil { + common.APIError(c, err.Error()) + return + } + + time.Sleep(time.Millisecond * 100) + + if err := svr.Connect(); err != nil { + common.APIError(c, err.Error()) + return + } + + c.JSON(http.StatusOK, svr.GetConfig()) +} diff --git a/lib/agent/apiv1.go b/lib/agent/apiv1.go index 3ca84b9..730e7c0 100644 --- a/lib/agent/apiv1.go +++ b/lib/agent/apiv1.go @@ -20,6 +20,7 @@ package agent import ( "fmt" "strconv" + "strings" "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent/lib/xaapiv1" "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent/lib/xdsconfig" @@ -99,12 +100,13 @@ func (s *APIService) AddXdsServer(cfg xdsconfig.XDSServerConf) (*XdsServer, erro } else { // Create a new server object + cfg.URLIndex = strconv.Itoa(s.serverIndex) + s.serverIndex = s.serverIndex + 1 if cfg.APIBaseURL == "" { cfg.APIBaseURL = apiBaseURL } if cfg.APIPartialURL == "" { - cfg.APIPartialURL = "/servers/" + strconv.Itoa(s.serverIndex) - s.serverIndex = s.serverIndex + 1 + cfg.APIPartialURL = "/servers/" + cfg.URLIndex } // Create a new XDS Server @@ -112,11 +114,16 @@ func (s *APIService) AddXdsServer(cfg xdsconfig.XDSServerConf) (*XdsServer, erro svr.SetLoggerOutput(s.Config.LogVerboseOut) - // Passthrough routes (handle by XDS Server) + // Define API group for this XDS Server grp := s.apiRouter.Group(svr.PartialURL) svr.SetAPIRouterGroup(grp) - // Declare passthrough routes + // Define servers API processed locally + s.apiRouter.GET("/servers", s.getServersList) // API /servers + svr.apiRouter.GET("", s.getServer) // API /servers/:id + svr.apiRouter.POST("/reconnect", s.reconnectServer) // API /servers/:id/reconnect + + // Declare passthrough API/routes s.sdksPassthroughInit(svr) s.targetsPassthroughInit(svr) @@ -179,3 +186,27 @@ func (s *APIService) UpdateXdsServer(cfg xaapiv1.ServerCfg) error { return nil } + +// GetXdsServerFromURLIndex Retrieve XdsServer from URLIndex value +func (s *APIService) GetXdsServerFromURLIndex(urlIdx string) *XdsServer { + for _, svr := range s.xdsServers { + if svr.URLIndex == urlIdx { + return svr + } + } + return nil +} + +// ParamGetIndex Retrieve numerical parameter in request url +func (s *APIService) ParamGetIndex(c *gin.Context) string { + uri := c.Request.RequestURI + for idx := strings.LastIndex(uri, "/"); idx > 0; { + id := uri[idx+1:] + if _, err := strconv.Atoi(id); err == nil { + return id + } + uri = uri[:idx] + idx = strings.LastIndex(uri, "/") + } + return "" +} diff --git a/lib/agent/xdsserver.go b/lib/agent/xdsserver.go index c08bfb1..f74e3ba 100644 --- a/lib/agent/xdsserver.go +++ b/lib/agent/xdsserver.go @@ -39,6 +39,7 @@ import ( type XdsServer struct { *Context ID string + URLIndex string BaseURL string APIURL string PartialURL string @@ -83,6 +84,7 @@ func NewXdsServer(ctx *Context, conf xdsconfig.XDSServerConf) *XdsServer { return &XdsServer{ Context: ctx, ID: _IDTempoPrefix + uuid.NewV1().String(), + URLIndex: conf.URLIndex, BaseURL: conf.URL, APIURL: conf.APIBaseURL + conf.APIPartialURL, PartialURL: conf.APIPartialURL, @@ -155,6 +157,19 @@ func (xs *XdsServer) SetLoggerOutput(out io.Writer) { xs.logOut = out } +// GetConfig +func (xs *XdsServer) GetConfig() xaapiv1.ServerCfg { + return xaapiv1.ServerCfg{ + ID: xs.ID, + URL: xs.BaseURL, + APIURL: xs.APIURL, + PartialURL: xs.PartialURL, + ConnRetry: xs.ConnRetry, + Connected: xs.Connected, + Disabled: xs.Disabled, + } +} + // SendCommand Send a command to XDS Server func (xs *XdsServer) SendCommand(cmd string, body []byte, res interface{}) error { url := cmd @@ -303,6 +318,7 @@ func (xs *XdsServer) PassthroughPost(url string) { xs._Disconnected() } common.APIError(c, err.Error()) + return }) } @@ -353,6 +369,7 @@ func (xs *XdsServer) PassthroughPut(url string) { xs._Disconnected() } common.APIError(c, err.Error()) + return }) } @@ -396,6 +413,7 @@ func (xs *XdsServer) PassthroughDelete(url string) { xs._Disconnected() } common.APIError(c, err.Error()) + return }) } @@ -683,7 +701,7 @@ func (xs *XdsServer) _SocketConnect() error { }) iosk.On("disconnection", func(err error) { - xs.Log.Infof("IO.socket disconnection server %s", xs.ID) + xs.Log.Infof("IO.socket disconnection server %s (APIURL %s)", xs.ID, xs.APIURL) if xs.CBOnDisconnect != nil { xs.CBOnDisconnect(err) } diff --git a/lib/xdsconfig/configfile.go b/lib/xdsconfig/configfile.go index 27456e7..009517f 100644 --- a/lib/xdsconfig/configfile.go +++ b/lib/xdsconfig/configfile.go @@ -38,6 +38,7 @@ type XDSServerConf struct { // private/not exported fields ID string `json:"-"` + URLIndex string `json:"-"` APIBaseURL string `json:"-"` APIPartialURL string `json:"-"` } -- 2.16.6