Reworked SDKs events (introduced sdk-state-change)
authorSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 23 Jan 2018 14:31:00 +0000 (15:31 +0100)
committerSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 23 Jan 2018 14:31:00 +0000 (15:31 +0100)
Split add/remove/state-change from installing output
(AKA SDKManagement event) in order to clearly separate events
used to send installation output and sdk config changes.

Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
lib/xdsserver/events.go
lib/xdsserver/sdk.go
lib/xdsserver/sdks.go
lib/xsapiv1/events.go
lib/xsapiv1/sdks.go

index 4ae1ff3..2528725 100644 (file)
@@ -88,7 +88,7 @@ func (e *Events) UnRegister(evName, sessionID string) error {
 }
 
 // Emit Used to manually emit an event
-func (e *Events) Emit(evName string, data interface{}, fromSid string) error {
+func (e *Events) Emit(evName string, data interface{}, fromSessID string) error {
        var firstErr error
 
        if _, ok := e.eventsMap[evName]; !ok {
@@ -108,7 +108,7 @@ func (e *Events) Emit(evName string, data interface{}, fromSid string) error {
                }
                msg := xsapiv1.EventMsg{
                        Time:          time.Now().String(),
-                       FromSessionID: fromSid,
+                       FromSessionID: fromSessID,
                        Type:          evName,
                        Data:          data,
                }
index d5b2b43..633fbee 100644 (file)
@@ -267,12 +267,12 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
                // IO socket can be nil when disconnected
                so := s.sessions.IOSocketGet(e.Sid)
                if so == nil {
-                       s.Log.Infof("%s not emitted: WS closed (sid:%s, msgid:%s)", xsapiv1.EVTSDKInstall, e.Sid, e.CmdID)
+                       s.Log.Infof("%s not emitted: WS closed (sid:%s, msgid:%s)", xsapiv1.EVTSDKManagement, e.Sid, e.CmdID)
                        return
                }
 
                if s.LogLevelSilly {
-                       s.Log.Debugf("%s emitted - WS sid[4:] %s - id:%s - SDK ID:%s:", xsapiv1.EVTSDKInstall, e.Sid[4:], e.CmdID, sdkID[:16])
+                       s.Log.Debugf("%s emitted - WS sid[4:] %s - id:%s - SDK ID:%s:", xsapiv1.EVTSDKManagement, e.Sid[4:], e.CmdID, sdkID[:16])
                        if stdout != "" {
                                s.Log.Debugf("STDOUT <<%v>>", strings.Replace(stdout, "\n", "\\n", -1))
                        }
@@ -287,9 +287,10 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
                s.bufStderr += stderr
                if len(s.bufStdout) > SizeBufStdout || len(s.bufStderr) > SizeBufStderr {
                        // Emit event
-                       err := (*so).Emit(xsapiv1.EVTSDKInstall, xsapiv1.SDKManagementMsg{
+                       err := (*so).Emit(xsapiv1.EVTSDKManagement, xsapiv1.SDKManagementMsg{
                                CmdID:     e.CmdID,
                                Timestamp: time.Now().String(),
+                               Action:    xsapiv1.SdkMgtActionInstall,
                                Sdk:       s.sdk,
                                Progress:  0, // TODO add progress
                                Exited:    false,
@@ -318,15 +319,16 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
                // IO socket can be nil when disconnected
                so := s.sessions.IOSocketGet(e.Sid)
                if so == nil {
-                       s.Log.Infof("%s (exit) not emitted - WS closed (id:%s)", xsapiv1.EVTSDKInstall, e.CmdID)
+                       s.Log.Infof("%s (exit) not emitted - WS closed (id:%s)", xsapiv1.EVTSDKManagement, e.CmdID)
                        return
                }
 
                // Emit event remaining data in bufStdout/err
                if len(s.bufStderr) > 0 || len(s.bufStdout) > 0 {
-                       err := (*so).Emit(xsapiv1.EVTSDKInstall, xsapiv1.SDKManagementMsg{
+                       err := (*so).Emit(xsapiv1.EVTSDKManagement, xsapiv1.SDKManagementMsg{
                                CmdID:     e.CmdID,
                                Timestamp: time.Now().String(),
+                               Action:    xsapiv1.SdkMgtActionInstall,
                                Sdk:       s.sdk,
                                Progress:  50, // TODO add progress
                                Exited:    false,
@@ -377,9 +379,10 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
                }
 
                // Emit event
-               errSoEmit := (*so).Emit(xsapiv1.EVTSDKInstall, xsapiv1.SDKManagementMsg{
+               errSoEmit := (*so).Emit(xsapiv1.EVTSDKManagement, xsapiv1.SDKManagementMsg{
                        CmdID:     e.CmdID,
                        Timestamp: time.Now().String(),
+                       Action:    xsapiv1.SdkMgtActionInstall,
                        Sdk:       s.sdk,
                        Progress:  100,
                        Exited:    true,
@@ -387,7 +390,12 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
                        Error:     emitErr,
                })
                if errSoEmit != nil {
-                       s.Log.Errorf("WS Emit : %v", errSoEmit)
+                       s.Log.Errorf("WS Emit EVTSDKManagement : %v", errSoEmit)
+               }
+
+               errSoEmit = s.events.Emit(xsapiv1.EVTSDKStateChange, s.sdk, e.Sid)
+               if errSoEmit != nil {
+                       s.Log.Errorf("WS Emit EVTSDKStateChange : %v", errSoEmit)
                }
 
                // Cleanup command for the next time
@@ -436,8 +444,8 @@ func (s *CrossSDK) Remove(timeout int, sess *ClientSession) error {
 
        s.sdk.Status = xsapiv1.SdkStatusUninstalling
 
-       // Emit Remove event
-       if err := (*so).Emit(xsapiv1.EVTSDKStateChange, s.sdk); err != nil {
+       // Notify state change
+       if err := s.events.Emit(xsapiv1.EVTSDKStateChange, s.sdk, sess.ID); err != nil {
                s.Log.Warningf("Cannot notify SDK remove: %v", err)
        }
 
@@ -445,43 +453,56 @@ func (s *CrossSDK) Remove(timeout int, sess *ClientSession) error {
        args := s.sdk.Path
        s.Log.Infof("Uninstall SDK %s: script=%v args=%v", s.sdk.Name, script, args)
 
+       // Notify start removing
+       evData := xsapiv1.SDKManagementMsg{
+               Timestamp: time.Now().String(),
+               Action:    xsapiv1.SdkMgtActionRemove,
+               Sdk:       s.sdk,
+               Progress:  0,
+               Exited:    false,
+               Code:      0,
+               Error:     "",
+       }
+       if errEmit := (*so).Emit(xsapiv1.EVTSDKManagement, evData); errEmit != nil {
+               s.Log.Warningf("Cannot notify EVTSDKManagement end: %v", errEmit)
+       }
+
+       // Run command to remove SDK
        cmd := exec.Command(script, args)
        stdout, err := cmd.CombinedOutput()
 
        s.sdk.Status = xsapiv1.SdkStatusNotInstalled
        s.Log.Debugf("SDK uninstall err %v, output:\n %v", err, string(stdout))
 
-       if err != nil {
-
-               // Emit Remove event
-               evData := xsapiv1.SDKManagementMsg{
-                       Timestamp: time.Now().String(),
-                       Sdk:       s.sdk,
-                       Progress:  100,
-                       Exited:    true,
-                       Code:      1,
-                       Error:     err.Error(),
-               }
-               if err := (*so).Emit(xsapiv1.EVTSDKRemove, evData); err != nil {
-                       s.Log.Warningf("Cannot notify SDK remove end: %v", err)
-               }
-
-               return fmt.Errorf("Error while uninstalling sdk: %v", err)
-       }
-
-       // Emit Remove event
-       evData := xsapiv1.SDKManagementMsg{
+       // Emit end of removing process
+       evData = xsapiv1.SDKManagementMsg{
                Timestamp: time.Now().String(),
+               Action:    xsapiv1.SdkMgtActionRemove,
                Sdk:       s.sdk,
                Progress:  100,
                Exited:    true,
                Code:      0,
                Error:     "",
        }
-       if err := (*so).Emit(xsapiv1.EVTSDKRemove, evData); err != nil {
-               s.Log.Warningf("Cannot notify SDK remove end: %v", err)
+
+       // Update error code on error
+       if err != nil {
+               evData.Code = 1
+               evData.Error = err.Error()
+       }
+
+       if errEmit := (*so).Emit(xsapiv1.EVTSDKManagement, evData); errEmit != nil {
+               s.Log.Warningf("Cannot notify EVTSDKManagement end: %v", errEmit)
+       }
+
+       // Notify state change
+       if errEmit := s.events.Emit(xsapiv1.EVTSDKStateChange, s.sdk, sess.ID); errEmit != nil {
+               s.Log.Warningf("Cannot notify EVTSDKStateChange end: %v", errEmit)
        }
 
+       if err != nil {
+               return fmt.Errorf("Error while uninstalling sdk: %v", err)
+       }
        return nil
 }
 
index a18d94f..c006861 100644 (file)
@@ -211,7 +211,7 @@ func (s *SDKs) monitorSDKInstallation(watchingDirs []string) {
                                sdk.Path = sdkDef.SetupFile
 
                                // Emit Folder state change event
-                               if err := s.events.Emit(xsapiv1.EVTSDKInstall, sdk, ""); err != nil {
+                               if err := s.events.Emit(xsapiv1.EVTSDKAdd, sdk, ""); err != nil {
                                        s.Log.Warningf("Cannot notify SDK install: %v", err)
                                }
 
index aa17187..84a364c 100644 (file)
@@ -51,8 +51,9 @@ const (
        EVTAll               = EventTypePrefix + "all"
        EVTFolderChange      = EventTypePrefix + "folder-change"       // type EventMsg with Data type xsapiv1.FolderConfig
        EVTFolderStateChange = EventTypePrefix + "folder-state-change" // type EventMsg with Data type xsapiv1.FolderConfig
-       EVTSDKInstall        = EventTypePrefix + "sdk-install"         // type EventMsg with Data type xsapiv1.SDKManagementMsg
-       EVTSDKRemove         = EventTypePrefix + "sdk-remove"          // type EventMsg with Data type xsapiv1.SDKManagementMsg
+       EVTSDKAdd            = EventTypePrefix + "sdk-add"             // type EventMsg with Data type xsapiv1.SDK
+       EVTSDKRemove         = EventTypePrefix + "sdk-remove"          // type EventMsg with Data type xsapiv1.SDK
+       EVTSDKManagement     = EventTypePrefix + "sdk-management"      // type EventMsg with Data type xsapiv1.SDKManagementMsg
        EVTSDKStateChange    = EventTypePrefix + "sdk-state-change"    // type EventMsg with Data type xsapiv1.SDK
 )
 
@@ -60,8 +61,9 @@ const (
 var EVTAllList = []string{
        EVTFolderChange,
        EVTFolderStateChange,
-       EVTSDKInstall,
+       EVTSDKAdd,
        EVTSDKRemove,
+       EVTSDKManagement,
        EVTSDKStateChange,
 }
 
@@ -81,3 +83,20 @@ func (e *EventMsg) DecodeFolderConfig() (FolderConfig, error) {
        }
        return f, err
 }
+
+// DecodeSDKEvent Helper to decode Data field type SDK
+func (e *EventMsg) DecodeSDKEvent() (SDK, error) {
+       var err error
+       s := SDK{}
+       switch e.Type {
+       case EVTSDKAdd, EVTSDKRemove, EVTSDKStateChange:
+               d := []byte{}
+               d, err = json.Marshal(e.Data)
+               if err == nil {
+                       err = json.Unmarshal(d, &s)
+               }
+       default:
+               err = fmt.Errorf("Invalid type")
+       }
+       return s, err
+}
index f751fc6..abb5d4a 100644 (file)
@@ -65,10 +65,17 @@ type SDKInstallArgs struct {
        InstallArgs []string `json:"installArgs"` // args directly passed to add/install script
 }
 
+// SDK SDKManagementMsg Actions
+const (
+       SdkMgtActionInstall = "installing"
+       SdkMgtActionRemove  = "removing"
+)
+
 // SDKManagementMsg Message send during SDK installation or when installation is complete
 type SDKManagementMsg struct {
        CmdID     string `json:"cmdID"`
        Timestamp string `json:"timestamp"`
+       Action    string `json:"action"`
        Sdk       SDK    `json:"sdk"`
        Stdout    string `json:"stdout"`
        Stderr    string `json:"stderr"`