tes.service.ts 20.3 KB
Newer Older
Chris Hines's avatar
Chris Hines committed
1
2
import { Injectable } from '@angular/core';
import { HttpClientModule, HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
Chris Hines's avatar
Chris Hines committed
3
import { Observable, Subject, BehaviorSubject, of, from } from 'rxjs';
4
import { fromEvent, throwError, Subscription } from 'rxjs';
Chris Hines's avatar
Chris Hines committed
5
6
import { catchError, map, tap } from 'rxjs/operators';
import { Job } from './job';
7
import { AppAction, Strudelapp, StrudelappInstance } from './strudelapp';
Chris Hines's avatar
Chris Hines committed
8
import { Computesite, Health } from './computesite';
9
import { APIServer } from './apiserver';
Chris Hines's avatar
Chris Hines committed
10
import { Identity, AuthToken, KeyCert, SshAuthzServer } from './identity';
11
12
import { BatchInterface } from './batchinterface';
import { ComputesitesService } from './computesites.service';
13
import { StrudelappsService } from './strudelapps.service';
Chris Hines's avatar
Chris Hines committed
14
import { timer } from 'rxjs/observable/timer';
Chris Hines's avatar
Chris Hines committed
15
import { repeat, takeUntil } from 'rxjs/operators';
Chris Hines's avatar
Chris Hines committed
16
import { LocationStrategy, Location } from '@angular/common';
Chris Hines's avatar
Chris Hines committed
17
import { ActivatedRoute, Router } from '@angular/router';
Chris Hines's avatar
Chris Hines committed
18
19
import { ModaldialogComponent } from './modaldialog/modaldialog.component';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material';
Chris Hines's avatar
Chris Hines committed
20
21
import { AuthorisationService } from './authorisation.service';
import { environment } from '../environments/environment';
Chris Hines's avatar
Chris Hines committed
22
import { BackendSelectionService } from './backend-selection.service';
Chris Hines's avatar
Chris Hines committed
23

Chris Hines's avatar
Chris Hines committed
24
25
/** The TES service contains ways to start Tunnels, and Execute programs
Its also responsible for querying a compute site for running jobs */
Chris Hines's avatar
Chris Hines committed
26
27


28

Chris Hines's avatar
Chris Hines committed
29
30
31
@Injectable({
  providedIn: 'root',
})
Chris Hines's avatar
Chris Hines committed
32
export class TesService {
33
34
35
36
public Base: string;
//public Base=environment.tesurl;
//private twsproxy = environment.twsurl;
private twsproxy: string;
Chris Hines's avatar
Chris Hines committed
37
// public Base='http://localhost:5000';
38
public statusMsg: BehaviorSubject<any>;
Chris Hines's avatar
Chris Hines committed
39
public jobs: any[];
Chris Hines's avatar
Chris Hines committed
40
// public joblist: BehaviorSubject<{ [id: string ]: Job[]}>;
Chris Hines's avatar
Chris Hines committed
41
42
//public joblist: BehaviorSubject<Job[]>;
//public userhealth: BehaviorSubject<Health[]>;
Chris Hines's avatar
Chris Hines committed
43

Chris Hines's avatar
Chris Hines committed
44
private timerSubscription: any;
Chris Hines's avatar
Chris Hines committed
45
private appwindow: any;
46
47
public apiserver: BehaviorSubject<APIServer>;
public apiservers: BehaviorSubject<APIServer[]>;
48
private updateJobSub: Subscription;
Chris Hines's avatar
Chris Hines committed
49
50
private updateUserHealthSub: Subscription;
private cachetincidents: BehaviorSubject<Health[]>;
51
private nextUpdate: Subscription;
Chris Hines's avatar
Chris Hines committed
52
private cancelRequests: Subject<string>;
53
54
public theme: BehaviorSubject<string>;
public identitySubject: BehaviorSubject<Identity>;
Chris Hines's avatar
Chris Hines committed
55
public appSubject: BehaviorSubject<Strudelapp>;
56

57
// public batchinterface: {[id: string] : BatchInterface};
Chris Hines's avatar
Chris Hines committed
58

59
  constructor(private http: HttpClient,
Chris Hines's avatar
Chris Hines committed
60
              public dialog: MatDialog,
Chris Hines's avatar
Chris Hines committed
61
62
              private computesitesService: ComputesitesService,
              private authorisationService: AuthorisationService,
Chris Hines's avatar
Chris Hines committed
63
              private strudelappsService: StrudelappsService,
Chris Hines's avatar
Chris Hines committed
64
              private backendSelectionService: BackendSelectionService,
Chris Hines's avatar
Chris Hines committed
65
              private location: Location ) {
Chris Hines's avatar
Chris Hines committed
66
67

    // this.joblist = new BehaviorSubject<{[id: string]: Job[]}>({});
Chris Hines's avatar
Chris Hines committed
68
69
70
    //this.joblist = new BehaviorSubject<Job[]>([]);
    //this.cachetincidents = new BehaviorSubject<Health[]>([]);
    //this.userhealth = new BehaviorSubject<Health[]>([{'stat':'ok','msg':''}])
Chris Hines's avatar
Chris Hines committed
71
    this.apiserver = new BehaviorSubject<APIServer>(null);
72
    this.apiservers = new BehaviorSubject<APIServer[]>([]);
Chris Hines's avatar
Chris Hines committed
73
    this.cancelRequests = new Subject<string>();
Chris Hines's avatar
Chris Hines committed
74
75
    //this.identitySubject = new BehaviorSubject<Identity>(null);
    //this.appSubject = new BehaviorSubject<Strudelapp>(null);
Chris Hines's avatar
Chris Hines committed
76

77
      this.backendSelectionService.apiserver.subscribe( (value) => { if (value != null) {this.twsproxy = value.tws ; this.Base = value.tes }});
78
    this.theme = new BehaviorSubject('strudel-light-theme');
79
    // this.batchinterface = {};
Chris Hines's avatar
Chris Hines committed
80
    // this.computesitesService.identities.subscribe(identities => this.startPolling(identities));
Chris Hines's avatar
Chris Hines committed
81
82
 }

Chris Hines's avatar
Chris Hines committed
83
84
85
public setStatusMsg(statusMsg: BehaviorSubject<any>) {
  this.statusMsg = statusMsg;
}
86

87
88
89
 public setTheme(theme: string) {
   this.theme.next(theme);
 }
90

Chris Hines's avatar
Chris Hines committed
91
 private buildParams(app: Strudelapp, identity: Identity, batchinterface: BatchInterface, appinst?: any): string {
92
   let params = new URLSearchParams();
Chris Hines's avatar
Chris Hines committed
93
94
95
   let id = identity.copy_skip_catalog();
   id.site.appCatalog = null;

Chris Hines's avatar
Chris Hines committed
96
97
98
   if (appinst!== null)  {
     params.set('appinstance',JSON.stringify(appinst));
   }
99
100
   params.set('app',JSON.stringify(app));
   params.set('interface',JSON.stringify(batchinterface));
Chris Hines's avatar
Chris Hines committed
101
   params.set('identity',JSON.stringify(id));
102
   return params.toString();
Chris Hines's avatar
Chris Hines committed
103
104
 }

105

106
 updateJoblist(resp, identity: Identity) {
107
108
109
110
111
112
113
114
     // resp contains a javascript represnetiation of a list of jobs
     // We want to update the joblist BUT we don't want to create new Job objects
     // instead we want to reuse existing job objects removing any which are no longer valid
     // and adding any new ones. We also want the list sorted from largest jobid to smallest (oldest job)
     // The sort is lexographic since sometimes jobids are a string rather than a number
   
   var joblist: Job[] = []
   var jobquery: Job[] = <Job[]>resp;
Chris Hines's avatar
Chris Hines committed
115
   var lastjoblist: Job[] = identity.joblist.value;
116
117
   var qjobids: any[] = [];
   var jobids: any[] = [];
Chris Hines's avatar
Chris Hines committed
118
119
120
   var j: Job;
   var newjob: Job;
   var idx: number;
121
122
123
124
125
126
127

   for (j of jobquery) {
       qjobids.push(j.jobid);
   }
   for (j of lastjoblist) {
       if (qjobids.indexOf(j.jobid) != -1) {
           if (jobids.indexOf(j.jobid) == -1) {
Chris Hines's avatar
Chris Hines committed
128
129
130
131
132
133
               idx = qjobids.indexOf(j.jobid)
               newjob = jobquery[idx]
               // These values in the job may change, but we need to keep using the old object
               j.state  = newjob.state;
               j.endtime = newjob.endtime;
               j.batch_host = newjob.batch_host;
134
135
136
137
               joblist.push(j);
               jobids.push(j.jobid);
           }
       }
138
   }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
   for (j of jobquery) {
       if (jobids.indexOf(j.jobid) == -1) {
           joblist.push(j);
           jobids.push(j.jobid);
       }
   }
       
   for (j of joblist) {
     if (j.app === undefined) {
       j.app = this.strudelappsService.getApp(j.name,identity.site.appCatalog.value);
     }
     if (j.identity == undefined) {
        j.identity = identity;
     }
     if (j.connectionState == undefined) {
         j.connectionState = 0;
     }
   }
   joblist = joblist.sort((a,b) =>  (a.jobid < b.jobid)? 1:-1);
Chris Hines's avatar
Chris Hines committed
158
   identity.joblist.next(joblist);
Chris Hines's avatar
Chris Hines committed
159
   //this.statusMsg.next(null);
160
161
 }

Chris Hines's avatar
Chris Hines committed
162
163
 private getBatchInterfaceError(error: any) {
   console.error(error);
164
165
 }

166
167


Chris Hines's avatar
Chris Hines committed
168
169
 private getCachetIncidentsError(error: any, identity: Identity) {
   return this.getJobsError(error, identity)
Chris Hines's avatar
Chris Hines committed
170
 }
171

Chris Hines's avatar
Chris Hines committed
172
173
 
 public cancelHealthRequests() {
Chris Hines's avatar
Chris Hines committed
174
    this.cancelRequests.next('cancel');
Chris Hines's avatar
Chris Hines committed
175
176
 }

Chris Hines's avatar
Chris Hines committed
177
 private getUserHealthError(error: any, identity: Identity) {
Chris Hines's avatar
Chris Hines committed
178
   console.log('user health error');
179
   identity.accountalerts.next([]);
Chris Hines's avatar
Chris Hines committed
180
181
   this.statusMsg.next("There was an error checking your user account");
   //return this.getJobsError(error,identity)
Chris Hines's avatar
Chris Hines committed
182
183
 }

Chris Hines's avatar
Chris Hines committed
184
185
 private getJobsError(error: any, identity: Identity) {
   identity.joblist.next([]);
Chris Hines's avatar
Chris Hines committed
186
   if (error.status == 0) {
Chris Hines's avatar
Chris Hines committed
187
     this.statusMsg.next("A network error occurred. Please try again later");
Chris Hines's avatar
Chris Hines committed
188
     return
189
   }
190
   console.error(error);
191
   if (error.status == 401) {
Chris Hines's avatar
Chris Hines committed
192
     this.statusMsg.next("Login expired. Please log in again.");
193
     this.authorisationService.updateAgentContents();
Chris Hines's avatar
Chris Hines committed
194
     return
195
   }
196
197
198
199
200
201
   if (error.status == 400) {
       if (error.error !== undefined && error.error.message !== undefined) {
        this.statusMsg.next(error.error.message);
       }
       return
   }
Chris Hines's avatar
Chris Hines committed
202
203
 }

Chris Hines's avatar
Chris Hines committed
204
205
206
207
 getJobs(identity: Identity) {
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: true};
  // remove from the job list any jobs for identities that we don't know about
Chris Hines's avatar
Chris Hines committed
208
  let oldjobs = identity.joblist.value;
209
210
211
  let bi = new BatchInterface();
  bi.cancelcmd = identity.site.cancelcmd;
  bi.statcmd = identity.site.statcmd;
212
213
214
215
216
  let params = new URLSearchParams();
  params.set('statcmd',JSON.stringify(identity.site.statcmd));
  params.set('host',JSON.stringify(identity.site.host));
  params.set('username',JSON.stringify(identity.username));
  
217
  this.updateJobSub = this.http.get<Job[]>(this.Base+'/stat'+'?'+params.toString(),options)
218
                .subscribe(resp => this.updateJoblist(resp, identity),
Chris Hines's avatar
Chris Hines committed
219
                           error => this.getJobsError(error, identity));
Chris Hines's avatar
Chris Hines committed
220
221
}

Chris Hines's avatar
Chris Hines committed
222
223
224
225
226
227
228
229
230
getUserHealth(identity: Identity)  {
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: true};
  // remove from the job list any jobs for identities that we don't know about
  let params = new URLSearchParams();
  if (identity === undefined || identity === null) {
    return
  }
  if (identity.site.userhealth === undefined) {
231
    identity.accountalerts.next([]);
Chris Hines's avatar
Chris Hines committed
232
233
234
235
236
237
238
239
    return
  }
  params.set('statcmd',JSON.stringify(identity.site.userhealth));
  params.set('host',JSON.stringify(identity.site.host));
  params.set('username',JSON.stringify(identity.username));
  
  this.updateUserHealthSub = this.http.get<Health[]>(this.Base+'/stat'+'?'+params.toString(),options)
    .pipe(takeUntil(this.cancelRequests))
Chris Hines's avatar
Chris Hines committed
240
241
242
243
    .subscribe(resp => this.addUserHealth(identity,resp), error => this.getUserHealthError(error,identity));
}

