From e3edace882821db8cfcc3376f5e3ad7ab7b54e66 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:01:04 +0100 Subject: [PATCH 01/11] feat(create-context): add the ability to create a compute context --- src/SASViyaApiClient.ts | 52 +++++++++++++++++++++++++++++++++++++++++ src/SASjs.ts | 7 ++++++ 2 files changed, 59 insertions(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index b560076..4b2e62a 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -189,6 +189,58 @@ export class SASViyaApiClient { return createdSession } + /** + * Creates a compute context on the given server. + * @param contextName - the name of the context to create a session on. + * @param sharedAccountId - the ID of the account to run the servers for this context as. + * @param autoExecLines - the lines of code to execute during session initialization. + * @param accessToken - an access token for an authorized user. + */ + public async createContext( + contextName: string, + sharedAccountId: string, + autoExecLines: string, + accessToken?: string + ) { + if (!contextName) { + throw new Error('Missing context name.') + } + + if (!sharedAccountId) { + throw new Error('Missing shared account ID.') + } + + const headers: any = { + 'Content-Type': 'application/json' + } + + if (accessToken) { + headers.Authorization = `Bearer ${accessToken}` + } + + const createContextRequest: RequestInit = { + method: 'POST', + headers, + body: JSON.stringify({ + name: contextName, + environment: { + autoExecLines: autoExecLines || '' + }, + attributes: { + reuseServerProcesses: true, + runServerAs: sharedAccountId + } + }) + } + + const { result: context } = await this.request( + `${this.serverUrl}/compute/contexts`, + createContextRequest + ) + + return context + } + /** * Executes code on the current SAS Viya server. * @param fileName - a name for the file being submitted for execution. diff --git a/src/SASjs.ts b/src/SASjs.ts index 02eecc6..82d56d7 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -107,6 +107,13 @@ export default class SASjs { return await this.sasViyaApiClient!.getExecutableContexts(accessToken) } + public async createContext(contextName: string, sharedAccountId: string, autoExecLines: string, accessToken: string) { + if (this.sasjsConfig.serverType !== ServerType.SASViya) { + throw new Error('This operation is only supported on SAS Viya servers.') + } + return await this.sasViyaApiClient!.createContext(contextName, sharedAccountId, autoExecLines, accessToken) + } + public async createSession(contextName: string, accessToken: string) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { throw new Error('This operation is only supported on SAS Viya servers.') From d932d9ea0a900698231fa0a21c3fa9fa311e86cf Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:05:05 +0100 Subject: [PATCH 02/11] chore(*): fix code style --- src/SASjs.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/SASjs.ts b/src/SASjs.ts index 82d56d7..72af085 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -107,11 +107,21 @@ export default class SASjs { return await this.sasViyaApiClient!.getExecutableContexts(accessToken) } - public async createContext(contextName: string, sharedAccountId: string, autoExecLines: string, accessToken: string) { + public async createContext( + contextName: string, + sharedAccountId: string, + autoExecLines: string, + accessToken: string + ) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { throw new Error('This operation is only supported on SAS Viya servers.') } - return await this.sasViyaApiClient!.createContext(contextName, sharedAccountId, autoExecLines, accessToken) + return await this.sasViyaApiClient!.createContext( + contextName, + sharedAccountId, + autoExecLines, + accessToken + ) } public async createSession(contextName: string, accessToken: string) { From cc5a0cbec36d1606126705b6b8bc442232043e5d Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:10:08 +0100 Subject: [PATCH 03/11] feat(create-context): allow all authenticated users to use context --- src/SASViyaApiClient.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 4b2e62a..4e4d20a 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -226,6 +226,7 @@ export class SASViyaApiClient { environment: { autoExecLines: autoExecLines || '' }, + authorizeAllAuthenticatedUsers: true, attributes: { reuseServerProcesses: true, runServerAs: sharedAccountId From a318d61f83ff3fe912c1f1d09e529785d555ac04 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:27:44 +0100 Subject: [PATCH 04/11] feat(create-context): add launch context name --- src/SASViyaApiClient.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 4e4d20a..30a5734 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -198,6 +198,7 @@ export class SASViyaApiClient { */ public async createContext( contextName: string, + launchContextName: string, sharedAccountId: string, autoExecLines: string, accessToken?: string @@ -206,6 +207,10 @@ export class SASViyaApiClient { throw new Error('Missing context name.') } + if (!launchContextName) { + throw new Error('Missing launch context name.') + } + if (!sharedAccountId) { throw new Error('Missing shared account ID.') } @@ -226,6 +231,9 @@ export class SASViyaApiClient { environment: { autoExecLines: autoExecLines || '' }, + launchContext: { + contextName: launchContextName + }, authorizeAllAuthenticatedUsers: true, attributes: { reuseServerProcesses: true, From fc1d54d1059f77edac4109f407af0656ae6d36b8 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:28:24 +0100 Subject: [PATCH 05/11] feat(create-context): add launch context name --- src/SASjs.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SASjs.ts b/src/SASjs.ts index 72af085..d44d537 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -109,6 +109,7 @@ export default class SASjs { public async createContext( contextName: string, + launchContextName: string, sharedAccountId: string, autoExecLines: string, accessToken: string @@ -118,6 +119,7 @@ export default class SASjs { } return await this.sasViyaApiClient!.createContext( contextName, + launchContextName, sharedAccountId, autoExecLines, accessToken From 26c8946fd59af8f7098766259612008f4fc36085 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:32:48 +0100 Subject: [PATCH 06/11] feat(create-context): add list of authorized users --- src/SASViyaApiClient.ts | 36 ++++++++++++++++++++++-------------- src/SASjs.ts | 2 ++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 30a5734..66fbc38 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -201,6 +201,7 @@ export class SASViyaApiClient { launchContextName: string, sharedAccountId: string, autoExecLines: string, + authorizedUsers: string[], accessToken?: string ) { if (!contextName) { @@ -223,23 +224,30 @@ export class SASViyaApiClient { headers.Authorization = `Bearer ${accessToken}` } + const requestBody: any = { + name: contextName, + environment: { + autoExecLines: autoExecLines || '' + }, + launchContext: { + contextName: launchContextName + }, + attributes: { + reuseServerProcesses: true, + runServerAs: sharedAccountId + } + } + + if (authorizedUsers && authorizedUsers.length) { + requestBody['authorizedUsers'] = authorizedUsers + } else { + requestBody['authorizeAllAuthenticatedUsers'] = true + } + const createContextRequest: RequestInit = { method: 'POST', headers, - body: JSON.stringify({ - name: contextName, - environment: { - autoExecLines: autoExecLines || '' - }, - launchContext: { - contextName: launchContextName - }, - authorizeAllAuthenticatedUsers: true, - attributes: { - reuseServerProcesses: true, - runServerAs: sharedAccountId - } - }) + body: JSON.stringify(requestBody) } const { result: context } = await this.request( diff --git a/src/SASjs.ts b/src/SASjs.ts index d44d537..f9b1b58 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -112,6 +112,7 @@ export default class SASjs { launchContextName: string, sharedAccountId: string, autoExecLines: string, + authorizedUsers: string[], accessToken: string ) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { @@ -122,6 +123,7 @@ export default class SASjs { launchContextName, sharedAccountId, autoExecLines, + authorizedUsers, accessToken ) } From 07695bdb858f248036619892f7383843fb32f54d Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Sun, 6 Sep 2020 21:35:56 +0100 Subject: [PATCH 07/11] chore(create-context): update TSDoc comment --- src/SASViyaApiClient.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 66fbc38..a1aa1a1 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -192,8 +192,10 @@ export class SASViyaApiClient { /** * Creates a compute context on the given server. * @param contextName - the name of the context to create a session on. + * @param launchContextName - the name of the launcher context used by the compute service. * @param sharedAccountId - the ID of the account to run the servers for this context as. * @param autoExecLines - the lines of code to execute during session initialization. + * @param authorizedUsers - an optional list of authorized user IDs. * @param accessToken - an access token for an authorized user. */ public async createContext( From c9c9754916dc132822d3bc22cbc010b7bd726d6f Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 8 Sep 2020 18:25:36 +0100 Subject: [PATCH 08/11] fix(create-context): change autoExecLines to an array --- src/SASViyaApiClient.ts | 42 ++++++++++++++++++++++++++++++++++++----- src/SASjs.ts | 9 ++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index a1aa1a1..e1a222a 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -191,7 +191,7 @@ export class SASViyaApiClient { /** * Creates a compute context on the given server. - * @param contextName - the name of the context to create a session on. + * @param contextName - the name of the context to be created. * @param launchContextName - the name of the launcher context used by the compute service. * @param sharedAccountId - the ID of the account to run the servers for this context as. * @param autoExecLines - the lines of code to execute during session initialization. @@ -202,7 +202,7 @@ export class SASViyaApiClient { contextName: string, launchContextName: string, sharedAccountId: string, - autoExecLines: string, + autoExecLines: string[], authorizedUsers: string[], accessToken?: string ) { @@ -228,9 +228,6 @@ export class SASViyaApiClient { const requestBody: any = { name: contextName, - environment: { - autoExecLines: autoExecLines || '' - }, launchContext: { contextName: launchContextName }, @@ -246,6 +243,12 @@ export class SASViyaApiClient { requestBody['authorizeAllAuthenticatedUsers'] = true } + if (autoExecLines) { + requestBody.environment = { autoExecLines } + } + + console.log('Body', requestBody) + const createContextRequest: RequestInit = { method: 'POST', headers, @@ -260,6 +263,35 @@ export class SASViyaApiClient { return context } + /** + * Deletes a compute context on the given server. + * @param contextId - the ID of the context to be deleted. + * @param accessToken - an access token for an authorized user. + */ + public async deleteContext(contextId: string, accessToken?: string) { + if (!contextId) { + throw new Error('Invalid context ID') + } + + const headers: any = { + 'Content-Type': 'application/json' + } + + if (accessToken) { + headers.Authorization = `Bearer ${accessToken}` + } + + const deleteContextRequest: RequestInit = { + method: 'DELETE', + headers + } + + return await this.request( + `${this.serverUrl}/compute/contexts/${contextId}`, + deleteContextRequest + ) + } + /** * Executes code on the current SAS Viya server. * @param fileName - a name for the file being submitted for execution. diff --git a/src/SASjs.ts b/src/SASjs.ts index f9b1b58..308c42d 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -111,7 +111,7 @@ export default class SASjs { contextName: string, launchContextName: string, sharedAccountId: string, - autoExecLines: string, + autoExecLines: string[], authorizedUsers: string[], accessToken: string ) { @@ -128,6 +128,13 @@ export default class SASjs { ) } + public async deleteContext(contextId: string) { + if (this.sasjsConfig.serverType !== ServerType.SASViya) { + throw new Error('This operation is only supported on SAS Viya servers.') + } + return await this.sasViyaApiClient!.deleteContext(contextId) + } + public async createSession(contextName: string, accessToken: string) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { throw new Error('This operation is only supported on SAS Viya servers.') From 58d69a62d64ac21f0b22942c9628b53bae1b8385 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 8 Sep 2020 18:29:12 +0100 Subject: [PATCH 09/11] feat(delete-context): add the ability to delete a compute context --- src/SASjs.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SASjs.ts b/src/SASjs.ts index 308c42d..b901917 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -128,11 +128,11 @@ export default class SASjs { ) } - public async deleteContext(contextId: string) { + public async deleteContext(contextId: string, accessToken?: string) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { throw new Error('This operation is only supported on SAS Viya servers.') } - return await this.sasViyaApiClient!.deleteContext(contextId) + return await this.sasViyaApiClient!.deleteContext(contextId, accessToken) } public async createSession(contextName: string, accessToken: string) { From 7a1cce193efe1650da0de197634d39121a3b6d18 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 8 Sep 2020 18:55:30 +0100 Subject: [PATCH 10/11] chore(delete-context): add punctuation to error message --- src/SASViyaApiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index e1a222a..2d4f3c5 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -270,7 +270,7 @@ export class SASViyaApiClient { */ public async deleteContext(contextId: string, accessToken?: string) { if (!contextId) { - throw new Error('Invalid context ID') + throw new Error('Invalid context ID.') } const headers: any = { From f6b1eecb42fb07de196234fb7342f7415e3f29ff Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Wed, 9 Sep 2020 07:36:27 +0100 Subject: [PATCH 11/11] chore(*): remove console log, add comments --- src/SASViyaApiClient.ts | 2 -- src/SASjs.ts | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index e9d7744..ba6e004 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -251,8 +251,6 @@ export class SASViyaApiClient { requestBody.environment = { autoExecLines } } - console.log('Body', requestBody) - const createContextRequest: RequestInit = { method: 'POST', headers, diff --git a/src/SASjs.ts b/src/SASjs.ts index 2e0c812..e412184 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -107,6 +107,15 @@ export default class SASjs { return await this.sasViyaApiClient!.getExecutableContexts(accessToken) } + /** + * Creates a compute context on the given server. + * @param contextName - the name of the context to be created. + * @param launchContextName - the name of the launcher context used by the compute service. + * @param sharedAccountId - the ID of the account to run the servers for this context as. + * @param autoExecLines - the lines of code to execute during session initialization. + * @param authorizedUsers - an optional list of authorized user IDs. + * @param accessToken - an access token for an authorized user. + */ public async createContext( contextName: string, launchContextName: string, @@ -128,6 +137,11 @@ export default class SASjs { ) } + /** + * Deletes a compute context on the given server. + * @param contextId - the ID of the context to be deleted. + * @param accessToken - an access token for an authorized user. + */ public async deleteContext(contextId: string, accessToken?: string) { if (this.sasjsConfig.serverType !== ServerType.SASViya) { throw new Error('This operation is only supported on SAS Viya servers.')