mirror of
https://github.com/sasjs/adapter.git
synced 2026-01-07 12:30:06 +00:00
Merge branch 'master' into issue-409
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
"postpublish": "git clean -fd",
|
"postpublish": "git clean -fd",
|
||||||
"semantic-release": "semantic-release",
|
"semantic-release": "semantic-release",
|
||||||
"typedoc": "typedoc",
|
"typedoc": "typedoc",
|
||||||
"postinstall": "[ -d .git ] && git config core.hooksPath ./.git-hooks || true"
|
"prepare": "[ -d .git ] && git config core.hooksPath ./.git-hooks || true"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
@@ -290,16 +290,14 @@ export class SASViyaApiClient {
|
|||||||
printPid = false,
|
printPid = false,
|
||||||
variables?: MacroVar
|
variables?: MacroVar
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const { access_token } = authConfig || {}
|
let access_token = (authConfig || {}).access_token
|
||||||
|
if (authConfig) {
|
||||||
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
|
}
|
||||||
|
|
||||||
const logger = process.logger || console
|
const logger = process.logger || console
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const headers: any = {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (access_token) headers.Authorization = `Bearer ${access_token}`
|
|
||||||
|
|
||||||
let executionSessionId: string
|
let executionSessionId: string
|
||||||
|
|
||||||
const session = await this.sessionManager
|
const session = await this.sessionManager
|
||||||
@@ -443,6 +441,10 @@ export class SASViyaApiClient {
|
|||||||
throw prefixMessage(err, 'Error while polling job status. ')
|
throw prefixMessage(err, 'Error while polling job status. ')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (authConfig) {
|
||||||
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
|
}
|
||||||
|
|
||||||
const { result: currentJob } = await this.requestClient
|
const { result: currentJob } = await this.requestClient
|
||||||
.get<Job>(
|
.get<Job>(
|
||||||
`/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
|
`/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
|
||||||
@@ -886,7 +888,10 @@ export class SASViyaApiClient {
|
|||||||
printPid = false,
|
printPid = false,
|
||||||
variables?: MacroVar
|
variables?: MacroVar
|
||||||
) {
|
) {
|
||||||
let { access_token } = authConfig || {}
|
let access_token = (authConfig || {}).access_token
|
||||||
|
if (authConfig) {
|
||||||
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
|
}
|
||||||
|
|
||||||
if (isRelativePath(sasJob) && !this.rootFolderName) {
|
if (isRelativePath(sasJob) && !this.rootFolderName) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -913,12 +918,6 @@ export class SASViyaApiClient {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers: any = { 'Content-Type': 'application/json' }
|
|
||||||
|
|
||||||
if (!!access_token) {
|
|
||||||
headers.Authorization = `Bearer ${access_token}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const jobToExecute = jobFolder?.find((item) => item.name === jobName)
|
const jobToExecute = jobFolder?.find((item) => item.name === jobName)
|
||||||
|
|
||||||
if (!jobToExecute) {
|
if (!jobToExecute) {
|
||||||
@@ -985,7 +984,10 @@ export class SASViyaApiClient {
|
|||||||
data?: any,
|
data?: any,
|
||||||
authConfig?: AuthConfig
|
authConfig?: AuthConfig
|
||||||
) {
|
) {
|
||||||
let { access_token } = authConfig || {}
|
let access_token = (authConfig || {}).access_token
|
||||||
|
if (authConfig) {
|
||||||
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
|
}
|
||||||
if (isRelativePath(sasJob) && !this.rootFolderName) {
|
if (isRelativePath(sasJob) && !this.rootFolderName) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Relative paths cannot be used without specifying a root folder name.'
|
'Relative paths cannot be used without specifying a root folder name.'
|
||||||
@@ -1145,21 +1147,9 @@ export class SASViyaApiClient {
|
|||||||
let POLL_INTERVAL = 300
|
let POLL_INTERVAL = 300
|
||||||
let MAX_POLL_COUNT = 1000
|
let MAX_POLL_COUNT = 1000
|
||||||
let MAX_ERROR_COUNT = 5
|
let MAX_ERROR_COUNT = 5
|
||||||
let { access_token, refresh_token, client, secret } = authConfig || {}
|
let access_token = (authConfig || {}).access_token
|
||||||
if (access_token && refresh_token) {
|
if (authConfig) {
|
||||||
if (
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
client &&
|
|
||||||
secret &&
|
|
||||||
refresh_token &&
|
|
||||||
(isAccessTokenExpiring(access_token) ||
|
|
||||||
isRefreshTokenExpiring(refresh_token))
|
|
||||||
) {
|
|
||||||
;({ access_token, refresh_token } = await this.refreshTokens(
|
|
||||||
client,
|
|
||||||
secret,
|
|
||||||
refresh_token
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pollOptions) {
|
if (pollOptions) {
|
||||||
@@ -1213,20 +1203,8 @@ export class SASViyaApiClient {
|
|||||||
postedJobState === 'pending' ||
|
postedJobState === 'pending' ||
|
||||||
postedJobState === 'unavailable'
|
postedJobState === 'unavailable'
|
||||||
) {
|
) {
|
||||||
if (access_token && refresh_token) {
|
if (authConfig) {
|
||||||
if (
|
;({ access_token } = await this.getTokens(authConfig))
|
||||||
client &&
|
|
||||||
secret &&
|
|
||||||
refresh_token &&
|
|
||||||
(isAccessTokenExpiring(access_token) ||
|
|
||||||
isRefreshTokenExpiring(refresh_token))
|
|
||||||
) {
|
|
||||||
;({ access_token, refresh_token } = await this.refreshTokens(
|
|
||||||
client,
|
|
||||||
secret,
|
|
||||||
refresh_token
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateLink) {
|
if (stateLink) {
|
||||||
@@ -1510,4 +1488,21 @@ export class SASViyaApiClient {
|
|||||||
|
|
||||||
return movedFolder
|
return movedFolder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getTokens(authConfig: AuthConfig): Promise<AuthConfig> {
|
||||||
|
const logger = process.logger || console
|
||||||
|
let { access_token, refresh_token, client, secret } = authConfig
|
||||||
|
if (
|
||||||
|
isAccessTokenExpiring(access_token) ||
|
||||||
|
isRefreshTokenExpiring(refresh_token)
|
||||||
|
) {
|
||||||
|
logger.info('Refreshing access and refresh tokens.')
|
||||||
|
;({ access_token, refresh_token } = await this.refreshTokens(
|
||||||
|
client,
|
||||||
|
secret,
|
||||||
|
refresh_token
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return { access_token, refresh_token, client, secret }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ import { RequestClient } from './request/RequestClient'
|
|||||||
const MAX_SESSION_COUNT = 1
|
const MAX_SESSION_COUNT = 1
|
||||||
const RETRY_LIMIT: number = 3
|
const RETRY_LIMIT: number = 3
|
||||||
let RETRY_COUNT: number = 0
|
let RETRY_COUNT: number = 0
|
||||||
const INTERNAL_SAS_ERROR = {
|
|
||||||
status: 304,
|
|
||||||
message: 'Not Modified'
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SessionManager {
|
export class SessionManager {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -164,7 +160,7 @@ export class SessionManager {
|
|||||||
|
|
||||||
const stateLink = session.links.find((l: any) => l.rel === 'state')
|
const stateLink = session.links.find((l: any) => l.rel === 'state')
|
||||||
|
|
||||||
return new Promise(async (resolve, _) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
if (
|
if (
|
||||||
sessionState === 'pending' ||
|
sessionState === 'pending' ||
|
||||||
sessionState === 'running' ||
|
sessionState === 'running' ||
|
||||||
@@ -182,7 +178,7 @@ export class SessionManager {
|
|||||||
etag!,
|
etag!,
|
||||||
accessToken
|
accessToken
|
||||||
).catch((err) => {
|
).catch((err) => {
|
||||||
throw err
|
throw prefixMessage(err, 'Error while getting session state.')
|
||||||
})
|
})
|
||||||
|
|
||||||
sessionState = state.trim()
|
sessionState = state.trim()
|
||||||
@@ -196,13 +192,14 @@ export class SessionManager {
|
|||||||
|
|
||||||
// There is an internal error present in SAS Viya 3.5
|
// There is an internal error present in SAS Viya 3.5
|
||||||
// Retry to wait for a session status in such case of SAS internal error
|
// Retry to wait for a session status in such case of SAS internal error
|
||||||
if (
|
if (!sessionState) {
|
||||||
sessionState === INTERNAL_SAS_ERROR.message &&
|
if (RETRY_COUNT < RETRY_LIMIT) {
|
||||||
RETRY_COUNT < RETRY_LIMIT
|
RETRY_COUNT++
|
||||||
) {
|
|
||||||
RETRY_COUNT++
|
|
||||||
|
|
||||||
resolve(this.waitForSession(session, etag, accessToken))
|
resolve(this.waitForSession(session, etag, accessToken))
|
||||||
|
} else {
|
||||||
|
reject('Could not get session state.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(sessionState)
|
resolve(sessionState)
|
||||||
@@ -222,9 +219,6 @@ export class SessionManager {
|
|||||||
.get(url, accessToken, 'text/plain', { 'If-None-Match': etag })
|
.get(url, accessToken, 'text/plain', { 'If-None-Match': etag })
|
||||||
.then((res) => res.result as string)
|
.then((res) => res.result as string)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err.status === INTERNAL_SAS_ERROR.status)
|
|
||||||
return INTERNAL_SAS_ERROR.message
|
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ export class RequestClient implements HttpClient {
|
|||||||
baseURL: baseUrl
|
baseURL: baseUrl
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.httpClient.defaults.validateStatus = (status) =>
|
||||||
|
status >= 200 && status < 305
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCsrfToken(type: 'general' | 'file' = 'general') {
|
public getCsrfToken(type: 'general' | 'file' = 'general') {
|
||||||
|
|||||||
Reference in New Issue
Block a user