getHealthAlerts(identity: Identity) {
244
245
  identity.accountalerts.next(null);
  identity.systemalerts.next(null);
Chris Hines's avatar
Chris Hines committed
246
247
  this.getCachetIncidents(identity);
  this.getUserHealth(identity);
Chris Hines's avatar
Chris Hines committed
248
249
250
251
252
253
254
255
256
}

getCachetIncidents(identity: Identity) {
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: false};
  // remove from the job list any jobs for identities that we don't know about
  let params = new URLSearchParams();

  if (identity.site.cacheturis === undefined ||  identity.site.cacheturis.length == 0) {
257
    identity.systemalerts.next([]);
Chris Hines's avatar
Chris Hines committed
258
259
260
261
262
    return
  }
  for (let uri of identity.site.cacheturis) {
    this.http.get(uri,options)
      .pipe(takeUntil(this.cancelRequests))
Chris Hines's avatar
Chris Hines committed
263
      .subscribe(resp => this.addCachetIncidents(identity,resp), error => this.getCachetIncidentsError(error,identity));
Chris Hines's avatar
Chris Hines committed
264
265
266
  }
}

Chris Hines's avatar
Chris Hines committed
267
addCachetIncidents(identity,resp) {
268
  let ci = identity.systemalerts.value;
269
270
271
  if (ci == null) {
    ci = []
  }
Chris Hines's avatar
Chris Hines committed
272
273
274
275
276
277
278
279
280
  for (let i of resp.data) {
    if (i.status == 3 || i.status == 4) {
      continue;
    }
    let h = new Health();
    h.stat = 'error';
    h.msg = i.message;
    ci.push(h);
  }
281
  identity.systemalerts.next(ci);
Chris Hines's avatar
Chris Hines committed
282
283
284
}

