Updating observable on webscoket event

Change-Id: I8325785b8d40b646ea67f28b61b8d603803a571e
diff --git a/src/app/services/rest/auth.service.ts b/src/app/services/rest/auth.service.ts
index c53e3f4..b5b00fb 100644
--- a/src/app/services/rest/auth.service.ts
+++ b/src/app/services/rest/auth.service.ts
@@ -3,7 +3,7 @@
 // Imports
 import {AppConfig} from '../../config/app.config';
 import {Injectable}     from '@angular/core';
-import {Http, Response} from '@angular/http';
+import {Http, Response, Headers} from '@angular/http';
 import {Observable} from 'rxjs/Rx';
 import {IAuthRequest, IAuthResponse} from '../../interfaces/auth.interface';
 import {CookieService} from 'angular2-cookie/core';
@@ -24,17 +24,25 @@
   isAuthenticated(): string {
     this.xosToken = this.cookieService.get('xoscsrftoken');
     this.xosSessionId = this.cookieService.get('xossessionid');
-    return this.xosToken;
+    return this.xosToken && this.xosSessionId;
+  }
+
+  // get auth info to authenticate API
+  getUserHeaders(): Headers{
+    const headers = new Headers();
+    headers.append('x-csrftoken', this.cookieService.get('xoscsrftoken'));
+    headers.append('x-sessionid', this.cookieService.get('xossessionid'));
+    return headers;
   }
 
   // save cookies
