1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-07 20:40:05 +00:00

Merge pull request #830 from sasjs/issue-829

fix(execute-script): fixed executing jobs on viya using compute api
This commit is contained in:
Yury Shkoda
2023-09-05 15:20:38 +03:00
committed by GitHub
4 changed files with 43 additions and 66 deletions

View File

@@ -43,10 +43,10 @@ module.exports = {
// An object that configures minimum threshold enforcement for coverage results // An object that configures minimum threshold enforcement for coverage results
coverageThreshold: { coverageThreshold: {
global: { global: {
statements: 63.66, statements: 63.61,
branches: 44.74, branches: 44.72,
functions: 53.94, functions: 53.94,
lines: 64.12 lines: 64.07
} }
}, },

View File

@@ -25,7 +25,7 @@ import { prefixMessage } from '@sasjs/utils/error'
import { pollJobState } from './api/viya/pollJobState' import { pollJobState } from './api/viya/pollJobState'
import { getTokens } from './auth/getTokens' import { getTokens } from './auth/getTokens'
import { uploadTables } from './api/viya/uploadTables' import { uploadTables } from './api/viya/uploadTables'
import { executeScript } from './api/viya/executeScript' import { executeOnComputeApi } from './api/viya/executeOnComputeApi'
import { getAccessTokenForViya } from './auth/getAccessTokenForViya' import { getAccessTokenForViya } from './auth/getAccessTokenForViya'
import { refreshTokensForViya } from './auth/refreshTokensForViya' import { refreshTokensForViya } from './auth/refreshTokensForViya'
@@ -293,7 +293,7 @@ export class SASViyaApiClient {
printPid = false, printPid = false,
variables?: MacroVar variables?: MacroVar
): Promise<any> { ): Promise<any> {
return executeScript( return executeOnComputeApi(
this.requestClient, this.requestClient,
this.sessionManager, this.sessionManager,
this.rootFolderName, this.rootFolderName,

View File

@@ -15,8 +15,12 @@ import { formatDataForRequest } from '../../utils/formatDataForRequest'
import { pollJobState, JobState } from './pollJobState' import { pollJobState, JobState } from './pollJobState'
import { uploadTables } from './uploadTables' import { uploadTables } from './uploadTables'
interface JobRequestBody {
[key: string]: number | string | string[]
}
/** /**
* Executes code on the current SAS Viya server. * Executes SAS program on the current SAS Viya server using Compute API.
* @param jobPath - the path to the file being submitted for execution. * @param jobPath - the path to the file being submitted for execution.
* @param linesOfCode - an array of code lines to execute. * @param linesOfCode - an array of code lines to execute.
* @param contextName - the context to execute the code in. * @param contextName - the context to execute the code in.
@@ -29,7 +33,7 @@ import { uploadTables } from './uploadTables'
* @param printPid - a boolean that indicates whether the function should print (PID) of the started job. * @param printPid - a boolean that indicates whether the function should print (PID) of the started job.
* @param variables - an object that represents macro variables. * @param variables - an object that represents macro variables.
*/ */
export async function executeScript( export async function executeOnComputeApi(
requestClient: RequestClient, requestClient: RequestClient,
sessionManager: SessionManager, sessionManager: SessionManager,
rootFolderName: string, rootFolderName: string,
@@ -46,6 +50,7 @@ export async function executeScript(
variables?: MacroVar variables?: MacroVar
): Promise<any> { ): Promise<any> {
let access_token = (authConfig || {}).access_token let access_token = (authConfig || {}).access_token
if (authConfig) { if (authConfig) {
;({ access_token } = await getTokens(requestClient, authConfig)) ;({ access_token } = await getTokens(requestClient, authConfig))
} }
@@ -85,20 +90,6 @@ export async function executeScript(
} }
} }
const jobArguments: { [key: string]: any } = {
_contextName: contextName,
_OMITJSONLISTING: true,
_OMITJSONLOG: true,
_OMITSESSIONRESULTS: true,
_OMITTEXTLISTING: true,
_OMITTEXTLOG: true
}
if (debug) {
jobArguments['_OMITTEXTLOG'] = false
jobArguments['_OMITSESSIONRESULTS'] = false
}
let fileName let fileName
if (isRelativePath(jobPath)) { if (isRelativePath(jobPath)) {
@@ -107,6 +98,7 @@ export async function executeScript(
}` }`
} else { } else {
const jobPathParts = jobPath.split('/') const jobPathParts = jobPath.split('/')
fileName = jobPathParts.pop() fileName = jobPathParts.pop()
} }
@@ -118,7 +110,6 @@ export async function executeScript(
} }
if (variables) jobVariables = { ...jobVariables, ...variables } if (variables) jobVariables = { ...jobVariables, ...variables }
if (debug) jobVariables = { ...jobVariables, _DEBUG: 131 } if (debug) jobVariables = { ...jobVariables, _DEBUG: 131 }
let files: any[] = [] let files: any[] = []
@@ -145,12 +136,12 @@ export async function executeScript(
} }
// Execute job in session // Execute job in session
const jobRequestBody = { const jobRequestBody: JobRequestBody = {
name: fileName, name: fileName || 'Default Job Name',
description: 'Powered by SASjs', description: 'Powered by SASjs',
code: linesOfCode, code: linesOfCode,
variables: jobVariables, variables: jobVariables,
arguments: jobArguments version: 2
} }
const { result: postedJob, etag } = await requestClient const { result: postedJob, etag } = await requestClient
@@ -279,7 +270,7 @@ export async function executeScript(
const error = e as HttpError const error = e as HttpError
if (error.status === 404) { if (error.status === 404) {
return executeScript( return executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
rootFolderName, rootFolderName,

View File

@@ -1,6 +1,6 @@
import { RequestClient } from '../../../request/RequestClient' import { RequestClient } from '../../../request/RequestClient'
import { SessionManager } from '../../../SessionManager' import { SessionManager } from '../../../SessionManager'
import { executeScript } from '../executeScript' import { executeOnComputeApi } from '../executeOnComputeApi'
import { mockSession, mockAuthConfig, mockJob } from './mockResponses' import { mockSession, mockAuthConfig, mockJob } from './mockResponses'
import * as pollJobStateModule from '../pollJobState' import * as pollJobStateModule from '../pollJobState'
import * as uploadTablesModule from '../uploadTables' import * as uploadTablesModule from '../uploadTables'
@@ -25,7 +25,7 @@ describe('executeScript', () => {
}) })
it('should not try to get fresh tokens if an authConfig is not provided', async () => { it('should not try to get fresh tokens if an authConfig is not provided', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -38,7 +38,7 @@ describe('executeScript', () => {
}) })
it('should try to get fresh tokens if an authConfig is provided', async () => { it('should try to get fresh tokens if an authConfig is provided', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -55,7 +55,7 @@ describe('executeScript', () => {
}) })
it('should get a session from the session manager before executing', async () => { it('should get a session from the session manager before executing', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -72,7 +72,7 @@ describe('executeScript', () => {
.spyOn(sessionManager, 'getSession') .spyOn(sessionManager, 'getSession')
.mockImplementation(() => Promise.reject('Test Error')) .mockImplementation(() => Promise.reject('Test Error'))
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -85,7 +85,7 @@ describe('executeScript', () => {
}) })
it('should fetch the PID when printPid is true', async () => { it('should fetch the PID when printPid is true', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -113,7 +113,7 @@ describe('executeScript', () => {
.spyOn(sessionManager, 'getVariable') .spyOn(sessionManager, 'getVariable')
.mockImplementation(() => Promise.reject('Test Error')) .mockImplementation(() => Promise.reject('Test Error'))
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -139,7 +139,7 @@ describe('executeScript', () => {
Promise.resolve([{ tableName: 'test', file: { id: 1 } }]) Promise.resolve([{ tableName: 'test', file: { id: 1 } }])
) )
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -163,7 +163,7 @@ describe('executeScript', () => {
}) })
it('should format data as CSV when it does not contain semicolons', async () => { it('should format data as CSV when it does not contain semicolons', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -189,7 +189,7 @@ describe('executeScript', () => {
.spyOn(formatDataModule, 'formatDataForRequest') .spyOn(formatDataModule, 'formatDataForRequest')
.mockImplementation(() => ({ sasjs_tables: 'foo', sasjs0data: 'bar' })) .mockImplementation(() => ({ sasjs_tables: 'foo', sasjs0data: 'bar' }))
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -217,14 +217,7 @@ describe('executeScript', () => {
sasjs_tables: 'foo', sasjs_tables: 'foo',
sasjs0data: 'bar' sasjs0data: 'bar'
}, },
arguments: { version: 2
_contextName: 'test context',
_OMITJSONLISTING: true,
_OMITJSONLOG: true,
_OMITSESSIONRESULTS: true,
_OMITTEXTLISTING: true,
_OMITTEXTLOG: true
}
}, },
mockAuthConfig.access_token mockAuthConfig.access_token
) )
@@ -235,7 +228,7 @@ describe('executeScript', () => {
.spyOn(formatDataModule, 'formatDataForRequest') .spyOn(formatDataModule, 'formatDataForRequest')
.mockImplementation(() => ({ sasjs_tables: 'foo', sasjs0data: 'bar' })) .mockImplementation(() => ({ sasjs_tables: 'foo', sasjs0data: 'bar' }))
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -264,14 +257,7 @@ describe('executeScript', () => {
sasjs0data: 'bar', sasjs0data: 'bar',
_DEBUG: 131 _DEBUG: 131
}, },
arguments: { version: 2
_contextName: 'test context',
_OMITJSONLISTING: true,
_OMITJSONLOG: true,
_OMITSESSIONRESULTS: false,
_OMITTEXTLISTING: true,
_OMITTEXTLOG: false
}
}, },
mockAuthConfig.access_token mockAuthConfig.access_token
) )
@@ -282,7 +268,7 @@ describe('executeScript', () => {
.spyOn(requestClient, 'post') .spyOn(requestClient, 'post')
.mockImplementation(() => Promise.reject('Test Error')) .mockImplementation(() => Promise.reject('Test Error'))
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -302,7 +288,7 @@ describe('executeScript', () => {
}) })
it('should immediately return the session when waitForResult is false', async () => { it('should immediately return the session when waitForResult is false', async () => {
const result = await executeScript( const result = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -322,7 +308,7 @@ describe('executeScript', () => {
}) })
it('should poll for job completion when waitForResult is true', async () => { it('should poll for job completion when waitForResult is true', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -352,7 +338,7 @@ describe('executeScript', () => {
.spyOn(pollJobStateModule, 'pollJobState') .spyOn(pollJobStateModule, 'pollJobState')
.mockImplementation(() => Promise.reject('Poll Error')) .mockImplementation(() => Promise.reject('Poll Error'))
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -378,7 +364,7 @@ describe('executeScript', () => {
Promise.reject({ response: { data: 'err=5113,' } }) Promise.reject({ response: { data: 'err=5113,' } })
) )
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -404,7 +390,7 @@ describe('executeScript', () => {
}) })
it('should fetch the logs for the job if debug is true and a log URL is available', async () => { it('should fetch the logs for the job if debug is true and a log URL is available', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -429,7 +415,7 @@ describe('executeScript', () => {
}) })
it('should not fetch the logs for the job if debug is false', async () => { it('should not fetch the logs for the job if debug is false', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -455,7 +441,7 @@ describe('executeScript', () => {
Promise.resolve(pollJobStateModule.JobState.Failed) Promise.resolve(pollJobStateModule.JobState.Failed)
) )
const error: ComputeJobExecutionError = await executeScript( const error: ComputeJobExecutionError = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -490,7 +476,7 @@ describe('executeScript', () => {
Promise.resolve(pollJobStateModule.JobState.Error) Promise.resolve(pollJobStateModule.JobState.Error)
) )
const error: ComputeJobExecutionError = await executeScript( const error: ComputeJobExecutionError = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -519,7 +505,7 @@ describe('executeScript', () => {
}) })
it('should fetch the result if expectWebout is true', async () => { it('should fetch the result if expectWebout is true', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -550,7 +536,7 @@ describe('executeScript', () => {
return Promise.resolve({ result: mockJob, etag: '', status: 200 }) return Promise.resolve({ result: mockJob, etag: '', status: 200 })
}) })
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -584,7 +570,7 @@ describe('executeScript', () => {
}) })
it('should clear the session after execution is complete', async () => { it('should clear the session after execution is complete', async () => {
await executeScript( await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',
@@ -611,7 +597,7 @@ describe('executeScript', () => {
.spyOn(sessionManager, 'clearSession') .spyOn(sessionManager, 'clearSession')
.mockImplementation(() => Promise.reject('Clear Session Error')) .mockImplementation(() => Promise.reject('Clear Session Error'))
const error = await executeScript( const error = await executeOnComputeApi(
requestClient, requestClient,
sessionManager, sessionManager,
'test', 'test',