addUserHealth(identity,resp) {
285
  let ci = identity.accountalerts.value;
286
287
288
  if (ci == null) {
    ci = []
  }
Chris Hines's avatar
Chris Hines committed
289
290
  console.log('in add User HEalth');
  for (let i of resp) {
Chris Hines's avatar
Chris Hines committed
291
292
293
    let h = new Health();
    h.stat = i.stat;
    h.msg = i.message;
294
295
296
    if (i.title != undefined) {
      h.title = i.title;
    }
Chris Hines's avatar
Chris Hines committed
297
298
299
    if (i.type != undefined) {
      h.type = i.type;
      h.data = i.data;
Chris Hines's avatar
Chris Hines committed
300
    }
Chris Hines's avatar
Chris Hines committed
301
    ci.push(h);
Chris Hines's avatar
Chris Hines committed
302
  }
303
304
  identity.accountalerts.next(ci);
  console.log('id health is',identity.accountalerts.value);
Chris Hines's avatar
Chris Hines committed
305
306
307
308
}



309
 public getconfig(app: Strudelapp, identity: Identity): Observable<any> {
Chris Hines's avatar
Chris Hines committed
310
311
312
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
   return this.http.get<any>(identity.site.url+'getconfig/'+app.name,options)
Chris Hines's avatar
Chris Hines committed
313
                                        // .pipe(catchError(this.handleError))
Chris Hines's avatar
Chris Hines committed
314
315
}

