Added api to list and reconnect a XDS-Server.
authorSebastien Douheret <sebastien.douheret@iot.bzh>
Fri, 9 Mar 2018 16:28:43 +0000 (17:28 +0100)
committerSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 13 Mar 2018 11:39:57 +0000 (12:39 +0100)
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 <sebastien.douheret@iot.bzh>
lib/agent/apiv1-servers.go [new file with mode: 0644]
lib/agent/apiv1.go
lib/agent/xdsserver.go
lib/xdsconfig/configfile.go

diff --git a/lib/agent/apiv1-servers.go b/lib/agent/apiv1-servers.go
new file mode 100644 (file)
index 0000000..72c3a1b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * 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())
+}
index 3ca84b9..730e7c0 100644 (file)
@@ -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 ""
+}
index c08bfb1..f74e3ba 100644 (file)
@@ -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)
                }
index 27456e7..009517f 100644 (file)
@@ -38,6 +38,7 @@ type XDSServerConf struct {
 
        // private/not exported fields
        ID            string `json:"-"`
+       URLIndex      string `json:"-"`
        APIBaseURL    string `json:"-"`
        APIPartialURL string `json:"-"`
 }