diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 71c1ee38fe9442b4bfb2764bf84eb21793da5cb4..66fc38e19eb4cbbea987eab02778dc4a55fc7123 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -27,6 +27,7 @@ import { FileExplorerModule } from './file-explorer/file-explorer.module'; import { TesService} from './tes.service'; +import { BackendSelectionService} from './backend-selection.service'; import { SubmitAppService } from './submit-app.service'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @@ -97,7 +98,7 @@ import { ModaldialogComponent } from './modaldialog/modaldialog.component' ], entryComponents: [ LogoutdialogComponent, LaunchDialogComponent, ModaldialogComponent], - providers: [ StrudelappsService, ComputesitesService, TesService, SubmitAppService, MatDialog, AuthorisationService], + providers: [ StrudelappsService, ComputesitesService, TesService, SubmitAppService, MatDialog, AuthorisationService,BackendSelectionService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/authorisation.service.ts b/src/app/authorisation.service.ts index ce21cbe744114af351c2cef723f517df19253846..46137e200315ae8c29b550df9111975480f461dd 100644 --- a/src/app/authorisation.service.ts +++ b/src/app/authorisation.service.ts @@ -11,7 +11,7 @@ import * as forge from "node-forge"; import { Identity, AuthToken, KeyCert, SshAuthzServer } from './identity'; import {BehaviorSubject} from 'rxjs/BehaviorSubject'; import {Subject} from 'rxjs/Subject'; -import {TesService} from './tes.service'; +import {BackendSelectionService} from './backend-selection.service'; import { throwError } from 'rxjs'; import { environment } from '../environments/environment'; @@ -41,6 +41,7 @@ export class AuthorisationService { private locationStrategy: LocationStrategy, private route: ActivatedRoute, private router: Router, + private backendSelectionService: BackendSelectionService, private location: Location) { console.log('created AuthorisationService'); // this.token = new BehaviorSubject<AuthToken>(new AuthToken('','')); @@ -58,6 +59,7 @@ export class AuthorisationService { this.keys = []; this.getSshAuthzServers(); this.keys = []; + this.backendSelectionService.apiserver.subscribe((value) => { this.backendURI = value.tes ; this.updateAgentContents() }) this.agentContents.subscribe((value) => this.updateLoggedAuthZ()); this.sshAuthzServers.subscribe((value) => this.updateLoggedAuthZ()); } @@ -224,7 +226,10 @@ public getKeys(id?: Identity) { } public updateAgentContents() { - this.statusMsg.next("Updating the list of available accounts"); + if (this.statusMsg !== undefined) { + this.statusMsg.next("Updating the list of available accounts"); + }; + console.log('querying ',this.backendURI+'/sshagent'); let headers = new HttpHeaders(); let options = { headers: headers, withCredentials: true}; var anyvar: any; diff --git a/src/app/backend-selection.service.spec.ts b/src/app/backend-selection.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4223a184b4c0ce23b933107c7cc999d8ec8d1669 --- /dev/null +++ b/src/app/backend-selection.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { BackendSelectionService } from './backend-selection.service'; + +describe('BackendSelectionService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: BackendSelectionService = TestBed.get(BackendSelectionService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/backend-selection.service.ts b/src/app/backend-selection.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..a457110f261ad444ce9ceb3de4e509ebef3b4b27 --- /dev/null +++ b/src/app/backend-selection.service.ts @@ -0,0 +1,70 @@ +import { Injectable } from '@angular/core'; +import { APIServer } from './apiserver'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import { HttpClientModule, HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; +import { environment } from '../environments/environment'; + +@Injectable({ + providedIn: 'root' +}) +export class BackendSelectionService { + + public apiservers: BehaviorSubject<APIServer[]>; + public apiserver: BehaviorSubject<APIServer>; + + constructor(private http: HttpClient) { + this.apiservers = new BehaviorSubject([]); + this.apiserver = new BehaviorSubject(undefined); + this.initApiServer(); + this.getAPIServers(); + } + + private initApiServer() { + try { + this.apiserver.next(<APIServer>JSON.parse(localStorage.getItem('apiserver'))); + } catch { + this.apiserver.next(<APIServer>environment.apiserver); + } + } + + private saveLastApiServer(s: APIServer) { + console.log('saving api server value to local storage') + localStorage.setItem('apiserver', JSON.stringify(s)); + } + + setApiServer(server: APIServer) { + console.log('calling setAPIServer'); + this.apiserver.next(server); + console.log(this.apiserver); + this.saveLastApiServer(this.apiserver.value) + } + + getAPIServers() { + let headers = new HttpHeaders(); + let options = { headers: headers, withCredentials: false}; + this.http.get<APIServer[]>('./assets/config/apiservers.json',options) + .subscribe(resp => this.updateAPIServers(resp)); + } + + private updateAPIServers(resp) { + var s: APIServer; + var list: APIServer[] = [] + var current: APIServer; + var found: boolean; + current = this.apiserver.value; + found = false; + for (s of <APIServer[]>resp) { + if (s.name == current.name) { + list.push(current); + found = true; + } else { + list.push(s); + } + } + if (!found) { + list.push(current); + } + this.apiservers.next(list); + } + +} diff --git a/src/app/job/job.component.html b/src/app/job/job.component.html index e11bec3f7edb4dec5ed7af8e93b2bbaa1a7d4589..92e798fb144f27290f9b08d7ee95f8b56a7839ca 100644 --- a/src/app/job/job.component.html +++ b/src/app/job/job.component.html @@ -17,7 +17,7 @@ Cancel </button> </div> - <div fxFlex *ngIf="available"> + <div fxFlex *ngIf="jobdata.state == 'RUNNING'"> <button mat-button (click)="onConnect()" [disabled]="busy"> Connect </button> diff --git a/src/app/keygen/keygen.component.ts b/src/app/keygen/keygen.component.ts index d944f966a631cf9b3938ab309821130722eebf64..a96b1e7ba916debb2877a3accd21addb7937e743 100644 --- a/src/app/keygen/keygen.component.ts +++ b/src/app/keygen/keygen.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { AuthorisationService } from '../authorisation.service'; +import {TesService} from '../tes.service'; import { Router, NavigationStart } from '@angular/router'; import { timer } from 'rxjs/observable/timer'; @@ -13,7 +14,8 @@ import { timer } from 'rxjs/observable/timer'; }) export class KeygenComponent implements OnInit { - constructor(private router: Router, private authService: AuthorisationService) { } + constructor(private router: Router, private tesService: TesService, private authService: AuthorisationService) { } + //constructor(private router: Router, private authService: AuthorisationService) { } ngOnInit() { // The sequence is tricky here: diff --git a/src/app/launcher/launcher.component.html b/src/app/launcher/launcher.component.html index 768bba7e6f8e208fa6bd5f232d39b56e3aa19f5a..474d242f078abdb480aa8d91b5c6588fbee31673 100644 --- a/src/app/launcher/launcher.component.html +++ b/src/app/launcher/launcher.component.html @@ -41,17 +41,11 @@ Advanced Options </mat-expansion-panel-header> Select an API server - <!--(selectionChange)="tesService.setApiServer($event.value)" [compareWith]="tesService.compareServers"--> - <mat-select [ngModel]="selectedApiServer" (selectionChange)="tesService.setApiServer($event.value)"> - <mat-option *ngFor="let apis of tesService.apiservers|async" [value]="apis"> + <mat-select [ngModel]="selectedApiServer" (selectionChange)="backendSelectionService.setApiServer($event.value)"> + <mat-option *ngFor="let apis of backendSelectionService.apiservers|async" [value]="apis"> {{ apis.name }} </mat-option> </mat-select> - <!--<mat-select [ngModel]="tesService.apiserver | async" (ngModelChange)="tesService.setApiServer($event)"> - <mat-option *ngFor="let apis of tesService.apiservers|async" [value]="apis"> - {{ apis.name }} - </mat-option> - </mat-select>--> </mat-expansion-panel> </mat-accordion> </mat-sidenav> diff --git a/src/app/launcher/launcher.component.ts b/src/app/launcher/launcher.component.ts index 608faa87feaf9ccf282957277c5cebfc438a40c0..dfdcb9d6d824385a343e90cc4edc478a81e04fb1 100644 --- a/src/app/launcher/launcher.component.ts +++ b/src/app/launcher/launcher.component.ts @@ -10,6 +10,7 @@ import { repeat } from 'rxjs/operators'; import {Strudelapp} from '../strudelapp'; import { StrudelappsService } from '../strudelapps.service'; import { TesService } from '../tes.service'; +import {BackendSelectionService } from '../backend-selection.service'; import { AuthorisationService } from '../authorisation.service'; import { Identity } from '../identity'; import { Computesite } from '../computesite'; @@ -45,17 +46,18 @@ export class LauncherComponent implements OnInit { constructor( public dialog: MatDialog, public tesService: TesService, + public backendSelectionService: BackendSelectionService, public authService: AuthorisationService, public computeSitesService: ComputesitesService, ) { this.authService.sshAuthzServers.subscribe(o => {this.sshauthzservers = o}); this.identitySubject = new BehaviorSubject(undefined); - this.tesService.apiserver.subscribe((s) => this.selectedApiServer = s); + this.backendSelectionService.apiserver.subscribe((s) => this.selectedApiServer = s); } ngOnInit() { this.strudelapps = []; - setTimeout( () => this.authService.updateAgentContents() ) + // setTimeout( () => this.authService.updateAgentContents() ) } diff --git a/src/app/tes.service.ts b/src/app/tes.service.ts index 2f78fb03b532031bb40b689fc1c4cf0ec105b7ec..6e305d1edc58a1bd5eb5132a6d706dae8b702312 100644 --- a/src/app/tes.service.ts +++ b/src/app/tes.service.ts @@ -22,6 +22,7 @@ import { ModaldialogComponent } from './modaldialog/modaldialog.component'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material'; import { AuthorisationService } from './authorisation.service'; import { environment } from '../environments/environment'; +import { BackendSelectionService } from './backend-selection.service'; /** The TES service contains ways to start Tunnels, and Execute programs Its also responsible for querying a compute site for running jobs */ @@ -55,17 +56,18 @@ public apiservers: BehaviorSubject<APIServer[]>; private computesitesService: ComputesitesService, private authorisationService: AuthorisationService, private strudelappsService: StrudelappsService, + private backendSelectionService: BackendSelectionService, private location: Location ) { this.busy = new BehaviorSubject<boolean>(false); // this.joblist = new BehaviorSubject<{[id: string]: Job[]}>({}); this.joblist = new BehaviorSubject<Job[]>([]); - this.apiserver = new BehaviorSubject<APIServer>(null); + this.apiserver = new BehaviorSubject<APIServer>(null); this.apiservers = new BehaviorSubject<APIServer[]>([]); this.timerSubscription = null; this.appwindowWatcher = null; - this.getAPIServers(); + this.backendSelectionService.apiserver.subscribe( (value) => { this.twsproxy = value.tws ; this.Base = value.tes }); // this.batchinterface = {}; // this.computesitesService.identities.subscribe(identities => this.startPolling(identities)); } @@ -74,71 +76,6 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) { this.statusMsg = statusMsg; } -public compareServer(a: APIServer, b: APIServer) { - if (a.name == b.name) { - return true; - } - return false; -} - -private loadLastApiServer() { - var lastserver: APIServer; - try { - console.log('loading api server from local storage'); - lastserver = JSON.parse(localStorage.getItem('apiserver')); - } catch { - lastserver = undefined; - } - // If we got a value for the last server used, we need to search the list of available servers for a match - if (lastserver != undefined) { - for (let s of this.apiservers.value) { - if (lastserver.name == s.name) { - this.apiserver.next(s); - } - } - } - // If we didn't get a match, we'll just pick the first available server - if (this.apiserver.value == null) { - if (this.apiservers.value.length > 0) { - this.apiserver.next(this.apiservers.value[0]); - } else { - // If there are NO available backed servers ... well we shouldn't get here. - // In the future if we start detecting backends as down for maintainnce it might happen - this.statusMsg.next("There was an error selecting a backend API server. Please try reloading"); - return; - } - } - this.Base = this.apiserver.value.tes; - this.twsproxy = this.apiserver.value.tws; - this.authorisationService.backendURI = this.Base; - console.log('load succeeded'); -} -private saveLastApiServer(s: APIServer) { - console.log('saving api server value to local storage') - localStorage.setItem('apiserver', JSON.stringify(s)); -} - - setApiServer(server: APIServer) { - console.log('calling setAPIServer'); - this.apiserver.next(server); - console.log(this.apiserver); - this.Base = this.apiserver.value.tes; - this.twsproxy = this.apiserver.value.tws; - this.saveLastApiServer(this.apiserver.value) - } - - getAPIServers() { - let headers = new HttpHeaders(); - let options = { headers: headers, withCredentials: false}; - this.http.get<SshAuthzServer[]>('./assets/config/apiservers.json',options) - .subscribe(resp => this.updateAPIServers(resp)); - } - - private updateAPIServers(resp) { - this.apiservers.next(<APIServer[]>resp); - this.loadLastApiServer(); - } - private buildParams(app: Strudelapp, identity: Identity, batchinterface: BatchInterface, appinst?: any): string { let params = new URLSearchParams(); diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index fd24d66caebb61cd79859599512fea80eb778c18..4bf7bba304b59b83788fa35c19e8c25d1c108eb3 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,6 +1,11 @@ export const environment = { production: true, - tesurl: "https://strudel2-test.cloud.cvl.org.au/tes", - twsurl: "https://strudel2-test.cloud.cvl.org.au" + apiserver: { + tes: "https://strudel2-test.cloud.cvl.org.au/tes", + tws: "https://strudel2-test.cloud.cvl.org.au", + name: "Test" + } + + }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 998149d822dce8e35f7a325768b445fc78ad52de..0c3d3a6e41c74d8b2817db3be63c3d3a653478fb 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -5,6 +5,9 @@ export const environment = { production: false, - tesurl: "https://strudel2-test.cloud.cvl.org.au/tes", - twsurl: "https://strudel2-test.cloud.cvl.org.au" + apiserver: { + tes: "https://strudel2-test.cloud.cvl.org.au/tes", + tws: "https://strudel2-test.cloud.cvl.org.au", + name: "Test" + } };