Reworked SDKs events (introduced sdk-state-change) 5.0.1 eel/5.0.1 eel_5.0.1
authorSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 23 Jan 2018 14:33:08 +0000 (15:33 +0100)
committerSebastien Douheret <sebastien.douheret@iot.bzh>
Tue, 23 Jan 2018 14:33:08 +0000 (15:33 +0100)
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
lib/agent/apiv1-sdks.go
lib/xaapiv1/events.go
lib/xaapiv1/sdks.go
webapp/src/app/@core-xds/services/sdk.service.ts
webapp/src/app/@core-xds/services/xdsagent.service.ts

index fd897fc..e48bb9a 100644 (file)
@@ -44,44 +44,59 @@ func (s *APIService) sdksEventsForwardInit(svr *XdsServer) error {
        }
 
        // Forward SDK events from XDS-server to client
-       if _, err := svr.EventOn(xsapiv1.EVTSDKInstall, "", s._sdkEventInstallCB); err != nil {
-               s.Log.Errorf("XDS Server EventOn '%s' failed: %v", xsapiv1.EVTSDKInstall, err)
+       if _, err := svr.EventOn(xsapiv1.EVTSDKAdd, xaapiv1.EVTSDKAdd, s._sdkEventCB); err != nil {
+               s.Log.Errorf("XDS Server EventOn '%s' failed: %v", xsapiv1.EVTSDKAdd, err)
                return err
        }
-
-       if _, err := svr.EventOn(xsapiv1.EVTSDKRemove, "", s._sdkEventRemoveCB); err != nil {
+       if _, err := svr.EventOn(xsapiv1.EVTSDKRemove, xaapiv1.EVTSDKRemove, s._sdkEventCB); err != nil {
                s.Log.Errorf("XDS Server EventOn '%s' failed: %v", xsapiv1.EVTSDKRemove, err)
                return err
        }
+       if _, err := svr.EventOn(xsapiv1.EVTSDKStateChange, xaapiv1.EVTSDKStateChange, s._sdkEventCB); err != nil {
+               s.Log.Errorf("XDS Server EventOn '%s' failed: %v", xsapiv1.EVTSDKStateChange, err)
+               return err
+       }
+
+       if _, err := svr.EventOn(xsapiv1.EVTSDKManagement, "", s._sdkEventManagementCB); err != nil {
+               s.Log.Errorf("XDS Server EventOn '%s' failed: %v", xsapiv1.EVTSDKManagement, err)
+               return err
+       }
 
        return nil
 }
 
-func (s *APIService) _sdkEventInstallCB(privD interface{}, data interface{}) error {
-       // assume that xsapiv1.SDKManagementMsg == xaapiv1.SDKManagementMsg
-       evt := xaapiv1.SDKManagementMsg{}
-       evtName := xaapiv1.EVTSDKInstall
+func (s *APIService) _sdkEventCB(privD interface{}, data interface{}) error {
+       evt := xsapiv1.EventMsg{}
        d, err := json.Marshal(data)
        if err != nil {
-               s.Log.Errorf("Cannot marshal XDS Server %s: err=%v", evtName, err)
+               s.Log.Errorf("Cannot marshal XDS Server SDK event err=%v, data=%v", err, data)
                return err
        }
        if err = json.Unmarshal(d, &evt); err != nil {
-               s.Log.Errorf("Cannot unmarshal XDS Server %s: err=%v", evtName, err)
+               s.Log.Errorf("Cannot unmarshal XDS Server SDK event err=%v, d=%v", err, string(d))
                return err
        }
 
-       if err := s.events.Emit(evtName, evt, ""); err != nil {
+       // assume that xsapiv1.SDK == xaapiv1.SDK
+       sdk, err := evt.DecodeSDKEvent()
+       if err != nil {
+               s.Log.Errorf("Cannot decode XDS Server SDK event: err=%v, data=%v", err, data)
+               return err
+       }
+
+       evtName := privD.(string)
+
+       if err := s.events.Emit(evtName, sdk, ""); err != nil {
                s.Log.Warningf("Cannot notify %s (from server): %v", evtName, err)
                return err
        }
        return nil
 }
 
-func (s *APIService) _sdkEventRemoveCB(privD interface{}, data interface{}) error {
+func (s *APIService) _sdkEventManagementCB(privD interface{}, data interface{}) error {
        // assume that xsapiv1.SDKManagementMsg == xaapiv1.SDKManagementMsg
        evt := xaapiv1.SDKManagementMsg{}
-       evtName := xaapiv1.EVTSDKRemove
+       evtName := xaapiv1.EVTSDKManagement
        d, err := json.Marshal(data)
        if err != nil {
                s.Log.Errorf("Cannot marshal XDS Server %s: err=%v", evtName, err)
index ab08d0f..6520057 100644 (file)
@@ -40,13 +40,15 @@ const (
        EventTypePrefix = "event:" // following by event type
 
        // Supported Events type
-       EVTAll           = EventTypePrefix + "all"
-       EVTServerConfig  = EventTypePrefix + "server-config"        // type EventMsg with Data type xaapiv1.ServerCfg
-       EVTProjectAdd    = EventTypePrefix + "project-add"          // type EventMsg with Data type xaapiv1.ProjectConfig
-       EVTProjectDelete = EventTypePrefix + "project-delete"       // type EventMsg with Data type xaapiv1.ProjectConfig
-       EVTProjectChange = EventTypePrefix + "project-state-change" // type EventMsg with Data type xaapiv1.ProjectConfig
-       EVTSDKInstall    = EventTypePrefix + "sdk-install"          // type EventMsg with Data type xaapiv1.SDKManagementMsg
-       EVTSDKRemove     = EventTypePrefix + "sdk-remove"           // type EventMsg with Data type xaapiv1.SDKManagementMsg
+       EVTAll            = EventTypePrefix + "all"
+       EVTServerConfig   = EventTypePrefix + "server-config"        // type EventMsg with Data type xaapiv1.ServerCfg
+       EVTProjectAdd     = EventTypePrefix + "project-add"          // type EventMsg with Data type xaapiv1.ProjectConfig
+       EVTProjectDelete  = EventTypePrefix + "project-delete"       // type EventMsg with Data type xaapiv1.ProjectConfig
+       EVTProjectChange  = EventTypePrefix + "project-state-change" // type EventMsg with Data type xaapiv1.ProjectConfig
+       EVTSDKAdd         = EventTypePrefix + "sdk-add"              // type EventMsg with Data type xaapiv1.SDK
+       EVTSDKRemove      = EventTypePrefix + "sdk-remove"           // type EventMsg with Data type xaapiv1.SDK
+       EVTSDKManagement  = EventTypePrefix + "sdk-management"       // type EventMsg with Data type xaapiv1.SDKManagementMsg
+       EVTSDKStateChange = EventTypePrefix + "sdk-state-change"     // type EventMsg with Data type xaapiv1.SDK
 )
 
 // EVTAllList List of all supported events
@@ -55,8 +57,10 @@ var EVTAllList = []string{
        EVTProjectAdd,
        EVTProjectDelete,
        EVTProjectChange,
-       EVTSDKInstall,
+       EVTSDKAdd,
        EVTSDKRemove,
+       EVTSDKManagement,
+       EVTSDKStateChange,
 }
 
 // EventMsg Event message send over Websocket, data format depend to Type (see DecodeXXX function)
@@ -97,12 +101,27 @@ func (e *EventMsg) DecodeProjectConfig() (ProjectConfig, error) {
        return p, err
 }
 
-// DecodeSDKMsg Helper to decode Data field type SDKManagementMsg
-func (e *EventMsg) DecodeSDKMsg() (SDKManagementMsg, error) {
+// DecodeSDKMgtMsg Helper to decode Data field type SDKManagementMsg
+func (e *EventMsg) DecodeSDKMgtMsg() (SDKManagementMsg, error) {
        var err error
        s := SDKManagementMsg{}
+       if e.Type != EVTSDKManagement {
+               return s, fmt.Errorf("Invalid type")
+       }
+       d := []byte{}
+       d, err = json.Marshal(e.Data)
+       if err == nil {
+               err = json.Unmarshal(d, &s)
+       }
+       return s, err
+}
+
+// DecodeSDKEvent Helper to decode Data field type SDK
+func (e *EventMsg) DecodeSDKEvent() (SDK, error) {
+       var err error
+       s := SDK{}
        switch e.Type {
-       case EVTSDKInstall, EVTSDKRemove:
+       case EVTSDKAdd, EVTSDKRemove, EVTSDKStateChange:
                d := []byte{}
                d, err = json.Marshal(e.Data)
                if err == nil {
index 7f2ab02..97db9a8 100644 (file)
@@ -53,10 +53,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"`
index 6191c85..f854744 100644 (file)
@@ -62,6 +62,7 @@ export interface ISdk {
 export interface ISdkManagementMsg {
   cmdID: string;
   timestamp: string;
+  action: string;
   sdk: ISdk;
   stdout: string;
   stderr: string;
@@ -97,7 +98,7 @@ export class SdkService {
       this.xdsSvr.getSdks(this.curServerID).subscribe((sdks) => {
         this._sdksList = [];
         sdks.forEach(s => {
-          this._addSdk(s, true);
+          this._addUpdateSdk(s, true);
         });
 
         // TODO: get previous val from xds-config service / cookie
@@ -111,18 +112,17 @@ export class SdkService {
     });
 
     // Add listener on sdk creation, deletion and change events
-    this.xdsSvr.onSdkInstall().subscribe(evMgt => {
-      this._addSdk(evMgt.sdk);
-    });
-    this.xdsSvr.onSdkRemove().subscribe(evMgt => {
-      if (evMgt.sdk.status !== StatusType.NOT_INSTALLED) {
+    this.xdsSvr.onSdkAdd().subscribe(sdk => this._addUpdateSdk(sdk));
+    this.xdsSvr.onSdkChange().subscribe(sdk => this._addUpdateSdk(sdk));
+
+    this.xdsSvr.onSdkRemove().subscribe(sdk => {
+      if (sdk.status !== StatusType.NOT_INSTALLED) {
         /* tslint:disable:no-console */
-        console.log('Error: received event:sdk-remove with invalid status: evMgt=', evMgt);
+        console.log('Error: received event:sdk-remove with invalid status: sdk=', sdk);
         return;
       }
-      this._delSdk(evMgt.sdk);
+      this._delSdk(sdk);
     });
-
   }
 
   public setCurrent(s: ISdk) {
@@ -145,7 +145,11 @@ export class SdkService {
   }
 
   public onInstall(): Observable<ISdkManagementMsg> {
-    return this.xdsSvr.onSdkInstall();
+    return this.xdsSvr.onSdkManagement().filter(ev => ev.action === 'installing');
+  }
+
+  public onRemove(): Observable<ISdkManagementMsg> {
+    return this.xdsSvr.onSdkManagement().filter(ev => ev.action === 'removing');
   }
 
   public abortInstall(sdk: ISdk): Observable<ISdk> {
@@ -158,27 +162,28 @@ export class SdkService {
 
   /** Private **/
 
-  private _addSdk(sdk: ISdk, noNext?: boolean): ISdk {
+  private _addUpdateSdk(sdk: ISdk, noNext?: boolean): ISdk {
 
     // check if sdk already exists
     const idx = this._sdksList.findIndex(s => s.id === sdk.id);
     if (idx >= 0) {
+      // Just update existing one
       this._sdksList[idx] = sdk;
     } else {
       // add new sdk
       this._sdksList.push(sdk);
-    }
 
-    // sort sdk array
-    this._sdksList.sort((a, b) => {
-      if (a.name < b.name) {
-        return -1;
-      }
-      if (a.name > b.name) {
-        return 1;
-      }
-      return 0;
-    });
+      // sort sdk array
+      this._sdksList.sort((a, b) => {
+        if (a.name < b.name) {
+          return -1;
+        }
+        if (a.name > b.name) {
+          return 1;
+        }
+        return 0;
+      });
+    }
 
     if (!noNext) {
       this.sdksSubject.next(this._sdksList);
index 27e14cf..033185b 100644 (file)
@@ -133,8 +133,10 @@ export class XDSAgentService {
   protected projectDel$ = new Subject<IXDSProjectConfig>();
   protected projectChange$ = new Subject<IXDSProjectConfig>();
 
-  protected sdkInstall$ = new Subject<ISdkManagementMsg>();
-  protected sdkRemove$ = new Subject<ISdkManagementMsg>();
+  protected sdkAdd$ = new Subject<ISdk>();
+  protected sdkRemove$ = new Subject<ISdk>();
+  protected sdkChange$ = new Subject<ISdk>();
+  protected sdkManagement$ = new Subject<ISdkManagementMsg>();
 
   private baseUrl: string;
   private wsUrl: string;
@@ -249,6 +251,8 @@ export class XDSAgentService {
       }
     });
 
+    /*** Project events ****/
+
     this.socket.on('event:project-add', (ev) => {
       if (ev && ev.data && ev.data.id) {
         this.projectAdd$.next(Object.assign({}, ev.data));
@@ -280,32 +284,59 @@ export class XDSAgentService {
       }
     });
 
-    this.socket.on('event:sdk-install', (ev) => {
-      if (ev && ev.data && ev.data.sdk) {
-        const evt = <ISdkManagementMsg>ev.data;
-        this.sdkInstall$.next(Object.assign({}, evt));
+    /*** SDK Events ***/
 
-        if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && evt.sdk.name) {
-          this.alert.info('SDK "' + evt.sdk.name + '" has been installed by another tool.');
+    this.socket.on('event:sdk-add', (ev) => {
+      if (ev && ev.data && ev.data.id) {
+        const evt = <ISdk>ev.data;
+        this.sdkAdd$.next(Object.assign({}, evt));
+
+        if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && evt.name) {
+          this.alert.info('SDK "' + evt.name + '" has been added by another tool.');
         }
       } else if (isDevMode) {
-        /* tslint:disable:no-console */
-        console.log('Warning: received event:sdk-install with unknown data: ev=', ev);
+        console.log('Warning: received event:sdk-add with unknown data: ev=', ev);
       }
     });
 
     this.socket.on('event:sdk-remove', (ev) => {
+      if (ev && ev.data && ev.data.id) {
+        const evt = <ISdk>ev.data;
+        this.sdkRemove$.next(Object.assign({}, evt));
+
+        if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && evt.name) {
+          this.alert.info('SDK "' + evt.name + '" has been removed by another tool.');
+        }
+      } else if (isDevMode) {
+        console.log('Warning: received event:sdk-remove with unknown data: ev=', ev);
+      }
+    });
+
+    this.socket.on('event:sdk-state-change', (ev) => {
+      if (ev && ev.data && ev.data.id) {
+        const evt = <ISdk>ev.data;
+        this.sdkChange$.next(Object.assign({}, evt));
+
+      } else if (isDevMode) {
+        console.log('Warning: received event:sdk-state-change with unknown data: ev=', ev);
+      }
+    });
+
+
+    this.socket.on('event:sdk-management', (ev) => {
       if (ev && ev.data && ev.data.sdk) {
         const evt = <ISdkManagementMsg>ev.data;
-        this.sdkRemove$.next(Object.assign({}, evt));
+        this.sdkManagement$.next(Object.assign({}, evt));
 
         if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && evt.sdk.name) {
-          this.alert.info('SDK "' + evt.sdk.name + '" has been removed by another tool.');
+          this.alert.info('SDK "' + evt.sdk.name + '" has been installed by another tool.');
         }
       } else if (isDevMode) {
-        console.log('Warning: received event:sdk-remove with unknown data: ev=', ev);
+        /* tslint:disable:no-console */
+        console.log('Warning: received event:sdk-install with unknown data: ev=', ev);
       }
     });
+
   }
 
   /**
@@ -323,14 +354,22 @@ export class XDSAgentService {
     return this.projectChange$.asObservable();
   }
 
-  onSdkInstall(): Observable<ISdkManagementMsg> {
-    return this.sdkInstall$.asObservable();
+  onSdkAdd(): Observable<ISdk> {
+    return this.sdkAdd$.asObservable();
   }
 
-  onSdkRemove(): Observable<ISdkManagementMsg> {
+  onSdkRemove(): Observable<ISdk> {
     return this.sdkRemove$.asObservable();
   }
 
+  onSdkChange(): Observable<ISdk> {
+    return this.sdkChange$.asObservable();
+  }
+
+  onSdkManagement(): Observable<ISdkManagementMsg> {
+    return this.sdkManagement$.asObservable();
+  }
+
   /**
   ** Misc / Version
   ***/