diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 58c51f15..e3c4580f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -83,6 +83,7 @@ import { ToasterErrorHandler } from "./common/error-handlers/toaster-error-handl import { environment } from "../environments/environment"; import { RavenState } from "./common/error-handlers/raven-state-communicator"; import { ServerDiscoveryComponent } from "./components/servers/server-discovery/server-discovery.component"; +import { ServerDatabase } from './services/server.database'; if (environment.production) { @@ -176,7 +177,8 @@ if (environment.production) { SelectionManager, InRectangleHelper, DrawingsDataSource, - ServerErrorHandler + ServerErrorHandler, + ServerDatabase ], entryComponents: [ AddServerDialogComponent, diff --git a/src/app/components/servers/server-discovery/server-discovery.component.html b/src/app/components/servers/server-discovery/server-discovery.component.html index af4c0a46..15d9df49 100644 --- a/src/app/components/servers/server-discovery/server-discovery.component.html +++ b/src/app/components/servers/server-discovery/server-discovery.component.html @@ -1,9 +1,9 @@ - + - We've discovered GNS3 server on 127.0.0.1:3080, would you like to add it? + We've discovered GNS3 server on {{ discoveredServer.ip }}:{{ discoveredServer.port }}, would you like to add to the list? - - + + diff --git a/src/app/components/servers/server-discovery/server-discovery.component.spec.ts b/src/app/components/servers/server-discovery/server-discovery.component.spec.ts index 5379ff82..6ce2616c 100644 --- a/src/app/components/servers/server-discovery/server-discovery.component.spec.ts +++ b/src/app/components/servers/server-discovery/server-discovery.component.spec.ts @@ -1,12 +1,13 @@ import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; +import { MatCardModule } from "@angular/material"; + +import { Observable } from "rxjs/Rx"; import { ServerDiscoveryComponent } from './server-discovery.component'; -import { MatCardModule } from "@angular/material"; import { VersionService } from "../../../services/version.service"; -import {MockedVersionService} from "../../../services/version.service.spec"; -import {Observable} from "rxjs/Rx"; -import {Version} from "../../../models/version"; -import {Server} from "../../../models/server"; +import { MockedVersionService } from "../../../services/version.service.spec"; +import { Version } from "../../../models/version"; +import { Server } from "../../../models/server"; describe('ServerDiscoveryComponent', () => { @@ -36,31 +37,28 @@ describe('ServerDiscoveryComponent', () => { expect(component).toBeTruthy(); }); - // it('should discovery new server with no added yet', () => { - // const server = component.discovery([]); - // expect(server.ip); - // }); - describe('isAvailable', () => { - it('should return version when server is available', () => { - const version = new Version(); - version.version = '2.1.8'; - const getVersionSpy = spyOn(mockedVersionService, 'get') - .and.returnValue(Observable.of(version)); - - component.isServerAvailable('127.0.0.1', 3080).subscribe((ver) => { - expect(ver.version).toEqual('2.1.8'); - }); - + it('should return server object when server is available', () => { const server = new Server(); server.ip = '127.0.0.1'; server.port = 3080; + + const getVersionSpy = spyOn(mockedVersionService, 'get') + .and.returnValue(Observable.of(server)); + + component.isServerAvailable('127.0.0.1', 3080).subscribe((s) => { + expect(s.ip).toEqual('127.0.0.1'); + expect(s.port).toEqual(3080); + }); + expect(getVersionSpy).toHaveBeenCalledWith(server); }); it('should throw error once server is not available', () => { - const version = new Version(); - version.version = '2.1.8'; + const server = new Server(); + server.ip = '127.0.0.1'; + server.port = 3080; + const getVersionSpy = spyOn(mockedVersionService, 'get') .and.returnValue(Observable.throwError(new Error("server is unavailable"))); let hasExecuted = false; @@ -70,18 +68,15 @@ describe('ServerDiscoveryComponent', () => { expect(err.toString()).toEqual('Error: server is unavailable'); }); - const server = new Server(); - server.ip = '127.0.0.1'; - server.port = 3080; expect(getVersionSpy).toHaveBeenCalledWith(server); expect(hasExecuted).toBeTruthy(); }); }); - describe("discovery", () => { - it('should discovery single server', () => { - // component.discovery([]). - }); - }); + // describe("discovery", () => { + // it('should discovery single server', () => { + // component.discovery([]); + // }); + // }); }); diff --git a/src/app/components/servers/server-discovery/server-discovery.component.ts b/src/app/components/servers/server-discovery/server-discovery.component.ts index 3e434b97..65a13ae2 100644 --- a/src/app/components/servers/server-discovery/server-discovery.component.ts +++ b/src/app/components/servers/server-discovery/server-discovery.component.ts @@ -1,8 +1,15 @@ import { Component, OnInit } from '@angular/core'; + +import { Observable } from "rxjs/Rx"; +import { map } from "rxjs//operators"; + import { Server } from "../../../models/server"; import { VersionService } from "../../../services/version.service"; -import {Version} from "../../../models/version"; -import {Observable} from "rxjs/Rx"; +import { Version } from "../../../models/version"; +import { forkJoin } from 'rxjs'; +import { ServerService } from '../../../services/server.service'; +import { ServerDatabase } from '../../../services/server.database'; + @Component({ selector: 'app-server-discovery', @@ -13,26 +20,73 @@ export class ServerDiscoveryComponent implements OnInit { private defaultServers = [{ ip: '127.0.0.1', port: 3080 + }, + { + ip: '127.0.0.1', + port: 3085 } ]; + discoveredServer: Server; + constructor( - private versionService: VersionService + private versionService: VersionService, + private serverService: ServerService, + private serverDatabase: ServerDatabase ) {} ngOnInit() { - + forkJoin( + Observable.fromPromise(this.serverService.findAll()).pipe(map((s: Server[]) => s)), + this.discovery() + ).subscribe(([local, discovered]) => { + local.forEach((added) => { + discovered = discovered.filter((server) => { + return !(server.ip == added.ip && server.port == added.port); + }); + }); + if(discovered.length > 0) { + this.discoveredServer = discovered.shift(); + } + }); } - discovery(servers: Server[]): Observable { - // this.defaultServers.forEach(()); - return Observable.of(new Server()); + discovery(): Observable { + const queries: Observable[] = []; + + this.defaultServers.forEach((testServer) => { + queries.push(this.isServerAvailable(testServer.ip, testServer.port).catch((err) => { + return Observable.of(null); + })); + }); + + return new Observable((observer) => { + forkJoin(queries).subscribe((discoveredServers) => { + observer.next(discoveredServers.filter((s) => s != null)); + observer.complete(); + }); + }); } - isServerAvailable(ip: string, port: number): Observable { + isServerAvailable(ip: string, port: number): Observable { const server = new Server(); server.ip = ip; server.port = port; - return this.versionService.get(server); + return this.versionService.get(server).flatMap((version: Version) => Observable.of(server)); + } + + ignore(server: Server) { + this.discoveredServer = null; + } + + accept(server: Server) { + if(server.name == null) { + server.name = server.ip; + } + + this.serverService.create(server).then((created: Server) => { + this.serverDatabase.addServer(created); + this.discoveredServer = null; + }); } } diff --git a/src/app/components/servers/servers.component.ts b/src/app/components/servers/servers.component.ts index b90c8e77..5be47f31 100644 --- a/src/app/components/servers/servers.component.ts +++ b/src/app/components/servers/servers.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject, OnInit, Injectable } from '@angular/core'; import { DataSource } from "@angular/cdk/collections"; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; @@ -7,6 +7,8 @@ import { map } from "rxjs/operators"; import { Server } from "../../models/server"; import { ServerService } from "../../services/server.service"; +import { ServerDatabase } from '../../services/server.database'; + @Component({ @@ -15,11 +17,13 @@ import { ServerService } from "../../services/server.service"; styleUrls: ['./servers.component.css'] }) export class ServersComponent implements OnInit { - serverDatabase = new ServerDatabase(); dataSource: ServerDataSource; displayedColumns = ['id', 'name', 'ip', 'port', 'actions']; - constructor(private dialog: MatDialog, private serverService: ServerService) {} + constructor( + private dialog: MatDialog, + private serverService: ServerService, + private serverDatabase: ServerDatabase) {} ngOnInit() { this.serverService.findAll().then((servers: Server[]) => { @@ -82,32 +86,6 @@ export class AddServerDialogComponent implements OnInit { } -export class ServerDatabase { - dataChange: BehaviorSubject = new BehaviorSubject([]); - - get data(): Server[] { - return this.dataChange.value; - } - - public addServer(server: Server) { - const servers = this.data.slice(); - servers.push(server); - this.dataChange.next(servers); - } - - public addServers(servers: Server[]) { - this.dataChange.next(servers); - } - - public remove(server: Server) { - const index = this.data.indexOf(server); - if (index >= 0) { - this.data.splice(index, 1); - this.dataChange.next(this.data.slice()); - } - } -} - export class ServerDataSource extends DataSource { constructor(private serverDatabase: ServerDatabase) { super(); diff --git a/src/app/services/server.database.ts b/src/app/services/server.database.ts new file mode 100644 index 00000000..989a6e50 --- /dev/null +++ b/src/app/services/server.database.ts @@ -0,0 +1,33 @@ +import { Injectable } from "@angular/core"; +import { BehaviorSubject } from "rxjs"; +import { Server } from "../models/server"; + + +@Injectable() +export class ServerDatabase { + dataChange: BehaviorSubject = new BehaviorSubject([]); + + constructor() {} + + get data(): Server[] { + return this.dataChange.value; + } + + public addServer(server: Server) { + const servers = this.data.slice(); + servers.push(server); + this.dataChange.next(servers); + } + + public addServers(servers: Server[]) { + this.dataChange.next(servers); + } + + public remove(server: Server) { + const index = this.data.indexOf(server); + if (index >= 0) { + this.data.splice(index, 1); + this.dataChange.next(this.data.slice()); + } + } +} \ No newline at end of file