src/app/services/app.service.ts

Relationships

Used by

Depends on

No results matching.

Index

Properties
Methods

Constructor

constructor(licenceService: LicenceService, eventService: EventService, sasService: SasService, loggerService: LoggerService, appSettingsService: AppSettingsService, router: Router, appStoreService: AppStoreService, startupCheckService: StartupCheckService)
Parameters :
Name Type Optional
licenceService LicenceService No
eventService EventService No
sasService SasService No
loggerService LoggerService No
appSettingsService AppSettingsService No
router Router No
appStoreService AppStoreService No
startupCheckService StartupCheckService No

Methods

Public getEnvironmentInfo
getEnvironmentInfo()
Returns : EnvironmentInfo
Public patchSyssite
patchSyssite(syssite: string)
Parameters :
Name Type Optional
syssite string No
Returns : void
sasServiceInit
sasServiceInit()
Returns : void
Public Async startUpData
startUpData()
Returns : any
subscribe
subscribe()
Returns : void

Properties

Private environmentInfo
Type : EnvironmentInfo
Default value : {}
Private retryOptions
Type : RetryOnceOptions
Default value : {}
Public syssite
Type : unknown
Default value : new BehaviorSubject<string[] | null>(null)
import { Injectable } from '@angular/core'
import { EventService } from './event.service'
import { globals } from '../_globals'
import { SasService } from './sas.service'
import { NavigationEnd, Router } from '@angular/router'
import { BehaviorSubject } from 'rxjs'
import { LoggerService } from './logger.service'
import { EnvironmentInfo } from '../system/models/environment-info.model'
import { LicenceService } from './licence.service'
import { AppSettingsService } from './app-settings.service'
import { AppThemes } from '../models/AppSettings'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'
import { AppStoreService } from './app-store.service'
import { StartupCheckService } from './startup-check.service'
import { retryOnce, RetryOnceOptions } from '../shared/utils/retry-once'
import { getMalformedAdapterResponseMessage } from '../shared/utils/get-malformed-adapter-response-message'

@Injectable()
export class AppService {
  public syssite = new BehaviorSubject<string[] | null>(null)
  private environmentInfo: EnvironmentInfo = {}
  // Overridable in tests to keep the retry pause instant — see
  // retry-once.spec.ts and app.service.spec.ts.
  private retryOptions: RetryOnceOptions = {}

  constructor(
    private licenceService: LicenceService,
    private eventService: EventService,
    private sasService: SasService,
    private loggerService: LoggerService,
    private appSettingsService: AppSettingsService,
    private router: Router,
    private appStoreService: AppStoreService,
    private startupCheckService: StartupCheckService
  ) {
    this.subscribe()

    this.router.events.subscribe((val) => {
      if (val instanceof NavigationEnd) {
        if (val.url === '/deploy') {
          this.eventService.startupDataLoaded()
        }
      }
    })

    const appSettings = this.appSettingsService.settings.value

    if (!!appSettings.persistSelectedTheme) {
      if (appSettings.selectedTheme === AppThemes.light) {
        this.eventService.toggleDarkMode(false)
      } else if (appSettings.selectedTheme === AppThemes.dark) {
        this.eventService.toggleDarkMode(true)
      } else {
        // Fallback to light mode
        this.eventService.toggleDarkMode(false)
      }
    }
  }

  sasServiceInit() {
    this.sasService.sasServiceInit() //Code from constructor is put in this function inside SasService, because we first want to subscribe to emitters here before executing SasService init function
  }

  subscribe() {
    this.sasService.loadStartupServiceEmitter.subscribe(() => {
      this.startUpData()
    })

    this.sasService.requestSiteIdEmitter.subscribe((sysite: string) => {
      this.patchSyssite(sysite)
    })
  }

  public getEnvironmentInfo() {
    return this.environmentInfo
  }

  public patchSyssite(syssite: string) {
    let currentSyssite = this.syssite.getValue()

    if (currentSyssite) {
      if (!currentSyssite.includes(syssite)) {
        currentSyssite.push(syssite)
        this.syssite.next(currentSyssite)
      }
    }
  }