Chris Hines's avatar
Chris Hines committed
316
317
 submissionError(error: any) {
   if (error.status != 0) {
318
319
320
321
322
       if ('error' in error && 'message' in error.error) {
         this.statusMsg.next(error.error.message);
       } else {
         this.statusMsg.next('Job submission failed');
       }
Chris Hines's avatar
Chris Hines committed
323
324
   }
 }
325
326
327
328
329
330
331
332
333
334
 cancelError(error: any) {
     console.log('error canceling job',error);
   if (error.status != 0) {
       if ('error' in error && 'message' in error.error) {
         this.statusMsg.next(error.error.message);
       } else {
         this.statusMsg.next('Job submission failed');
       }
   }
 }
Chris Hines's avatar
Chris Hines committed
335
336
337

 buildBody(app: Strudelapp, appparams?: string) {
   return JSON.stringify({'app': app, 'appparams': appparams});
Chris Hines's avatar
Chris Hines committed
338
339
 }

340
 submit(app: Strudelapp, identity: Identity, batchinterface: BatchInterface, appparams?: any) {
Chris Hines's avatar
Chris Hines committed
341
342
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
343
   this.statusMsg.next('Submitting job');
Chris Hines's avatar
Chris Hines committed
344
   let paramstr = this.buildParams(app,identity,batchinterface);
Chris Hines's avatar
Chris Hines committed
345
   // let body = this.buildBody(app,appparams)
346
347
348
349
350
351
352
   let keys = JSON.stringify(this.authorisationService.getKeys());
   let loggedin = JSON.stringify(this.authorisationService.loggedInAuthZ.value);
   let ids = [];
     for (let id of this.computesitesService.ftidentities.value) {
         ids.push(id.copy_skip_catalog())
     }
   let body = {'app': app, 'appparams': appparams, 'keys': keys, 'ids': JSON.stringify(JSON.stringify(ids))}
Chris Hines's avatar
Chris Hines committed
353
   this.http.post<any>(this.Base+'/submit'+'?'+paramstr, body, options)
354
                                          .subscribe(resp => {
Chris Hines's avatar
Chris Hines committed
355
356
357
                                                              this.statusMsg.next(null)
                                                            },
                                                    error => this.submissionError(error));
Chris Hines's avatar
Chris Hines committed
358
359
 }

