From facf3f10b243d027cc2a28661fe1cd8d4253dafa Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Tue, 23 Jan 2018 15:33:08 +0100 Subject: Reworked SDKs events (introduced sdk-state-change) Signed-off-by: Sebastien Douheret --- lib/agent/apiv1-sdks.go | 41 +++++++++---- lib/xaapiv1/events.go | 41 +++++++++---- lib/xaapiv1/sdks.go | 7 +++ webapp/src/app/@core-xds/services/sdk.service.ts | 49 ++++++++------- .../src/app/@core-xds/services/xdsagent.service.ts | 71 +++++++++++++++++----- 5 files changed, 147 insertions(+), 62 deletions(-) diff --git a/lib/agent/apiv1-sdks.go b/lib/agent/apiv1-sdks.go index fd897fc..e48bb9a 100644 --- a/lib/agent/apiv1-sdks.go +++ b/lib/agent/apiv1-sdks.go @@ -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) diff --git a/lib/xaapiv1/events.go b/lib/xaapiv1/events.go index ab08d0f..6520057 100644 --- a/lib/xaapiv1/events.go +++ b/lib/xaapiv1/events.go @@ -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 { diff --git a/lib/xaapiv1/sdks.go b/lib/xaapiv1/sdks.go index 7f2ab02..97db9a8 100644 --- a/lib/xaapiv1/sdks.go +++ b/lib/xaapiv1/sdks.go @@ -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"` diff --git a/webapp/src/app/@core-xds/services/sdk.service.ts b/webapp/src/app/@core-xds/services/sdk.service.ts index 6191c85..f854744 100644 --- a/webapp/src/app/@core-xds/services/sdk.service.ts +++ b/webapp/src/app/@core-xds/services/sdk.service.ts @@ -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 { - return this.xdsSvr.onSdkInstall(); + return this.xdsSvr.onSdkManagement().filter(ev => ev.action === 'installing'); + } + + public onRemove(): Observable { + return this.xdsSvr.onSdkManagement().filter(ev => ev.action === 'removing'); } public abortInstall(sdk: ISdk): Observable { @@ -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); diff --git a/webapp/src/app/@core-xds/services/xdsagent.service.ts b/webapp/src/app/@core-xds/services/xdsagent.service.ts index 27e14cf..033185b 100644 --- a/webapp/src/app/@core-xds/services/xdsagent.service.ts +++ b/webapp/src/app/@core-xds/services/xdsagent.service.ts @@ -133,8 +133,10 @@ export class XDSAgentService { protected projectDel$ = new Subject(); protected projectChange$ = new Subject(); - protected sdkInstall$ = new Subject(); - protected sdkRemove$ = new Subject(); + protected sdkAdd$ = new Subject(); + protected sdkRemove$ = new Subject(); + protected sdkChange$ = new Subject(); + protected sdkManagement$ = new Subject(); 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 = 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 = 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 = 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 = 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 = 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 { - return this.sdkInstall$.asObservable(); + onSdkAdd(): Observable { + return this.sdkAdd$.asObservable(); } - onSdkRemove(): Observable { + onSdkRemove(): Observable { return this.sdkRemove$.asObservable(); } + onSdkChange(): Observable { + return this.sdkChange$.asObservable(); + } + + onSdkManagement(): Observable { + return this.sdkManagement$.asObservable(); + } + /** ** Misc / Version ***/ -- cgit 1.2.3-korg