-  storeAuth(auth: IAuthResponse): void {
+  private storeAuth(auth: IAuthResponse): void {
     this.cookieService.put('xoscsrftoken', auth.xoscsrftoken);
     this.cookieService.put('xossessionid', auth.xossessionid);
   }
 
   // remove cookies
-  removeAuth(): void {
+  private removeAuth(): void {
     this.cookieService.remove('xoscsrftoken');
     this.cookieService.remove('xossessionid');
   }
diff --git a/src/app/services/rest/core.service.ts b/src/app/services/rest/core.service.ts
index 04097a6..3890c47 100644
--- a/src/app/services/rest/core.service.ts
+++ b/src/app/services/rest/core.service.ts
@@ -2,9 +2,10 @@
 
 // Imports
 import {AppConfig} from '../../config/app.config';
-import { Injectable }     from '@angular/core';
-import { Http, Response, Headers, RequestOptions } from '@angular/http';
+import {Injectable}     from '@angular/core';
+import {Response} from '@angular/http';
 import {Observable} from 'rxjs/Rx';
+import {XosHttp} from './xoshttp.service';
 
 // Import RxJs required methods
 import 'rxjs/add/operator/map';
@@ -12,19 +13,22 @@
 
 @Injectable()
 export class CoreService {
-  // Resolve HTTP using the constructor
-  constructor (private http: Http) {}
   // private instance variable to hold base url
   private baseUrl = AppConfig.apiEndpoint;
 
+  // Resolve HTTP using the constructor
+  constructor (private http: XosHttp) {}
+
   // Fetch all existing comments
   getCoreEndpoints() : Observable<any[]> {
 
+    const search = 'some=param';
+
     // ...using get request
-    return this.http.get(`${this.baseUrl}/core/`)
+    return this.http.get(`${this.baseUrl}/core/`, {search})
     // ...and calling .json() on the response to return data
-      .map((res:Response) => res.json())
-      //...errors if any
+      .map((res: Response) => res.json())
+      // ...errors if any
       .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
 
   }
diff --git a/src/app/services/rest/instance.service.ts b/src/app/services/rest/instance.service.ts
new file mode 100644
index 0000000..c864e54
--- /dev/null
+++ b/src/app/services/rest/instance.service.ts
@@ -0,0 +1,25 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+
+// Imports
+import {AppConfig} from '../../config/app.config';
+import {AuthService} from './auth.service';
+import { Injectable }     from '@angular/core';
+import { Http, Response, Headers } from '@angular/http';
+import {XosHttp} from './xoshttp.service';
+import {Observable} from 'rxjs/Rx';
+
+// Import RxJs required methods
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/catch';
+
+@Injectable()
+export class InstanceService {
+  private baseUrl = AppConfig.apiEndpoint;
+  constructor (private http: XosHttp, private authService: AuthService) {}
+  // Fetch all existing instances
+  query() : Observable<any[]> {
+    return this.http.get(`${this.baseUrl}/core/instances/`)
+      .map((res: Response) => res.json())
+      .catch((error: any) => Observable.throw(error.response.json().error || 'Server error'));
+  }
+}
diff --git a/src/app/services/rest/xoshttp.service.ts b/src/app/services/rest/xoshttp.service.ts
new file mode 100644
index 0000000..5572683
--- /dev/null
+++ b/src/app/services/rest/xoshttp.service.ts
@@ -0,0 +1,55 @@
+import {Http, RequestOptionsArgs, Response, URLSearchParams} from '@angular/http';
+import {Injectable} from '@angular/core';
+import {Observable} from 'rxjs';
+import {AuthService} from './auth.service';
+/**
+ * Created by teone on 12/6/16.
+ */
+@Injectable()
+export class XosHttp {
+  constructor(
+    private http: Http,
+    private authService: AuthService
+  ) {
+  }
+
+  private checkOptions(options?: RequestOptionsArgs): RequestOptionsArgs {
+    // if options are not there, create them
+    if(!options){
+      options = {};
+    }
+    return options;
+  }
+
+  private getHeaders(options: RequestOptionsArgs): RequestOptionsArgs {
+    // add auth headers
+    options.headers = this.authService.getUserHeaders();
+    return options;
+  }
+
+  private getParams(options: RequestOptionsArgs): RequestOptionsArgs {
+    // add the no_hyperlinks param
+    if (!options.search) {
+      options.search = new URLSearchParams();
+    }
+
+    if (options.search instanceof URLSearchParams) {
+      options.search.set('no_hyperlinks', '1');
+    }
+    else if (typeof options.search === 'string') {
+      options.search += '&no_hyperlinks=1';
+    }
+    return options;
+  }
+
+  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
+
+    options = this.checkOptions(options);
+    options = this.getHeaders(options);
+    options = this.getParams(options);
+
+    return this.http.get(url, options)
+  }
+
+  // TODO add POST, PUT, DELETE declaration
+}
diff --git a/src/app/services/stores/instance.store.ts b/src/app/services/stores/instance.store.ts
new file mode 100644
index 0000000..a87630c
--- /dev/null
+++ b/src/app/services/stores/instance.store.ts
@@ -0,0 +1,54 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+
+import {Injectable} from '@angular/core';
+import {BehaviorSubject} from 'rxjs/Rx';
+import {IInstance} from '../../interfaces/instance.interface';
+import {InstanceService} from '../rest/instance.service';
+import * as _ from 'lodash';
+import {IWSEvent} from '../../interfaces/ws.interface';
+import {GlobalEvent} from '../websockets/websocket.global';
+
+@Injectable()
+export class InstanceStore {
+  private _instances: BehaviorSubject<IInstance[]> = new BehaviorSubject([]);
+  constructor(private instanceService: InstanceService, private globalEvent: GlobalEvent) {
+    this.loadInitialData();
+    this.globalEvent.list()
+      .filter((e: IWSEvent) => {
+        console.log('filter', e);
+        return e.model === 'Instance';
+      })
+      .subscribe(
+        (event: IWSEvent) => {
+
+          const collection = this._instances.value;
+
+          const exist = _.find(collection, (i) => {
+            return i.id === event.msg.object.id;
+          });
+
+          // remove in order to update
+          if (exist) {
+            _.remove(collection, {id: event.msg.object.id});
+          }
+          collection.push(event.msg.object);
+          this._instances.next(collection);
+        }
+      );
+  }
+
+  loadInitialData() {
+    this.instanceService.query()
+      .subscribe(
+        res => {
+          this._instances.next(res);
+        },
+        err => console.log('Error retrieving Instances', err)
+      );
+  }
+
+  query() {
+    return this._instances.asObservable();
+  }
+
+}
diff --git a/src/app/services/websockets/websocket.global.ts b/src/app/services/websockets/websocket.global.ts
new file mode 100644
index 0000000..ee62c12
--- /dev/null
+++ b/src/app/services/websockets/websocket.global.ts
@@ -0,0 +1,29 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+
+import {Injectable} from '@angular/core';
+import {BehaviorSubject} from 'rxjs/Rx';
+import * as io from 'socket.io-client';
+import {AppConfig} from '../../config/app.config';
+import {IWSEvent} from '../../interfaces/ws.interface';
+
+@Injectable()
+export class GlobalEvent {
+  private _events: BehaviorSubject<IWSEvent> = new BehaviorSubject<IWSEvent>({
+    model: 'XOS',
+    msg: {
+      changed_fields: []
+    }
+  });
+  private socket;
+  constructor() {
+    this.socket = io(AppConfig.websocketClient);
+    this.socket.on('event', (data: IWSEvent) => {
+      this._events.next(data);
+    });
+  }
+
+  list() {
+    return this._events.asObservable();
+  }
+
+}