Chris Hines's avatar
Chris Hines committed
360
 submitted(resp: any, identity: Identity ) {
361
   console.log('submitted',resp);
Chris Hines's avatar
Chris Hines committed
362
   this.getJobs(identity);
363
364
 }

365
 cancel(job: Job) {
Chris Hines's avatar
Chris Hines committed
366
367
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
Chris Hines's avatar
Chris Hines committed
368
   // this.statusMsg.next(null);
Chris Hines's avatar
Chris Hines committed
369
   let data = {};
370
371
372
373
   let bi = new BatchInterface();
   bi.statcmd = job.identity.site.statcmd;
   bi.cancelcmd = job.identity.site.cancelcmd;
   let paramstr = this.buildParams(job.app,job.identity,bi);
374
   this.http.delete<any>(this.Base+'/cancel/'+job.jobid+'?'+paramstr, options)
375
376
         .subscribe(resp => this.submitted(resp,job.identity),
                    error => this.cancelError(error));
Chris Hines's avatar
Chris Hines committed
377
378
379
380
381
382
 }

 public watchAppwindow(appwindow, dialogRef) {
   if (appwindow.closed) {
     dialogRef.close();
   }
Chris Hines's avatar
Chris Hines committed
383
384
 }

385
 public getAppInstance(job: Job, action: AppAction) {
Chris Hines's avatar
Chris Hines committed
386
387
388
   let username = job.identity.username;
   let loginhost = job.identity.site.host;
   let batchhost = job.batch_host;
Chris Hines's avatar
Chris Hines committed
389
   let jobid = job.jobid;
Chris Hines's avatar
Chris Hines committed
390
   let params = new URLSearchParams;
391
392
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
393
   params.set('cmd',JSON.stringify(action.paramscmd));
Chris Hines's avatar
Chris Hines committed
394
395
   let paramstr = params.toString();
   job.connectionState = 1;
Chris Hines's avatar
Chris Hines committed
396
   console.log('in getAppInstance');
Chris Hines's avatar
Chris Hines committed
397
   this.http.get<string>(this.Base+'/appinstance/'+username+'/'+loginhost+'/'+batchhost+'/'+jobid+'?'+paramstr, options)
Chris Hines's avatar
Chris Hines committed
398
                // .pipe(catchError(this.handleError))
399
     .subscribe(resp =>  { job.appinst = resp; if (action.client != null) { this.createTunnel(job, action) } else { job.connectionState = 0} },
400
             error => { this.handleAppInstanceError(job,error) })
Chris Hines's avatar
Chris Hines committed
401
402
403
404
405
406
407
408
   // let paramstr = this.buildParams(job.app,job.identity,this.batchinterface[job.identity.repr()]);
   // let headers = new HttpHeaders();
   // let options = { headers: headers, withCredentials: true};
   // this.http.get<any>(this.Base+'/getappinst/'+paramstr,options)
   //                                      .pipe(catchError(this.handleError))
   //                                      .subscribe(resp =>  { job.appinst = <StrudelappInstance>resp; this.openAppWindow(job);});
 }