  public async startUpData() {
    let startupServiceError = false

    // Retry once on failure — multiple concurrent DC instances (e.g. VA
    // multi-page reports) can cause this request to time out even though a
    // second attempt succeeds. See STARTUP_RETRY_PLAN.md.
    await retryOnce(
      () => this.sasService.request('public/startupservice', null),
      this.retryOptions
    )
      .then(async (res: RequestWrapperResponse) => {
        const malformedMessage = getMalformedAdapterResponseMessage(
          res.adapterResponse
        )
        if (malformedMessage) {
          startupServiceError = true
          console.error(
            'startUpData: startupservice returned malformed response:',
            malformedMessage
          )
          this.startupCheckService.updateStep(2, 'error', 'Malformed response')
          this.eventService.showInfoModal(
            'Error',
            malformedMessage,
            'public/startupservice'
          )
          this.licenceService.isAppActivated.next(false)

          return
        }

        this.syssite.next([res.adapterResponse.SYSSITE])

        let missingProps: string[] = []

        if (
          !res.adapterResponse.globvars ||
          (res.adapterResponse.globvars && !res.adapterResponse.globvars[0])
        )
          missingProps.push('Globvars')
        if (!res.adapterResponse.sasdatasets) missingProps.push('Sasdatasets')
        if (!res.adapterResponse.saslibs) missingProps.push('Saslibs')
        if (!res.adapterResponse.xlmaps) missingProps.push('XLMaps')

        if (missingProps.length > 0) {
          startupServiceError = true
          console.error(
            'startUpData: startupservice missing properties:',
            missingProps.join(', ')
          )
          this.startupCheckService.updateStep(
            2,
            'error',
            `Missing: ${missingProps.join(', ')}`
          )
          this.eventService.showInfoModal(
            'Error',
            `${missingProps.join(', ')} are not present in the startupservice`,
            'public/startupservice'
          )
          this.licenceService.isAppActivated.next(false)

          return
        }

        const dcAdapterSettings = this.appStoreService.getDcAdapterSettings()

        this.environmentInfo = {
          SYSSITE: res.adapterResponse.SYSSITE,
          SYSSCPL: res.adapterResponse.SYSSCPL,
          SYSTCPIPHOSTNAME: res.adapterResponse.SYSTCPIPHOSTNAME,
          SYSVLONG: res.adapterResponse.SYSVLONG,
          MEMSIZE: res.adapterResponse.MEMSIZE,
          SYSPROCESSMODE: res.adapterResponse.SYSPROCESSMODE,
          SYSHOSTNAME: res.adapterResponse.SYSHOSTNAME,
          SYSUSERID: res.adapterResponse.SYSUSERID,
          SYSHOSTINFOLONG: res.adapterResponse.SYSHOSTINFOLONG,
          SYSENCODING: res.adapterResponse.SYSENCODING,
          AUTOEXEC: res.adapterResponse.AUTOEXEC,
          TIMEZONE: res.adapterResponse.globvars[0].TIMEZONE,
          SYSTIMEZONEIDENT: res.adapterResponse.globvars[0].SYSTIMEZONEIDENT,
          SYSTIMEZONEOFFSET: res.adapterResponse.globvars[0].SYSTIMEZONEOFFSET,
          ISADMIN: res.adapterResponse.globvars[0].ISADMIN,
          DC_ADMIN_GROUP: res.adapterResponse.globvars[0].DC_ADMIN_GROUP,
          APP_LOC: dcAdapterSettings?.appLoc
        }

        let libs = res.adapterResponse.sasdatasets
        let libGroup: any = {}
        let libsAndTables
        let libraries

        for (let lib of libs) {
          if (!libGroup[lib.LIBREF]) {
            libGroup[lib.LIBREF] = []
          }

          libGroup[lib.LIBREF].push(lib.DSN)
        }

        // Sidebar data structure
        let treeNodeTemp = JSON.parse(JSON.stringify(libGroup))
        let treeNode = []

        for (let library of Object.keys(treeNodeTemp)) {
          treeNode.push({
            LIBRARYREF: library,
            tables: treeNodeTemp[library]
          })
        }

        let treeNodeLibraries = treeNode
        // Sidebar data structure end

        libsAndTables = libGroup
        libraries = Object.keys(libGroup)

        if (libsAndTables !== undefined) {
          globals.editor.libsAndTables = libsAndTables
        }

        globals.xlmaps = res.adapterResponse.xlmaps.map((xlmap: any) => ({
          id: xlmap[0],
          description: xlmap[1],
          targetDS: xlmap[2]
        }))
        globals.editor.treeNodeLibraries = treeNodeLibraries
        globals.editor.libraries = libraries
        globals.editor.startupSet = true

        globals.dcLib = res.adapterResponse.globvars[0].DCLIB

        await this.licenceService.activation(res.adapterResponse)
      })
      .catch((err: any) => {
        startupServiceError = true
        console.error('startUpData: startupservice request failed:', err)
        this.startupCheckService.updateStep(2, 'error', 'Request failed')
        this.eventService.showInfoModal(
          'Error',
          'There is an issue with startupservice response',
          'public/startupservice'
        )
        this.licenceService.isAppActivated.next(false)
      })

    this.loggerService.log(
      'Activated:',
      this.licenceService.isAppActivated.value
    )

    if (!startupServiceError) {
      this.eventService.startupDataLoaded()

      if (!this.licenceService.isAppActivated.value) {
        // If route is already on `licensing` page then we won't re route
        if (
          !this.router.url.includes('deploy') &&
          !this.router.url.includes('licensing')
        ) {
          this.router.navigateByUrl('/licensing/key?error=missing&force=true')
        }
      } else {
        if (this.router.url.includes('licensing'))
          this.router.navigateByUrl('/home')
      }
    }
  }
}

results matching ""

    No results matching ""