Moved all structs exposed by API into apiv1 package
authorSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 31 Oct 2017 17:09:45 +0000 (18:09 +0100)
committerSebastien Douheret <sebastien.douheret@iot.bzh>
Mon, 6 Nov 2017 09:18:00 +0000 (10:18 +0100)
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
22 files changed:
.vscode/settings.json
lib/agent/apiv1-config.go
lib/agent/apiv1-events.go
lib/agent/apiv1-exec.go
lib/agent/apiv1-projects.go
lib/agent/apiv1-sdks.go [new file with mode: 0644]
lib/agent/apiv1-version.go
lib/agent/apiv1.go
lib/agent/events.go
lib/agent/project-interface.go
lib/agent/project-pathmap.go
lib/agent/project-st.go
lib/agent/projects.go
lib/agent/sessions.go [moved from lib/agent/session.go with 99% similarity]
lib/agent/webserver.go
lib/agent/xdsserver.go
lib/apiv1/config.go [new file with mode: 0644]
lib/apiv1/events.go [new file with mode: 0644]
lib/apiv1/exec.go [new file with mode: 0644]
lib/apiv1/projects.go [new file with mode: 0644]
lib/apiv1/sdks.go [new file with mode: 0644]
lib/apiv1/version.go [new file with mode: 0644]

index eceb734..eafbcfa 100644 (file)
@@ -54,6 +54,7 @@
     "prjs",
     "iosk",
     "CIFS",
-    "IPROJECT"
+    "IPROJECT",
+    "unregister"
   ]
 }
index 31d8de6..2197720 100644 (file)
@@ -5,33 +5,13 @@ import (
        "sync"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        "github.com/iotbzh/xds-agent/lib/xdsconfig"
        common "github.com/iotbzh/xds-common/golib"
 )
 
 var confMut sync.Mutex
 
