mirror of
https://github.com/Telecominfraproject/wlan-cloud-loadsim.git
synced 2025-12-31 01:00:43 +00:00
252 lines
8.2 KiB
HTML
252 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<link rel="icon" href="assets/favicon.ico" type="image/x-icon" />
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>OWLS</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
|
|
|
|
<style>
|
|
html, body, #app {
|
|
height: 100%;
|
|
}
|
|
#app {
|
|
display: grid;
|
|
grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
|
|
}
|
|
.sidebar {
|
|
background: #e9ecef;
|
|
}
|
|
.output {
|
|
background: var(--bs-light);
|
|
white-space: pre;
|
|
max-width: 100%;
|
|
overflow: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<div class="sidebar p-3">
|
|
<h1 class="h3">OWLS test</h1>
|
|
<p><em>*open console for more output</em></p>
|
|
|
|
<div class="border border-secondary border-1 p-3 mb-3">
|
|
|
|
<h2 class="h5">API</h2>
|
|
<label class="form-label" for="apiBase">API base</label>
|
|
<input type="text" name="apiBase" v-model="apiBase" class="form-control" />
|
|
<div class="mt-2 d-flex flex-wrap">
|
|
<button class="btn btn-sm btn-secondary" v-on:click="apiGet('/api/v1/nodes')">GET /nodes</button>
|
|
</div>
|
|
<div class="mt-2 d-flex flex-wrap">
|
|
<button class="btn btn-sm btn-secondary" v-on:click="apiGet('/api/v1/ouis')">GET /OUIs</button>
|
|
</div>
|
|
<div class="mt-2 d-flex flex-wrap">
|
|
<button class="btn btn-sm btn-secondary" v-on:click="apiGet('/api/v1/vendors')">GET /vendors</button>
|
|
</div>
|
|
<div class="mt-2 d-flex flex-wrap">
|
|
<button class="btn btn-sm btn-secondary" v-on:click="apiGet('/api/v1/cas')">GET /cas</button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="border border-secondary border-1 p-3 mb-3">
|
|
|
|
<h2 class="h5">Websocket</h2>
|
|
<label class="form-label" for="wss">WebSocket URL</label>
|
|
<input type="text" name="wss" v-model="wss" class="form-control" />
|
|
<div class="mt-2">
|
|
<button v-on:click="setupWebsocket()" class="btn btn-primary">Start</button>
|
|
<button class="btn btn-light mw-2" v-on:click="closeWebsocket()" v-show="socketOpen">Close</button>
|
|
</div>
|
|
|
|
<div class="mb-3" v-if="socketOpen">
|
|
<input type="text" class="form-control w-auto" name="msg" v-model="msg" />
|
|
<button class="btn btn-sm btn-secondary" v-on:click="send()">Send Message</button>
|
|
</div>
|
|
|
|
<div class="mt-3 bg-warning p-2">
|
|
<button class="btn btn-sm btn-light" v-on:click="fakeStream()">{{ fakeStreamLabel }}</button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="p-3">
|
|
|
|
<div id="charts"></div>
|
|
|
|
<h2 class="h3">Output</h2>
|
|
<div class="output">
|
|
<code v-for="(msg, index) in output" :key="index">{{ msg }}</code>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!--
|
|
start of scripts
|
|
-->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha256-t9UJPrESBeG2ojKTIcFLPGF7nHi2vEc7f5A2KpH/UBU=" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/vue@3.0.4/dist/vue.global.js"></script>
|
|
<!-- temporary stats for stream testing -->
|
|
<script src="_tmp-stats.js"></script>
|
|
<script>
|
|
const App = {
|
|
data() {
|
|
return {
|
|
apiBase: 'http://localhost:9090',
|
|
output: [],
|
|
socket: null,
|
|
socketOpen: false,
|
|
wss: 'ws://localhost:9090/ws',
|
|
msg: 'Hello World',
|
|
nodesDict: {},
|
|
nodes: [],
|
|
charts: [],
|
|
streamInterval: null,
|
|
streamIntervalTime: 250,
|
|
streamTimeSince: 0,
|
|
streamOn: false,
|
|
streamIndex: 0,
|
|
}
|
|
},
|
|
created: function() {
|
|
console.log('App loaded')
|
|
},
|
|
methods: {
|
|
|
|
setupWebsocket: function() {
|
|
if( !this.wss ) {
|
|
console.log('Missing websocket URL');
|
|
return false;
|
|
}
|
|
|
|
console.log('Starting websocket...');
|
|
this.socket = new WebSocket(this.wss);
|
|
|
|
this.socket.onmessage = (event) => {
|
|
console.log(event);
|
|
this.output = [];
|
|
// try to pull data into a basic chart
|
|
if( event.data && event.data.value ) {
|
|
this.testLogKernel( event.data );
|
|
} else {
|
|
this.output.push(JSON.parse(event.data));
|
|
}
|
|
}
|
|
|
|
this.socket.onopen = (event) => {
|
|
console.log(event);
|
|
this.output.push('Websocket opened');
|
|
this.socketOpen = true;
|
|
}
|
|
|
|
this.socket.onclose = (event) => {
|
|
this.output.push('Websocket closed');
|
|
this.socketOpen = false;
|
|
}
|
|
|
|
},
|
|
|
|
closeWebsocket: function() {
|
|
if( this.socket )
|
|
this.socket.close();
|
|
},
|
|
|
|
// send a msg through the socket...
|
|
send: function() {
|
|
console.log(`Sending message '${this.msg}'...`);
|
|
// should check if socket is good before
|
|
this.socket.send(this.msg)
|
|
},
|
|
|
|
// generic get
|
|
apiGet: function(path) {
|
|
const location = this.apiBase + path + "?details=1";
|
|
fetch( location )
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log(data);
|
|
this.output = [];
|
|
this.output.push(data);
|
|
});
|
|
},
|
|
|
|
fakeStream: function() {
|
|
if( this.streamInterval ) {
|
|
console.log('Stopping fake stream...');
|
|
clearInterval( this.streamInterval );
|
|
this.streamOn = false;
|
|
} else {
|
|
console.log('Starting fake stream...');
|
|
this.streamInterval = setInterval(() => {
|
|
if( this.streamIndex + 1 >= window.tmpStats.length ) {
|
|
this.streamIndex = 0;
|
|
}
|
|
this.testLogKernel(window.tmpStats[ this.streamIndex ]);
|
|
this.streamIndex++;
|
|
this.streamTimeSince = this.streamIntervalTime * this.streamIndex;
|
|
}, this.streamIntervalTime);
|
|
this.streamOn = true;
|
|
}
|
|
},
|
|
|
|
testLogKernel: function( data ) {
|
|
let idx = null;
|
|
if( !data.node ) {
|
|
return;
|
|
}
|
|
if( data.node in this.nodesDict ) {
|
|
idx = this.nodesDict[data.node];
|
|
} else {
|
|
idx = this.nodes.length;
|
|
this.nodes.push([]);
|
|
this.nodesDict[data.node] = idx;
|
|
// canvas for chart
|
|
const el = document.createElement('canvas');
|
|
el.setAttribute('id', `chart-${idx}`);
|
|
const charts = document.getElementById('charts');
|
|
charts.appendChild(el);
|
|
const chart = new Chart(el, {
|
|
type: 'line',
|
|
data: {
|
|
labels: [],
|
|
datasets: [{
|
|
label: data.node,
|
|
data: this.nodes[idx],
|
|
}]
|
|
},
|
|
});
|
|
this.charts.push( chart );
|
|
}
|
|
if( data.value && data.value.kernel_utilization ) {
|
|
console.log(data.value.kernel_utilization);
|
|
this.charts[idx].data.datasets[0].data.push(data.value.kernel_utilization);
|
|
this.charts[idx].data.labels.push( this.streamTimeSince );
|
|
this.charts[idx].update();
|
|
} else {
|
|
console.log('No kernel utilization');
|
|
}
|
|
},
|
|
|
|
},
|
|
computed: {
|
|
fakeStreamLabel: function() {
|
|
return this.streamOn ? 'Stop Fake Stream' : 'Start Fake Stream'
|
|
}
|
|
},
|
|
};
|
|
|
|
Vue.createApp(App).mount('#app')
|
|
</script>
|
|
</body>
|
|
</html> |