X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=webapp%2Fsrc%2Fapp%2F%40core-xds%2Fservices%2Fxdsagent.service.ts;h=9f8385ac042aaf4e268ab12524397c770a8c7ad8;hb=45f6472d1e8ecad428da314a6d762143f033865d;hp=56e493f62c8269c284d8dd261c976c9a081b36c4;hpb=38c0c21a969e621c725245ce91c78e77076c5ce7;p=src%2Fxds%2Fxds-agent.git diff --git a/webapp/src/app/@core-xds/services/xdsagent.service.ts b/webapp/src/app/@core-xds/services/xdsagent.service.ts index 56e493f..9f8385a 100644 --- a/webapp/src/app/@core-xds/services/xdsagent.service.ts +++ b/webapp/src/app/@core-xds/services/xdsagent.service.ts @@ -1,4 +1,22 @@ -import { Injectable, Inject } from '@angular/core'; +/** +* @license +* Copyright (C) 2017 "IoT.bzh" +* Author Sebastien Douheret +* +* 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. +*/ + +import { Injectable, Inject, isDevMode } from '@angular/core'; import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; import { DOCUMENT } from '@angular/common'; import { Observable } from 'rxjs/Observable'; @@ -7,7 +25,7 @@ import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import * as io from 'socket.io-client'; import { AlertService } from './alert.service'; -import { ISdk } from './sdk.service'; +import { ISdk, ISdkManagementMsg } from './sdk.service'; import { ProjectType, ProjectTypeEnum } from './project.service'; // Import RxJs required methods @@ -16,7 +34,7 @@ import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; import 'rxjs/add/operator/mergeMap'; import 'rxjs/add/observable/of'; -import 'rxjs/add/operator/retryWhen'; +import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; export interface IXDSConfigProject { @@ -44,6 +62,7 @@ export interface IXDSProjectConfig { status?: string; isInSync?: boolean; defaultSdkID: string; + clientData?: string; } export interface IXDSVer { @@ -107,12 +126,19 @@ export class XDSAgentService { public XdsConfig$: Observable; public Status$: Observable; - public ProjectState$ = >new Subject(); public CmdOutput$ = >new Subject(); public CmdExit$ = >new Subject(); + protected projectAdd$ = new Subject(); + protected projectDel$ = new Subject(); + protected projectChange$ = new Subject(); + + protected sdkInstall$ = new Subject(); + protected sdkRemove$ = new Subject(); + private baseUrl: string; private wsUrl: string; + private httpSessionID: string; private _config = { servers: [] }; private _status = { connected: false, servers: [] }; @@ -130,14 +156,25 @@ export class XDSAgentService { const originUrl = this.document.location.origin; this.baseUrl = originUrl + '/api/v1'; - const re = originUrl.match(/http[s]?:\/\/([^\/]*)[\/]?/); - if (re === null || re.length < 2) { - console.error('ERROR: cannot determine Websocket url'); - } else { - this.wsUrl = 'ws://' + re[1]; - this._handleIoSocket(); - this._RegisterEvents(); - } + // Retrieve Session ID / token + this.http.get(this.baseUrl + '/version', { observe: 'response' }) + .subscribe( + resp => { + this.httpSessionID = resp.headers.get('xds-agent-sid'); + + const re = originUrl.match(/http[s]?:\/\/([^\/]*)[\/]?/); + if (re === null || re.length < 2) { + console.error('ERROR: cannot determine Websocket url'); + } else { + this.wsUrl = 'ws://' + re[1]; + this._handleIoSocket(); + this._RegisterEvents(); + } + }, + err => { + /* tslint:disable:no-console */ + console.error('ERROR while retrieving session id:', err); + }); } private _NotifyXdsAgentState(sts: boolean) { @@ -182,6 +219,8 @@ export class XDSAgentService { console.error('WS error:', err); }); + // XDS Events decoding + this.socket.on('make:output', data => { this.CmdOutput$.next(Object.assign({}, data)); }); @@ -198,8 +237,6 @@ export class XDSAgentService { this.CmdExit$.next(Object.assign({}, data)); }); - // Events - // (project-add and project-delete events are managed by project.service) this.socket.on('event:server-config', ev => { if (ev && ev.data) { const cfg: IXDServerCfg = ev.data; @@ -212,19 +249,86 @@ export class XDSAgentService { } }); + this.socket.on('event:project-add', (ev) => { + if (ev && ev.data && ev.data.id) { + this.projectAdd$.next(Object.assign({}, ev.data)); + if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && ev.data.label) { + this.alert.info('Project "' + ev.data.label + '" has been added by another tool.'); + } + } else if (isDevMode) { + /* tslint:disable:no-console */ + console.log('Warning: received event:project-add with unknown data: ev=', ev); + } + }); + + this.socket.on('event:project-delete', (ev) => { + if (ev && ev.data && ev.data.id) { + this.projectDel$.next(Object.assign({}, ev.data)); + if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && ev.data.label) { + this.alert.info('Project "' + ev.data.label + '" has been deleted by another tool.'); + } + } else if (isDevMode) { + console.log('Warning: received event:project-delete with unknown data: ev=', ev); + } + }); + this.socket.on('event:project-state-change', ev => { if (ev && ev.data) { - this.ProjectState$.next(Object.assign({}, ev.data)); + this.projectChange$.next(Object.assign({}, ev.data)); + } else if (isDevMode) { + console.log('Warning: received event:project-state-change with unkn220own data: ev=', ev); + } + }); + + this.socket.on('event:sdk-install', (ev) => { + if (ev && ev.data && ev.data.sdk) { + const evt = ev.data; + this.sdkInstall$.next(Object.assign({}, evt)); + + if (ev.sessionID !== '' && ev.sessionID !== this.httpSessionID && evt.sdk.name) { + this.alert.info('SDK "' + evt.sdk.name + '" has been installed by another tool.'); + } + } else if (isDevMode) { + /* tslint:disable:no-console */ + console.log('Warning: received event:sdk-install with unknown data: ev=', ev); } }); + this.socket.on('event:sdk-remove', (ev) => { + if (ev && ev.data && ev.data.sdk) { + const evt = ev.data; + this.sdkRemove$.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.'); + } + } else if (isDevMode) { + console.log('Warning: received event:sdk-remove with unknown data: ev=', ev); + } + }); } /** - ** Events + ** Events registration ***/ - addEventListener(ev: string, fn: Function): SocketIOClient.Emitter { - return this.socket.addEventListener(ev, fn); + onProjectAdd(): Observable { + return this.projectAdd$.asObservable(); + } + + onProjectDelete(): Observable { + return this.projectDel$.asObservable(); + } + + onProjectChange(): Observable { + return this.projectChange$.asObservable(); + } + + onSdkInstall(): Observable { + return this.sdkInstall$.asObservable(); + } + + onSdkRemove(): Observable { + return this.sdkRemove$.asObservable(); } /** @@ -288,10 +392,22 @@ export class XDSAgentService { if (!svr || !svr.connected) { return Observable.of([]); } - return this._get(svr.partialUrl + '/sdks'); } + installSdk(serverID: string, id: string, filename?: string, force?: boolean): Observable { + return this._post(this._getServerUrl(serverID) + '/sdks', { id: id, filename: filename, force: force }); + } + + abortInstall(serverID: string, id: string): Observable { + return this._post(this._getServerUrl(serverID) + '/sdks/abortinstall', { id: id }); + } + + removeSdk(serverID: string, id: string): Observable { + return this._delete(this._getServerUrl(serverID) + '/sdks/' + id); + } + + /*** ** Projects ***/ @@ -307,6 +423,10 @@ export class XDSAgentService { return this._delete('/projects/' + id); } + updateProject(cfg: IXDSProjectConfig): Observable { + return this._put('/projects/' + cfg.id, cfg); + } + syncProject(id: string): Observable { return this._post('/projects/sync/' + id, {}); } @@ -337,8 +457,8 @@ export class XDSAgentService { res => { }, error => { this.alert.error('ERROR while registering to all events: ' + error); - } - ); + }, + ); } private _getServer(ID: string): IXDServerCfg { @@ -349,6 +469,17 @@ export class XDSAgentService { return svr[0]; } + private _getServerUrl(serverID: string): string | ErrorObservable { + const svr = this._getServer(serverID); + if (!svr || !svr.connected) { + if (isDevMode) { + console.log('ERROR: XDS Server unknown: serverID=' + serverID); + } + return Observable.throw('Cannot identify XDS Server'); + } + return svr.partialUrl; + } + private _attachAuthHeaders(options?: any) { options = options || {}; const headers = options.headers || new HttpHeaders(); @@ -371,6 +502,12 @@ export class XDSAgentService { return this._decodeError(error); }); } + private _put(url: string, body: any): Observable { + return this.http.put(this.baseUrl + url, JSON.stringify(body), this._attachAuthHeaders()) + .catch((error) => { + return this._decodeError(error); + }); + } private _delete(url: string): Observable { return this.http.delete(this.baseUrl + url, this._attachAuthHeaders()) .catch(this._decodeError); @@ -391,7 +528,10 @@ export class XDSAgentService { } else { e = err.message ? err.message : err.toString(); } - console.log('xdsagent.service - ERROR: ', e); + /* tslint:disable:no-console */ + if (isDevMode) { + console.log('xdsagent.service - ERROR: ', e); + } return Observable.throw(e); } }