409
 public createTunnel(job: Job, action: AppAction) {
Chris Hines's avatar
Chris Hines committed
410
411
412
413
414
415
   let username = job.identity.username;
   let loginhost = job.identity.site.host;
   let batchhost = job.batch_host;
   let params = new URLSearchParams;
   let headers = new HttpHeaders();
   job.connectionState = 2;
416
417
418
419
420

     //    let sleepDuration = 20;
     //var now = new Date().getTime();
     //while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }

Chris Hines's avatar
Chris Hines committed
421
   let options = { headers: headers, withCredentials: true};
422
   //params.set('cmd',JSON.stringify(action.paramscmd));
Chris Hines's avatar
Chris Hines committed
423
424
   let paramstr = params.toString();
   this.http.post<string>(this.Base+'/createtunnel/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, job.appinst, options)
425
                .subscribe(() =>  { this.getAppUrl(job, action) } )
Chris Hines's avatar
Chris Hines committed
426
 }
Chris Hines's avatar
Chris Hines committed
427

428
 public getAppUrl(job: Job, action: AppAction) {
Chris Hines's avatar
Chris Hines committed
429
430
431
   let params = new URLSearchParams;
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
432
433
   let pseudoapp = {'client':{'redir':action.client.redir}};
   params.set('app',JSON.stringify(pseudoapp));
Chris Hines's avatar
Chris Hines committed
434
435
436
437
438
   params.set('appinst',JSON.stringify(job.appinst));
   let paramstr = params.toString();
   job.connectionState = 3;
   this.http.get<string>(this.Base+'/appurl?'+paramstr,options)
                .pipe(catchError(this.handleError))
439
                .subscribe(resp => {  job.connectionState = 0; this.openAppWindow(resp)});
Chris Hines's avatar
Chris Hines committed
440
441
442
443


 }

444
445
 public getInterface(job: Job, action: AppAction) {
   this.getAppInstance(job, action);
Chris Hines's avatar
Chris Hines committed
446
447
 }

448
 public openAppWindow(url: any) {
449
450
451
     var re = /^https:\/\/([a-z0-9\.-]+)\/?/;
     let twshost = this.twsproxy.replace(re,"$1");
     let windowloc = url.replace(/\{twsproxy\}/g,this.twsproxy).replace(/twshost/g,twshost);
Chris Hines's avatar
Chris Hines committed
452
     this.appwindow = window.open(windowloc);
453
454
455
456
457
458
     if (this.appwindow == null) {
         this.statusMsg.next('It looks like a window failed to open. Please check your popup blocker settings (Strudel 2 needs to be able to open a window to your application');
         return;
     }
     if (this.appwindow.closed) {
     }
Chris Hines's avatar
Chris Hines committed
459
460
 }

461
 public connect(job: Job, action: AppAction, appinst?: any) {
Chris Hines's avatar
Chris Hines committed
462
463
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
464
   this.getInterface(job,action); // getInterface will subsequently called getAppInstance, which will call createTunnel, which will openAppWindow
Chris Hines's avatar
Chris Hines committed
465
 }
Chris Hines's avatar
Chris Hines committed
466

Chris Hines's avatar
Chris Hines committed
467
468
469
470



public postAgentData(keyCert: KeyCert) {
471
472
473
474
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: true};

  this.statusMsg.next("Authorising ...")
Chris Hines's avatar
Chris Hines committed
475
  let data = {'key': keyCert.key, 'cert': keyCert.cert};
Chris Hines's avatar
Chris Hines committed
476
  return this.http.post<any>(this.Base+'/sshagent',data,options)
Chris Hines's avatar
Chris Hines committed
477
                      .pipe(catchError(this.handleError))
Chris Hines's avatar
Chris Hines committed
478

479
480
}