-// APIConfig parameters (json format) of /config command
-type APIConfig struct {
-       Servers []ServerCfg `json:"servers"`
-
-       // Not exposed outside in JSON
-       Version       string `json:"-"`
-       APIVersion    string `json:"-"`
-       VersionGitTag string `json:"-"`
-}
-
-// ServerCfg .
-type ServerCfg struct {
-       ID         string `json:"id"`
-       URL        string `json:"url"`
-       APIURL     string `json:"apiUrl"`
-       PartialURL string `json:"partialUrl"`
-       ConnRetry  int    `json:"connRetry"`
-       Connected  bool   `json:"connected"`
-       Disabled   bool   `json:"disabled"`
-}
-
 // GetConfig returns the configuration
 func (s *APIService) getConfig(c *gin.Context) {
        confMut.Lock()
@@ -44,7 +24,7 @@ func (s *APIService) getConfig(c *gin.Context) {
 
 // SetConfig sets configuration
 func (s *APIService) setConfig(c *gin.Context) {
-       var cfgArg APIConfig
+       var cfgArg apiv1.APIConfig
        if c.BindJSON(&cfgArg) != nil {
                common.APIError(c, "Invalid arguments")
                return
@@ -85,16 +65,16 @@ func (s *APIService) setConfig(c *gin.Context) {
        c.JSON(http.StatusOK, s._getConfig())
 }
 
-func (s *APIService) _getConfig() APIConfig {
-       cfg := APIConfig{
+func (s *APIService) _getConfig() apiv1.APIConfig {
+       cfg := apiv1.APIConfig{
                Version:       s.Config.Version,
                APIVersion:    s.Config.APIVersion,
                VersionGitTag: s.Config.VersionGitTag,
-               Servers:       []ServerCfg{},
+               Servers:       []apiv1.ServerCfg{},
        }
 
        for _, svr := range s.xdsServers {
-               cfg.Servers = append(cfg.Servers, ServerCfg{
+               cfg.Servers = append(cfg.Servers, apiv1.ServerCfg{
                        ID:         svr.ID,
                        URL:        svr.BaseURL,
                        APIURL:     svr.APIURL,
index 8aad18a..cb7cde1 100644 (file)
@@ -4,21 +4,10 @@ import (
        "net/http"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        common "github.com/iotbzh/xds-common/golib"
 )
 
-// EventRegisterArgs is the parameters (json format) of /events/register command
-type EventRegisterArgs struct {
-       Name      string `json:"name"`
-       ProjectID string `json:"filterProjectID"`
-}
-
-// EventUnRegisterArgs is the parameters (json format) of /events/unregister command
-type EventUnRegisterArgs struct {
-       Name string `json:"name"`
-       ID   int    `json:"id"`
-}
-
 // eventsList Registering for events that will be send over a WS
 func (s *APIService) eventsList(c *gin.Context) {
        c.JSON(http.StatusOK, s.events.GetList())
@@ -26,7 +15,7 @@ func (s *APIService) eventsList(c *gin.Context) {
 
 // eventsRegister Registering for events that will be send over a WS
 func (s *APIService) eventsRegister(c *gin.Context) {
-       var args EventRegisterArgs
+       var args apiv1.EventRegisterArgs
 
        if c.BindJSON(&args) != nil || args.Name == "" {
                common.APIError(c, "Invalid arguments")
@@ -50,7 +39,7 @@ func (s *APIService) eventsRegister(c *gin.Context) {
 
 // eventsRegister Registering for events that will be send over a WS
 func (s *APIService) eventsUnRegister(c *gin.Context) {
-       var args EventUnRegisterArgs
+       var args apiv1.EventUnRegisterArgs
 
        if c.BindJSON(&args) != nil || args.Name == "" {
                common.APIError(c, "Invalid arguments")
index 37070f7..9c65bc2 100644 (file)
@@ -6,16 +6,11 @@ import (
        "net/http"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        common "github.com/iotbzh/xds-common/golib"
        uuid "github.com/satori/go.uuid"
 )
 
-// ExecArgs Only define used fields
-type ExecArgs struct {
-       ID    string `json:"id" binding:"required"`
-       CmdID string `json:"cmdID"` // command unique ID
-}
-
 var execCmdID = 1
 
 // ExecCmd executes remotely a command
@@ -34,7 +29,7 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) {
                common.APIError(c, err.Error())
        }
 
-       args := ExecArgs{}
+       args := apiv1.ExecArgs{}
        // XXX - we cannot use c.BindJSON, so directly unmarshall it
        // (see https://github.com/gin-gonic/gin/issues/1078)
        if err := json.Unmarshal(data, &args); err != nil {
@@ -75,10 +70,10 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) {
        // Forward XDSServer WS events to client WS
        // TODO removed static event name list and get it from XDSServer
        evtList := []string{
-               "exec:input",
-               "exec:output",
-               "exec:inferior-input",
-               "exec:inferior-output",
+               apiv1.ExecInEvent,
+               apiv1.ExecOutEvent,
+               apiv1.ExecInferiorInEvent,
+               apiv1.ExecInferiorOutEvent,
        }
        so := *sock
        fwdFuncID := []uuid.UUID{}
@@ -99,15 +94,15 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) {
        // Handle Exit event separately to cleanup registered listener
        var exitFuncID uuid.UUID
        exitFunc := func(evData interface{}) {
-               so.Emit("exec:exit", evData)
+               so.Emit(apiv1.ExecExitEvent, evData)
 
                // cleanup listener
                for i, evName := range evtList {
                        svr.EventOff(evName, fwdFuncID[i])
                }
-               svr.EventOff("exec:exit", exitFuncID)
+               svr.EventOff(apiv1.ExecExitEvent, exitFuncID)
        }
-       exitFuncID, err = svr.EventOn("exec:exit", exitFunc)
+       exitFuncID, err = svr.EventOn(apiv1.ExecExitEvent, exitFunc)
        if err != nil {
                common.APIError(c, err.Error())
                return
@@ -127,5 +122,4 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) {
                return
        }
        c.JSON(http.StatusOK, string(body))
-
 }
index d4b5e74..89218ab 100644 (file)
@@ -4,6 +4,7 @@ import (
        "net/http"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        common "github.com/iotbzh/xds-common/golib"
 )
 
@@ -25,7 +26,7 @@ func (s *APIService) getProject(c *gin.Context) {
 
 // addProject adds a new project to server config
 func (s *APIService) addProject(c *gin.Context) {
-       var cfgArg ProjectConfig
+       var cfgArg apiv1.ProjectConfig
        if c.BindJSON(&cfgArg) != nil {
                common.APIError(c, "Invalid arguments")
                return
diff --git a/lib/agent/apiv1-sdks.go b/lib/agent/apiv1-sdks.go
new file mode 100644 (file)
index 0000000..ee6409d
--- /dev/null
@@ -0,0 +1,9 @@
+package agent
+
+// sdksPassthroughInit Declare passthrough routes for sdks
+func (s *APIService) sdksPassthroughInit(svr *XdsServer) error {
+       svr.PassthroughGet("/sdks")
+       svr.PassthroughGet("/sdk/:id")
+
+       return nil
+}
index 6b4923f..c75e7f5 100644 (file)
@@ -4,25 +4,14 @@ import (
        "net/http"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        common "github.com/iotbzh/xds-common/golib"
 )
 
-type version struct {
-       ID            string `json:"id"`
-       Version       string `json:"version"`
-       APIVersion    string `json:"apiVersion"`
-       VersionGitTag string `json:"gitTag"`
-}
-
-type apiVersion struct {
-       Client version   `json:"client"`
-       Server []version `json:"servers"`
-}
-
 // getInfo : return various information about server
 func (s *APIService) getVersion(c *gin.Context) {
-       response := apiVersion{
-               Client: version{
+       response := apiv1.XDSVersion{
+               Client: apiv1.VersionData{
                        ID:            "",
                        Version:       s.Config.Version,
                        APIVersion:    s.Config.APIVersion,
@@ -30,9 +19,9 @@ func (s *APIService) getVersion(c *gin.Context) {
                },
        }
 
-       svrVer := []version{}
+       svrVer := []apiv1.VersionData{}
        for _, svr := range s.xdsServers {
-               res := version{}
+               res := apiv1.VersionData{}
                if err := svr.GetVersion(&res); err != nil {
                        common.APIError(c, "Cannot retrieve version of XDS server ID %s : %v", svr.ID, err.Error())
                        return
index 77b05ba..3fd9990 100644 (file)
@@ -95,8 +95,9 @@ func (s *APIService) AddXdsServer(cfg xdsconfig.XDSServerConf) (*XdsServer, erro
                // Passthrough routes (handle by XDS Server)
                grp := s.apiRouter.Group(svr.PartialURL)
                svr.SetAPIRouterGroup(grp)
-               svr.PassthroughGet("/sdks")
-               svr.PassthroughGet("/sdk/:id")
+
+               // Declare passthrough routes
+               s.sdksPassthroughInit(svr)
        }
 
        // Established connection
index e66f758..046c377 100644 (file)
@@ -3,39 +3,23 @@ package agent
 import (
        "fmt"
        "time"
-)
-
-// Events constants
-const (
-       // EventTypePrefix Used as event prefix
-       EventTypePrefix = "event:" // following by event type
 
-       // Supported Events type
-       EVTAll           = "all"
-       EVTServerConfig  = "server-config"        // data type ServerCfg
-       EVTProjectAdd    = "project-add"          // data type ProjectConfig
-       EVTProjectDelete = "project-delete"       // data type ProjectConfig
-       EVTProjectChange = "project-state-change" // data type ProjectConfig
+       "github.com/iotbzh/xds-agent/lib/apiv1"
 )
 
 var _EVTAllList = []string{
-       EVTServerConfig,
-       EVTProjectAdd,
-       EVTProjectDelete,
-       EVTProjectChange,
-}
-
-// EventMsg Message send
-type EventMsg struct {
-       Time string      `json:"time"`
-       Type string      `json:"type"`
-       Data interface{} `json:"data"`
+       apiv1.EVTServerConfig,
+       apiv1.EVTProjectAdd,
+       apiv1.EVTProjectDelete,
+       apiv1.EVTProjectChange,
 }
 
+// EventDef Definition on one event
 type EventDef struct {
        sids map[string]int
 }
 
+// Events Hold registered events per context
 type Events struct {
        *Context
        eventsMap map[string]*EventDef
@@ -63,7 +47,7 @@ func (e *Events) GetList() []string {
 // Register Used by a client/session to register to a specific (or all) event(s)
 func (e *Events) Register(evName, sessionID string) error {
        evs := _EVTAllList
-       if evName != EVTAll {
+       if evName != apiv1.EVTAll {
                if _, ok := e.eventsMap[evName]; !ok {
                        return fmt.Errorf("Unsupported event type name")
                }
@@ -78,7 +62,7 @@ func (e *Events) Register(evName, sessionID string) error {
 // UnRegister Used by a client/session to unregister event(s)
 func (e *Events) UnRegister(evName, sessionID string) error {
        evs := _EVTAllList
-       if evName != EVTAll {
+       if evName != apiv1.EVTAll {
                if _, ok := e.eventsMap[evName]; !ok {
                        return fmt.Errorf("Unsupported event type name")
                }
@@ -115,13 +99,13 @@ func (e *Events) Emit(evName string, data interface{}) error {
                        }
                        continue
                }
-               msg := EventMsg{
+               msg := apiv1.EventMsg{
                        Time: time.Now().String(),
                        Type: evName,
                        Data: data,
                }
-               if err := (*so).Emit(EventTypePrefix+evName, msg); err != nil {
-                       e.Log.Errorf("WS Emit %v error : %v", EventTypePrefix+evName, err)
+               if err := (*so).Emit(apiv1.EventTypePrefix+evName, msg); err != nil {
+                       e.Log.Errorf("WS Emit %v error : %v", apiv1.EventTypePrefix+evName, err)
                        if firstErr == nil {
                                firstErr = err
                        }
index 0a4a17e..c9e9ec5 100644 (file)
@@ -1,43 +1,14 @@
 package agent
 
-// ProjectType definition
-type ProjectType string
-
-const (
-       TypePathMap   = "PathMap"
-       TypeCloudSync = "CloudSync"
-       TypeCifsSmb   = "CIFS"
-)
-
-// Project Status definition
-const (
-       StatusErrorConfig = "ErrorConfig"
-       StatusDisable     = "Disable"
-       StatusEnable      = "Enable"
-       StatusPause       = "Pause"
-       StatusSyncing     = "Syncing"
-)
+import "github.com/iotbzh/xds-agent/lib/apiv1"
 
 // IPROJECT Project interface
 type IPROJECT interface {
-       Add(cfg ProjectConfig) (*ProjectConfig, error)           // Add a new project
-       Delete() error                                           // Delete a project
-       GetProject() *ProjectConfig                              // Get project public configuration
-       UpdateProject(prj ProjectConfig) (*ProjectConfig, error) // Update project configuration
-       GetServer() *XdsServer                                   // Get XdsServer that holds this project
-       Sync() error                                             // Force project files synchronization
-       IsInSync() (bool, error)                                 // Check if project files are in-sync
-}
-
-// ProjectConfig is the config for one project
-type ProjectConfig struct {
-       ID         string      `json:"id"`
-       ServerID   string      `json:"serverId"`
-       Label      string      `json:"label"`
-       ClientPath string      `json:"clientPath"`
-       ServerPath string      `json:"serverPath"`
-       Type       ProjectType `json:"type"`
-       Status     string      `json:"status"`
-       IsInSync   bool        `json:"isInSync"`
-       DefaultSdk string      `json:"defaultSdk"`
+       Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error)           // Add a new project
+       Delete() error                                                             // Delete a project
+       GetProject() *apiv1.ProjectConfig                                       // Get project public configuration
+       UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) // Update project configuration
+       GetServer() *XdsServer                                                     // Get XdsServer that holds this project
+       Sync() error                                                               // Force project files synchronization
+       IsInSync() (bool, error)                                                   // Check if project files are in-sync
 }
index aacbd1f..7a96e6e 100644 (file)
@@ -6,6 +6,7 @@ import (
        "os"
        "strings"
 
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        common "github.com/iotbzh/xds-common/golib"
 )
 
@@ -29,7 +30,7 @@ func NewProjectPathMap(ctx *Context, svr *XdsServer) *PathMap {
 }
 
 // Add a new project
-func (p *PathMap) Add(cfg ProjectConfig) (*ProjectConfig, error) {
+func (p *PathMap) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
        var err error
        var file *os.File
        errMsg := "ClientPath sanity check error (%d): %v"
@@ -91,17 +92,17 @@ func (p *PathMap) Delete() error {
 }
 
 // GetProject Get public part of project config
-func (p *PathMap) GetProject() *ProjectConfig {
+func (p *PathMap) GetProject() *apiv1.ProjectConfig {
        prj := p.server.FolderToProject(*p.folder)
        prj.ServerID = p.server.ID
        return &prj
 }
 
 // UpdateProject Set project config
-func (p *PathMap) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) {
+func (p *PathMap) UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
        p.folder = p.server.ProjectToFolder(prj)
        np := p.GetProject()
-       if err := p.events.Emit(EVTProjectChange, np); err != nil {
+       if err := p.events.Emit(apiv1.EVTProjectChange, np); err != nil {
                return np, err
        }
        return np, nil
index c0d2550..dba5978 100644 (file)
@@ -1,6 +1,7 @@
 package agent
 
 import (
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        st "github.com/iotbzh/xds-agent/lib/syncthing"
 )
 
@@ -25,7 +26,7 @@ func NewProjectST(ctx *Context, svr *XdsServer) *STProject {
 }
 
 // Add a new project
-func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) {
+func (p *STProject) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
        var err error
 
        // Add project/folder into XDS Server
@@ -48,7 +49,7 @@ func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) {
 
        locPrj, err := p.SThg.FolderConfigGet(id)
        if err != nil {
-               svrPrj.Status = StatusErrorConfig
+               svrPrj.Status = apiv1.StatusErrorConfig
                return nil, err
        }
        if svrPrj.ID != locPrj.ID {
@@ -70,14 +71,14 @@ func (p *STProject) Delete() error {
 }
 
 // GetProject Get public part of project config
-func (p *STProject) GetProject() *ProjectConfig {
+func (p *STProject) GetProject() *apiv1.ProjectConfig {
        prj := p.server.FolderToProject(*p.folder)
        prj.ServerID = p.server.ID
        return &prj
 }
 
 // UpdateProject Update project config
-func (p *STProject) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) {
+func (p *STProject) UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
        // Update folder
        p.folder = p.server.ProjectToFolder(prj)
        svrPrj := p.GetProject()
@@ -141,7 +142,7 @@ func (p *STProject) _cbServerFolderChanged(data interface{}) {
                p.folder.DataCloudSync.STSvrIsInSync = evt.Folder.IsInSync
                p.folder.DataCloudSync.STSvrStatus = evt.Folder.Status
 
-               if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
+               if err := p.events.Emit(apiv1.EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
                        p.Log.Warningf("Cannot notify project change: %v", err)
                }
        }
@@ -161,15 +162,15 @@ func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) {
                to := ev.Data["to"]
                switch to {
                case "scanning", "syncing":
-                       sts = StatusSyncing
+                       sts = apiv1.StatusSyncing
                case "idle":
-                       sts = StatusEnable
+                       sts = apiv1.StatusEnable
                }
                inSync = (to == "idle")
 
        case st.EventFolderPaused:
-               if sts == StatusEnable {
-                       sts = StatusPause
+               if sts == apiv1.StatusEnable {
+                       sts = apiv1.StatusPause
                }
                inSync = false
        }
@@ -179,7 +180,7 @@ func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) {
                p.folder.DataCloudSync.STLocIsInSync = inSync
                p.folder.DataCloudSync.STLocStatus = sts
 
-               if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
+               if err := p.events.Emit(apiv1.EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
                        p.Log.Warningf("Cannot notify project change: %v", err)
                }
        }
index 5e20395..6804d35 100644 (file)
@@ -5,6 +5,7 @@ import (
        "log"
        "time"
 
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        "github.com/iotbzh/xds-agent/lib/syncthing"
        "github.com/syncthing/syncthing/lib/sync"
 )
@@ -78,7 +79,7 @@ func (p *Projects) Get(id string) *IPROJECT {
 }
 
 // GetProjectArr returns the config of all folders as an array
-func (p *Projects) GetProjectArr() []ProjectConfig {
+func (p *Projects) GetProjectArr() []apiv1.ProjectConfig {
        pjMutex.Lock()
        defer pjMutex.Unlock()
 
@@ -86,8 +87,8 @@ func (p *Projects) GetProjectArr() []ProjectConfig {
 }
 
 // GetProjectArrUnsafe Same as GetProjectArr without mutex protection
-func (p *Projects) GetProjectArrUnsafe() []ProjectConfig {
-       conf := []ProjectConfig{}
+func (p *Projects) GetProjectArrUnsafe() []apiv1.ProjectConfig {
+       conf := []apiv1.ProjectConfig{}
        for _, v := range p.projects {
                prj := (*v).GetProject()
                conf = append(conf, *prj)
@@ -96,14 +97,14 @@ func (p *Projects) GetProjectArrUnsafe() []ProjectConfig {
 }
 
 // Add adds a new folder
-func (p *Projects) Add(newF ProjectConfig) (*ProjectConfig, error) {
+func (p *Projects) Add(newF apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
        prj, err := p.createUpdate(newF, true, false)
        if err != nil {
                return prj, err
        }
 
        // Notify client with event
-       if err := p.events.Emit(EVTProjectAdd, *prj); err != nil {
+       if err := p.events.Emit(apiv1.EVTProjectAdd, *prj); err != nil {
                p.Log.Warningf("Cannot notify project deletion: %v", err)
        }
 
@@ -111,7 +112,7 @@ func (p *Projects) Add(newF ProjectConfig) (*ProjectConfig, error) {
 }
 
 // CreateUpdate creates or update a folder
-func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (*ProjectConfig, error) {
+func (p *Projects) createUpdate(newF apiv1.ProjectConfig, create bool, initial bool) (*apiv1.ProjectConfig, error) {
        var err error
 
        pjMutex.Lock()
@@ -143,7 +144,7 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (
        var fld IPROJECT
        switch newF.Type {
        // SYNCTHING
-       case TypeCloudSync:
+       case apiv1.TypeCloudSync:
                if p.SThg != nil {
                        fld = NewProjectST(p.Context, svr)
                } else {
@@ -151,24 +152,24 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (
                }
 
        // PATH MAP
-       case TypePathMap:
+       case apiv1.TypePathMap:
                fld = NewProjectPathMap(p.Context, svr)
        default:
                return nil, fmt.Errorf("Unsupported folder type")
        }
 
-       var newPrj *ProjectConfig
+       var newPrj *apiv1.ProjectConfig
        if create {
                // Add project on server
                if newPrj, err = fld.Add(newF); err != nil {
-                       newF.Status = StatusErrorConfig
+                       newF.Status = apiv1.StatusErrorConfig
                        log.Printf("ERROR Adding project: %v\n", err)
                        return newPrj, err
                }
        } else {
                // Just update project config
                if newPrj, err = fld.UpdateProject(newF); err != nil {
-                       newF.Status = StatusErrorConfig
+                       newF.Status = apiv1.StatusErrorConfig
                        log.Printf("ERROR Updating project: %v\n", err)
                        return newPrj, err
                }
@@ -194,13 +195,13 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (
 }
 
 // Delete deletes a specific folder
-func (p *Projects) Delete(id string) (ProjectConfig, error) {
+func (p *Projects) Delete(id string) (apiv1.ProjectConfig, error) {
        var err error
 
        pjMutex.Lock()
        defer pjMutex.Unlock()
 
-       fld := ProjectConfig{}
+       fld := apiv1.ProjectConfig{}
        fc, exist := p.projects[id]
        if !exist {
                return fld, fmt.Errorf("unknown id")
@@ -215,7 +216,7 @@ func (p *Projects) Delete(id string) (ProjectConfig, error) {
        delete(p.projects, id)
 
        // Notify client with event
-       if err := p.events.Emit(EVTProjectDelete, *prj); err != nil {
+       if err := p.events.Emit(apiv1.EVTProjectDelete, *prj); err != nil {
                p.Log.Warningf("Cannot notify project deletion: %v", err)
        }
 
similarity index 99%
rename from lib/agent/session.go
rename to lib/agent/sessions.go
index 06789d5..7347480 100644 (file)
@@ -154,7 +154,7 @@ func (s *Sessions) UpdateIOSocket(sid string, so *socketio.Socket) error {
        return nil
 }
 
-// nesSession Allocate a new client session
+// newSession Allocate a new client session
 func (s *Sessions) newSession(prefix string) *ClientSession {
        uuid := prefix + uuid.NewV4().String()
        id := base64.URLEncoding.EncodeToString([]byte(uuid))
index 4b2e024..d15236d 100644 (file)
@@ -227,11 +227,11 @@ func (s *WebServer) socketHandler(c *gin.Context) {
        }
 
        s.sIOServer.On("connection", func(so socketio.Socket) {
-               s.Log.Debugf("WS Connected (SID=%v)", so.Id())
+               s.Log.Debugf("WS Connected (WSID=%s, SID=%s)", so.Id(), sess.ID)
                s.sessions.UpdateIOSocket(sess.ID, &so)
 
                so.On("disconnection", func() {
-                       s.Log.Debugf("WS disconnected (SID=%v)", so.Id())
+                       s.Log.Debugf("WS disconnected (WSID=%s, SID=%s)", so.Id(), sess.ID)
                        s.sessions.UpdateIOSocket(sess.ID, nil)
                })
        })
index b76908c..5851a07 100644 (file)
@@ -11,6 +11,7 @@ import (
        "time"
 
        "github.com/gin-gonic/gin"
+       "github.com/iotbzh/xds-agent/lib/apiv1"
        "github.com/iotbzh/xds-agent/lib/xdsconfig"
        common "github.com/iotbzh/xds-common/golib"
        uuid "github.com/satori/go.uuid"
@@ -366,7 +367,7 @@ func (xs *XdsServer) EventOff(evName string, id uuid.UUID) error {
 }
 
 // ProjectToFolder Convert Project structure to Folder structure
-func (xs *XdsServer) ProjectToFolder(pPrj ProjectConfig) *XdsFolderConfig {
+func (xs *XdsServer) ProjectToFolder(pPrj apiv1.ProjectConfig) *XdsFolderConfig {
        stID := ""
        if pPrj.Type == XdsTypeCloudSync {
                stID, _ = xs.SThg.IDGet()
@@ -395,7 +396,7 @@ func (xs *XdsServer) ProjectToFolder(pPrj ProjectConfig) *XdsFolderConfig {
 }
 
 // FolderToProject Convert Folder structure to Project structure
-func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) ProjectConfig {
+func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) apiv1.ProjectConfig {
        inSync := fPrj.IsInSync
        sts := fPrj.Status
 
@@ -404,27 +405,27 @@ func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) ProjectConfig {
 
                sts = fPrj.DataCloudSync.STSvrStatus
                switch fPrj.DataCloudSync.STLocStatus {
-               case StatusErrorConfig, StatusDisable, StatusPause:
+               case apiv1.StatusErrorConfig, apiv1.StatusDisable, apiv1.StatusPause:
                        sts = fPrj.DataCloudSync.STLocStatus
                        break
-               case StatusSyncing:
-                       if sts != StatusErrorConfig && sts != StatusDisable && sts != StatusPause {
-                               sts = StatusSyncing
+               case apiv1.StatusSyncing:
+                       if sts != apiv1.StatusErrorConfig && sts != apiv1.StatusDisable && sts != apiv1.StatusPause {
+                               sts = apiv1.StatusSyncing
                        }
                        break
-               case StatusEnable:
+               case apiv1.StatusEnable:
                        // keep STSvrStatus
                        break
                }
        }
 
-       pPrj := ProjectConfig{
+       pPrj := apiv1.ProjectConfig{
                ID:         fPrj.ID,
                ServerID:   xs.ID,
                Label:      fPrj.Label,
                ClientPath: fPrj.ClientPath,
                ServerPath: fPrj.DataPathMap.ServerPath,
-               Type:       ProjectType(fPrj.Type),
+               Type:       apiv1.ProjectType(fPrj.Type),
                Status:     sts,
                IsInSync:   inSync,
                DefaultSdk: fPrj.DefaultSdk,
@@ -591,7 +592,7 @@ func (xs *XdsServer) _SocketConnect() error {
 // Send event to notify changes
 func (xs *XdsServer) _NotifyState() {
 
-       evSts := ServerCfg{
+       evSts := apiv1.ServerCfg{
                ID:         xs.ID,
                URL:        xs.BaseURL,
                APIURL:     xs.APIURL,
@@ -599,7 +600,7 @@ func (xs *XdsServer) _NotifyState() {
                ConnRetry:  xs.ConnRetry,
                Connected:  xs.Connected,
        }
-       if err := xs.events.Emit(EVTServerConfig, evSts); err != nil {
+       if err := xs.events.Emit(apiv1.EVTServerConfig, evSts); err != nil {
                xs.Log.Warningf("Cannot notify XdsServer state change: %v", err)
        }
 }
diff --git a/lib/apiv1/config.go b/lib/apiv1/config.go
new file mode 100644 (file)
index 0000000..f5c1fb5
--- /dev/null
@@ -0,0 +1,22 @@
+package apiv1
+
+// APIConfig parameters (json format) of /config command
+type APIConfig struct {
+       Servers []ServerCfg `json:"servers"`
+
+       // Not exposed outside in JSON
+       Version       string `json:"-"`
+       APIVersion    string `json:"-"`
+       VersionGitTag string `json:"-"`
+}
+
+// ServerCfg .
+type ServerCfg struct {
+       ID         string `json:"id"`
+       URL        string `json:"url"`
+       APIURL     string `json:"apiUrl"`
+       PartialURL string `json:"partialUrl"`
+       ConnRetry  int    `json:"connRetry"`
+       Connected  bool   `json:"connected"`
+       Disabled   bool   `json:"disabled"`
+}
diff --git a/lib/apiv1/events.go b/lib/apiv1/events.go
new file mode 100644 (file)
index 0000000..8bad394
--- /dev/null
@@ -0,0 +1,33 @@
+package apiv1
+
+// EventRegisterArgs is the parameters (json format) of /events/register command
+type EventRegisterArgs struct {
+       Name      string `json:"name"`
+       ProjectID string `json:"filterProjectID"`
+}
+
+// EventUnRegisterArgs is the parameters (json format) of /events/unregister command
+type EventUnRegisterArgs struct {
+       Name string `json:"name"`
+       ID   int    `json:"id"`
+}
+
+// Events definitions
+const (
+       // EventTypePrefix Used as event prefix
+       EventTypePrefix = "event:" // following by event type
+
+       // Supported Events type
+       EVTAll           = "all"
+       EVTServerConfig  = "server-config"        // data type apiv1.ServerCfg
+       EVTProjectAdd    = "project-add"          // data type apiv1.ProjectConfig
+       EVTProjectDelete = "project-delete"       // data type apiv1.ProjectConfig
+       EVTProjectChange = "project-state-change" // data type apiv1.ProjectConfig
+)
+
+// EventMsg Message send
+type EventMsg struct {
+       Time string      `json:"time"`
+       Type string      `json:"type"`
+       Data interface{} `json:"data"`
+}
diff --git a/lib/apiv1/exec.go b/lib/apiv1/exec.go
new file mode 100644 (file)
index 0000000..914ed79
--- /dev/null
@@ -0,0 +1,64 @@
+package apiv1
+
+type (
+       // ExecArgs JSON parameters of /exec command
+       ExecArgs struct {
+               ID              string   `json:"id" binding:"required"`
+               SdkID           string   `json:"sdkID"` // sdk ID to use for setting env
+               CmdID           string   `json:"cmdID"` // command unique ID
+               Cmd             string   `json:"cmd" binding:"required"`
+               Args            []string `json:"args"`
+               Env             []string `json:"env"`
+               RPath           string   `json:"rpath"`           // relative path into project
+               TTY             bool     `json:"tty"`             // Use a tty, specific to gdb --tty option
+               TTYGdbserverFix bool     `json:"ttyGdbserverFix"` // Set to true to activate gdbserver workaround about inferior output
+               ExitImmediate   bool     `json:"exitImmediate"`   // when true, exit event sent immediately when command exited (IOW, don't wait file synchronization)
+               CmdTimeout      int      `json:"timeout"`         // command completion timeout in Second
+       }
+
+       // ExecInMsg Message used to received input characters (stdin)
+       ExecInMsg struct {
+               CmdID     string `json:"cmdID"`
+               Timestamp string `json:"timestamp"`
+               Stdin     string `json:"stdin"`
+       }
+
+       // ExecOutMsg Message used to send output characters (stdout+stderr)
+       ExecOutMsg struct {
+               CmdID     string `json:"cmdID"`
+               Timestamp string `json:"timestamp"`
+               Stdout    string `json:"stdout"`
+               Stderr    string `json:"stderr"`
+       }
+
+       // ExecExitMsg Message sent when executed command exited
+       ExecExitMsg struct {
+               CmdID     string `json:"cmdID"`
+               Timestamp string `json:"timestamp"`
+               Code      int    `json:"code"`
+               Error     error  `json:"error"`
+       }
+
+       // ExecSignalArgs JSON parameters of /exec/signal command
+       ExecSignalArgs struct {
+               CmdID  string `json:"cmdID" binding:"required"`  // command id
+               Signal string `json:"signal" binding:"required"` // signal number
+       }
+)
+
+const (
+       // ExecInEvent Event send in WS when characters are sent (stdin)
+       ExecInEvent = "exec:input"
+
+       // ExecOutEvent Event send in WS when characters are received (stdout or stderr)
+       ExecOutEvent = "exec:output"
+
+       // ExecExitEvent Event send in WS when program exited
+       ExecExitEvent = "exec:exit"
+
+       // ExecInferiorInEvent Event send in WS when characters are sent to an inferior (used by gdb inferior/tty)
+       ExecInferiorInEvent = "exec:inferior-input"
+
+       // ExecInferiorOutEvent Event send in WS when characters are received by an inferior
+       ExecInferiorOutEvent = "exec:inferior-output"
+)
diff --git a/lib/apiv1/projects.go b/lib/apiv1/projects.go
new file mode 100644 (file)
index 0000000..d76fa09
--- /dev/null
@@ -0,0 +1,32 @@
+package apiv1
+
+// ProjectType definition
+type ProjectType string
+
+const (
+       TypePathMap   = "PathMap"
+       TypeCloudSync = "CloudSync"
+       TypeCifsSmb   = "CIFS"
+)
+
+// Project Status definition
+const (
+       StatusErrorConfig = "ErrorConfig"
+       StatusDisable     = "Disable"
+       StatusEnable      = "Enable"
+       StatusPause       = "Pause"
+       StatusSyncing     = "Syncing"
+)
+
+// ProjectConfig is the config for one project
+type ProjectConfig struct {
+       ID         string      `json:"id"`
+       ServerID   string      `json:"serverId"`
+       Label      string      `json:"label"`
+       ClientPath string      `json:"clientPath"`
+       ServerPath string      `json:"serverPath"`
+       Type       ProjectType `json:"type"`
+       Status     string      `json:"status"`
+       IsInSync   bool        `json:"isInSync"`
+       DefaultSdk string      `json:"defaultSdk"`
+}
diff --git a/lib/apiv1/sdks.go b/lib/apiv1/sdks.go
new file mode 100644 (file)
index 0000000..dfa44e2
--- /dev/null
@@ -0,0 +1,11 @@
+package apiv1
+
+// SDK Define a cross tool chain used to build application
+type SDK struct {
+       ID      string `json:"id" binding:"required"`
+       Name    string `json:"name"`
+       Profile string `json:"profile"`
+       Version string `json:"version"`
+       Arch    string `json:"arch"`
+       Path    string `json:"path"`
+}
diff --git a/lib/apiv1/version.go b/lib/apiv1/version.go
new file mode 100644 (file)
index 0000000..956f890
--- /dev/null
@@ -0,0 +1,15 @@
+package apiv1
+
+// VersionData
+type VersionData struct {
+       ID            string `json:"id"`
+       Version       string `json:"version"`
+       APIVersion    string `json:"apiVersion"`
+       VersionGitTag string `json:"gitTag"`
+}
+
+// XDSVersion
+type XDSVersion struct {
+       Client VersionData   `json:"client"`
+       Server []VersionData `json:"servers"`
+}