Skip to content
Snippets Groups Projects
backend.service.ts 6.23 KiB
Newer Older
  • Learn to ignore specific revisions
  • import {
      CheckConfig,
      NetworkRequestTestResult,
      UnitAndPlayerContainer,
      SysCheckReport
    } from './sys-check.interfaces';
    
    Martin Mechtel's avatar
    Martin Mechtel committed
    import { Injectable, Inject } from '@angular/core';
    
    import { HttpClient } from '@angular/common/http';
    
    paflov's avatar
    paflov committed
    import { Observable, of } from 'rxjs';
    
    import { catchError, map } from 'rxjs/operators';
    
    import { ErrorHandler, ServerError } from 'iqb-components';
    
    Martin Mechtel's avatar
    Martin Mechtel committed
    
    
    @Injectable({
      providedIn: 'root'
    })
    export class BackendService {
    
    
    Martin Mechtel's avatar
    Martin Mechtel committed
      constructor(
    
        @Inject('SERVER_URL') private readonly serverUrl: string,
    
        private http: HttpClient
      ) {}
    
    
      public getCheckConfigData(workspaceId: number, sysCheckName: string): Observable<CheckConfig> {
    
    Martin Mechtel's avatar
    Martin Mechtel committed
        return this.http
    
          .get<CheckConfig>(this.serverUrl + `workspace/${workspaceId}/sys-check/${sysCheckName}`)
          .pipe(
            catchError(() => {
              const myreturn: CheckConfig = null;
    
    Martin Mechtel's avatar
    Martin Mechtel committed
              return of(myreturn);
            })
          );
      }
    
      public saveReport(workspaceId: number, sysCheckName: string, sysCheckReport: SysCheckReport): Observable<Boolean|ServerError> {
    
        return this.http
    
    paf's avatar
    paf committed
          .put<boolean>(this.serverUrl + `workspace/${workspaceId}/sys-check/${sysCheckName}/report`, {...sysCheckReport});
    
      public getUnitAndPlayer(workspaceId: number, sysCheckName: string): Observable<UnitAndPlayerContainer|ServerError> {
    
        const startingTime = BackendService.getMostPreciseTimestampBrowserCanProvide();
    
    Martin Mechtel's avatar
    Martin Mechtel committed
        return this.http
    
          .get<UnitAndPlayerContainer>(this.serverUrl + `workspace/${workspaceId}/sys-check/${sysCheckName}/unit-and-player`)
    
          .pipe(map(data => {
              data.duration = BackendService.getMostPreciseTimestampBrowserCanProvide() - startingTime;
              return data;
    
      public benchmarkDownloadRequest(requestedDownloadSize: number): Promise<NetworkRequestTestResult> {
    
        const serverUrl = this.serverUrl;
    
        const cacheKiller = '&uid=' + (new Date().getTime());
    
        const testResult: NetworkRequestTestResult = {
          type: 'downloadTest',
          size: requestedDownloadSize,
    
    paflov's avatar
    paflov committed
          error: null,
          speedInBPS: 0
    
        return new Promise(function(resolve) {
    
          const xhr = new XMLHttpRequest();
    
          xhr.open('GET', serverUrl + `speed-test/random-package/${requestedDownloadSize}${cacheKiller}`, true);
    
    
          xhr.timeout = 45000;
    
          xhr.onload = () => {
            if (xhr.status !== 200) {
              testResult.error = `Error ${xhr.statusText} (${xhr.status}) `;
    
            // tslint:disable-next-line:triple-equals
    
            if (xhr.response.toString().length != requestedDownloadSize) {
    
              testResult.error = `Error: Data package has wrong size! ${requestedDownloadSize} ` + xhr.response.toString().length;
            }
            const currentTime = testResult.duration = BackendService.getMostPreciseTimestampBrowserCanProvide();
    
            // console.log({'c': currentTime, 's': startingTime});
    
            testResult.duration = currentTime - startingTime;
    
    paflov's avatar
    paflov committed
            resolve(testResult);
    
          };
    
          xhr.onerror = () => {
            testResult.error = `Network Error ${xhr.statusText} (${xhr.status}) `;
            resolve(testResult);
          };
    
          xhr.ontimeout = () => {
            testResult.duration = xhr.timeout;
            testResult.error = 'timeout';
            resolve(testResult);
          };
    
          const startingTime = BackendService.getMostPreciseTimestampBrowserCanProvide();
    
          xhr.setRequestHeader('Content-Type', 'application/json');
          xhr.send(`{"size":"${requestedDownloadSize}"}`);
    
    paflov's avatar
    paflov committed
      }
    
    
      public benchmarkUploadRequest(requestedUploadSize: number): Promise<NetworkRequestTestResult> {
    
    paflov's avatar
    paflov committed
        const serverUrl = this.serverUrl;
        const randomContent = BackendService.generateRandomContent(requestedUploadSize);
        const testResult: NetworkRequestTestResult = {
          type: 'uploadTest',
          size: requestedUploadSize,
          duration: 10000,
          error: null,
          speedInBPS: 0
        };
    
    
        return new Promise(function(resolve) {
    
    paflov's avatar
    paflov committed
    
          const xhr = new XMLHttpRequest();
    
          xhr.open('POST', serverUrl + 'speed-test/random-package', true);
    
    paflov's avatar
    paflov committed
    
          xhr.timeout = 10000;
    
          xhr.setRequestHeader('Content-Type', 'text/plain');
    
          xhr.onload = () => {
    
            if (xhr.status !== 200) {
              testResult.error = `Error ${xhr.statusText} (${xhr.status}) `;
            }
    
            const currentTime = BackendService.getMostPreciseTimestampBrowserCanProvide();
            testResult.duration = currentTime - startingTime;
    
            try {
    
              const response = JSON.parse(xhr.response);
    
              const arrivingSize = parseFloat(response['packageReceivedSize']);
    
              // tslint:disable-next-line:triple-equals
    
              if (arrivingSize != requestedUploadSize) {
    
    paflov's avatar
    paflov committed
                testResult.error = `Error: Data package has wrong size! ${requestedUploadSize} != ${arrivingSize}`;
              }
            } catch (e) {
              testResult.error = `bogus server response`;
            }
    
    
            // console.log({ 'c': currentTime, 's': startingTime });
    
    paflov's avatar
    paflov committed
            resolve(testResult);
    
          };
    
          xhr.onerror = () => {
            testResult.error = `Network Error ${xhr.statusText} (${xhr.status}) `;
            resolve(testResult);
          };
    
          xhr.ontimeout = () => {
            testResult.duration = xhr.timeout;
            testResult.error = 'timeout';
            resolve(testResult);
          };
    
          const startingTime = BackendService.getMostPreciseTimestampBrowserCanProvide();
    
          xhr.send(randomContent);
        });
      }
    
    
      // tslint:disable-next-line:member-ordering
      private static getMostPreciseTimestampBrowserCanProvide(): number {
        if (typeof performance !== 'undefined') {
          const timeOrigin = (typeof performance.timeOrigin !== 'undefined') ? performance.timeOrigin : performance.timing.navigationStart;
    
          if (typeof timeOrigin !== 'undefined' && timeOrigin) {
    
            return timeOrigin + performance.now();
          }
        }
    
        return Date.now(); // milliseconds
    
    paflov's avatar
    paflov committed
      // tslint:disable-next-line:member-ordering
      private static generateRandomContent(length: number): string {
        const base64Characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcefghijklmnopqrstuvwxyz0123456789+/';
        let randomString = '';
    
    paflov's avatar
    paflov committed
        for (let i = 1; i <= length; i++) {
    
    paflov's avatar
    paflov committed
          const randomCharacterID = Math.floor(Math.random() * 63);
          randomString += base64Characters[randomCharacterID];
        }
        return randomString;
      }