Chris Hines's avatar
Chris Hines committed
481
public postMkDir(id: Identity, path: string, name: string ) {
482
483
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: true};
Chris Hines's avatar
Chris Hines committed
484
485
486
487
  let params = new URLSearchParams;
  params.set('identity',JSON.stringify(id));
  params.set('path',JSON.stringify(path));

488
  return this.http.post<any>(this.Base+'/mkdir?'+params.toString(),name, options);
489
490
}

Chris Hines's avatar
Chris Hines committed
491
public getSftpData(id: Identity, path: string, cd: string ) {
492
493
  let headers = new HttpHeaders();
  let options = { headers: headers, withCredentials: true};
Chris Hines's avatar
Chris Hines committed
494
495
496
497
  let params = new URLSearchParams;
  params.set('identity',JSON.stringify(id));
  params.set('path',JSON.stringify(path));
  params.set('cd',JSON.stringify(cd));
498

Chris Hines's avatar
Chris Hines committed
499
  return this.http.get<any>(this.Base+'/ls?'+params.toString(),options)
500
                      // .pipe(catchError(this.handleError))
501

Chris Hines's avatar
Chris Hines committed
502
503
}

Chris Hines's avatar
Chris Hines committed
504
505


506
507
public getstatusMsgSubject(): BehaviorSubject<any> {
  return this.statusMsg;
Chris Hines's avatar
Chris Hines committed
508
509
}

Chris Hines's avatar
Chris Hines committed
510
511
512
513
514
private httperror(errorstr: string) {
  var re = /login expired/gi;
  let searchresult = errorstr.search(re);
  if (searchresult != -1) {
    this.statusMsg.next("Some authentication tokens have expired, you may need to log in again");
515
    console.error(errorstr);
Chris Hines's avatar
Chris Hines committed
516
    this.authorisationService.updateAgentContents();
Chris Hines's avatar
Chris Hines committed
517
  }
518
  console.error(errorstr);
Chris Hines's avatar
Chris Hines committed
519
}
Chris Hines's avatar
Chris Hines committed
520

Chris Hines's avatar
Chris Hines committed
521
522
523
524
525
526
527
528
529
// private networkError(error: HttpErrorResponse) {
//   if (error.error instanceof ErrorEvent) {
//     console.log('network error contacting TES backend');
//   } else {
//     return error;
//   }
// }


530
private handleAppInstanceError(job: Job, error: any) {
Chris Hines's avatar
Chris Hines committed
531
532
    console.log('in handle app instance error');
    console.log(error);
533
    job.connectionState=0;
Chris Hines's avatar
Chris Hines committed
534
535
    if (error.error !== undefined && error.error.message !== undefined) {
        this.statusMsg.next(error.error.message);
Chris Hines's avatar
Chris Hines committed
536
537
    } else if (error.error !== undefined && error.error.error !== undefined) {
      this.statusMsg.next(error.error.error.msg);
538
539
540
541
542
    } else {
        this.statusMsg.next(error);
    }
}

Chris Hines's avatar
Chris Hines committed
543
private handleError(error: HttpErrorResponse) {
544
545
  console.error('in handleError');
  console.error(error);
Chris Hines's avatar
Chris Hines committed
546
547
548
549
550
551
552
553
  if (error.error instanceof ErrorEvent) {
    // A client-side or network error occurred. Handle it accordingly.
    return throwError("Hmm, that didn't work. If you're using a local connection, please make sure Strudel-TES is running.");
  } else {
    // Not sure if this code works correctly. It should update identities in case the error is
    // that the user isn't allowed to run the job

    var re = /identity/gi;
Chris Hines's avatar
Chris Hines committed
554
555
556
557
558
559
560
561
562
    if (error.error.message != undefined) {
      let searchresult = error.error.message.search(re);
      if (searchresult != -1) {
        // this.getIdentities();
        return throwError('login expired, refreshing');
      }
      return throwError(error.error.message)
    } else {
      return throwError('An error occured but I\'m not sure exactly what. Please try again latter or contact the sys admins');
Chris Hines's avatar
Chris Hines committed
563
    }
Chris Hines's avatar
Chris Hines committed
564
565
566
    // this.statusMsg.next("There was an error submitting that job. The backend gave me the message: " + error.error.message);

  }
Chris Hines's avatar
Chris Hines committed
567
}
Chris Hines's avatar
Chris Hines committed
568
569
570



Chris Hines's avatar
Chris Hines committed
571
}