@sassoftware/viya-serverjs
Version:
Easy to use app server for SAS Viya applications
351 lines (319 loc) • 9.3 kB
HTML
<!--
~ /* ------------------------------------------------------------------------------------
~ * Copyright (c) SAS Institute Inc.
~ * Licensed under the Apache License, Version 2.0 (the "License");
~ * you may not use this file except in compliance with the License.
~ * You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS,
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ * See the License for the specific language governing permissions and
~ * limitations under the License.
~ ----------------------------------------------------------------------------------------*/
~
-->
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>index.html</title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>
<script src="https://unpkg.com/@sassoftware/restaf@5.2.4"></script>
<script src="https://unpkg.com/@sassoftware/restaflib@5.2.4"></script>
<script src="/appenv"></script>
<style>
.container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
min-height: 800px;
}
.elabel {
display: inline-block;
clear: left;
width: 250px;
text-align: right;
}
.einput {
display: inline-block;
}
.div1 {
border: 1px solid black;
background: lightskyblue;
}
.div2 {
border: 1px solid black;
background: lightskyblue;
height: 200px;
}
</style>
<script>
debugger;
console.log(JSON.stringify(APPENV, null, 4));
let store = restaf.initStore({
casProxy: true,
options: {
proxyServer: APPENV.PROXYSERVER,
httpOptions: null
}
});
debugger; console.log(store.config);
let session = null;
let servers = null;
let services = null;
let files = null;
let reports = null;
let compute = null;
function setup() {
debugger;
document.getElementById('output').innerHTML = '...initializing';
initSession()
.then(r => {
document.getElementById('output').innerHTML = 'ready';
keepAlive();
})
.catch(e => {
console.log(e);
});
}
function keepAlive() {
if (LOGONPAYLOAD.keepAlive != null) {
let interval = 120;
let timeout = 14400;
if (LOGONPAYLOAD.timers != null) {
let opts = LOGONPAYLOAD.timers.split(',');
interval = parseInt(opts[0]);
timeout = parseInt(opts[1]);
}
console.log(`Keepalive is active`);
store.keepViyaAlive(LOGONPAYLOAD.keepAlive, interval, timeout, () => {
console.log('timed out at', Date());
let params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,width=0,height=0,left=-1000,top=-1000`;
window.open(`${appOptions.logonPayload.host}/SASLogon/timedout`, 'Timed Out', params);
return true;
});
}
}
function logoff() {
let url = `${window.location.protocol}//${window.location.host}/${LOGONPAYLOAD.appName}/logout?callbackUrl=onlogoff.html`;
window.location.replace(url);
}
async function initSession() {
debugger;
console.log(APPENV);
console.log(LOGONPAYLOAD);
debugger;
if (LOGONPAYLOAD.host == null) {
return 'done';
}
try {
let msg = await store.logon(LOGONPAYLOAD);
console.log(store.connection());
console.log(msg);
} catch (err) {
console.log('Error logging in', JSON.stringify(err, null, 4));
throw err;
}
let name = 'user';
//document.getElementById('output').innerHTML = '...running';
return 'done';
}
function runit(type) {
let testcase;
switch (type) {
case 'files': {
testcase = SASfileService;
break;
}
case 'compute': {
testcase = dsCompute;
break;
}
case 'cas': {
testcase = runCas;
break;
}
case 'timedout': {
testcase = timedout;
break;
}
case 'redir': {
testcase = noaction;
break;
}
case 'spre': {
testcase = spre;
break;
}
default: {
testcase = SASfileService;
break;
}
}
testcase(store)
.then(r => {
document.getElementById(
'output'
).innerHTML = JSON.stringify(r, null, 4);
})
.catch(err => {
document.getElementById(
'output'
).innerHTML = JSON.stringify(err, null, 4);
});
}
async function noaction() {
r = { msg: 'redirects completed' };
return r;
}
async function spre(store) {
let p = {
method: 'GET',
url: 'http://localhost:3000/api/test',
withCredentials: true
}
let r = await store.request(p);
return r.data;
}
async function timedout(store) {
console.log('timed out at', Date());
let params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,width=0,height=0,left=-1000,top=-1000`;
window.open(`${LOGONPAYLOAD.host}/SASLogon/timedout`, 'Timed Out', params);
return true;
}
async function runCas(store) {
debugger;
let { casManagement } = await store.addServices('casManagement');
let servers = await store.apiCall(
casManagement.links('servers')
);
let serverName = servers.itemsList(0);
let session = await store.apiCall(
servers.itemsCmd(serverName, 'createSession')
);
let payload = {
action: 'builtins.echo',
data: { code: { x: 1 } }
};
console.log(JSON.stringify(session.links("execute"), null, 4));
let r = await store.runAction(session, payload);
console.log('echo completed');
await store.apiCall(session.links('delete'));
return r.items();
}
async function SASfileService(store) {
debugger;
let content;
try {
debugger;
let { files } = await store.addServices('files');
debugger;
console.log(JSON.stringify(files.links(), null, 4));
//console.log('items - should be an array of files(empty array is ok)')
// console.log(files.items().toJS());
let payload = {
data: { x: 1, y: 'This was saved earlier in the step' },
headers: { 'content-type': 'application/json' }
};
let createCmd = files.links('create');
let newFile = await store.apiCall(createCmd, payload);
debugger;
console.log(JSON.stringify(newFile.links('content'), null, 4));
content = await store.apiCall(newFile.links('content'));
} catch (err) {
console.log(JSON.stringify(err, null, 4));
debugger;
}
console.log(content);
return content.items();
}
async function dsCompute(store) {
let log = null;
debugger;
let { compute } = await store.addServices('compute');
let servers = await store.apiCall(compute.links('servers'));
let contexts = await store.apiCall(compute.links('contexts'));
// lookup the name of the first context and then use it to get the associated createSession restafLink
let createSession = contexts.itemsCmd(
contexts.itemsList(0),
'createSession'
);
let session = await store.apiCall(createSession);
// Now run a simple data step in that session
let payload = {
data: {
code: [`data _null_; do i = 1 to 100; x=1; end; run; `]
}
};
// Now execute the data step and wait for completion
let job = await store.apiCall(
session.links('execute'),
payload
);
let status = await store.jobState(job, null, 5, 2);
if (status.data === 'running') {
throw `ERROR: Job did not complete in allotted time`;
} else {
switch (status.data) {
case 'warning':
console.log(`Warning: check your log for warnings`);
break;
case 'error':
throw `Please correct errors and rerun program`;
default:
log = await store.apiCall(status.job.links('log'));
break;
}
}
return log === null ? status : log.items();
}
</script>
</head>
<body onload="setup()">
<h1 id="head">Hi</h1>
<div>
<button onclick="runit('redir')">
Press to do some redirs
</button>
<button onclick="runit('files')">
Press to make a call to file service
</button>
<br />
<br />
<button onclick="runit('compute')">
Press to make a call compute service
</button>
<br />
<br />
<button onclick="runit('cas')">
Press to make a call to cas echo
</button>
<br />
<br />
<button onclick="runit('spre')">
REST call
</button>
<br />
<br />
<input id='filename'> </input>
<button onclick="runit('timedout')">
Press to test timedout
</button>
<br />
<br />
<button onclick="logoff()">
logoff
</button>
<br />
</div>
<div>
<pre id="output"></pre>
</div>
</body>
</html>