source: src/main/webapp/newsession.xhtml@ 1

Last change on this file since 1 was 1, checked in by bart, 5 years ago

Initial Release

File size: 10.5 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
3<head>
4<title>Profiles and Domains list</title>
5<link rel="stylesheet" type="text/css" href="style.css" />
6
7</head>
8<body onload="init()">
9 <h1>Session</h1>
10
11 On this page you can configure the settings for running a new session
12 and start the session.
13
14 <br /> Protocol:
15 <select>
16 <option value="SAOP">SAOP</option>
17 </select>
18
19 <br /> Deadline:
20 <input type="number" id="deadlinevalue" name="deadline" min="1"
21 max="10000" value="10" />
22 <select id="deadlinetype">
23 <option value="TIME">seconds</option>
24 <option value="ROUNDS">rounds</option>
25 </select>
26
27 <br /> Domain/Profile Server:
28 <input type="url" name="url" id="profilesserverurl"
29 value="localhost:8080/profilesserver-1.0.0"
30 pattern=".*:[0-9]+/profilesserver" size="30"
31 onchange="connectDomain()"> </input>
32 <br /> Domain:
33 <select id="domainselection" onclick="selectDomain()">
34 <!-- <option>Waiting for profiles server</option> -->
35 </select>
36
37 <br />
38 <br />
39
40 <div id="box" class="box">
41 <br /> <b>Participants</b> <br /> Parties Server: <input type="url"
42 name="url" id="partiesserverurl" value="localhost:8080/partiesserver-1.0.0"
43 pattern=".*:[0-9]+/partiesserver" size="30"
44 onchange="connectParties()"> </input> <br />
45 <br /> <b>Edit next party</b> <br /> Party: <select id="partyselection">
46 </select> <br /> Profile: <select id="profileselection">
47 </select> <br />
48
49 <button onclick="addParty()">Add</button>
50
51
52 <br /> <br /> <b>Selected Profiles, Parties for the session</b>
53 <table>
54 <thead>
55 <th align="left" width='40%'>Party</th>
56 <th align="left" width='40%'>Profile</th>
57 </thead>
58 <tbody id="partiesList">
59 <tr id="partiesList">
60 </tr>
61
62 </tbody>
63 </table>
64
65 </div>
66
67 <form>
68 <input id="startbutton" type="button" value="Start Session"
69 onclick="start()" />
70 </form>
71
72 <div id="started" style="visibility: hidden">
73 Your session started.<br /> <a href="" id="logref">view the log
74 file</a> <br /> <a href="" id="plotref">render a utilities plot</a>.
75 </div>
76
77</body>
78
79<script type="application/javascript">
80
81
82 // FIXME quick and dirty code. No clean MVC
83
84
85 <![CDATA[
86 "use strict";
87
88 var domainwebsocket = null;
89 var partieswebsocket=null;
90 // currently known domains (and profiles) as coming from domainwebsocket.
91 // keys are domain names, values are list of profile names
92 var knowndomains={};
93
94 /**
95 List of created participants for the session. Each participant is a dictionary.
96 Each dict element contains keys
97 "party" and "profile", both containing a String containing
98 a valid IRI to the party resp. the profile to use.
99 The party should contain a IRI that gives a new instance of the required party.
100 The profile should contain an IRI that gives the profile contents.
101 */
102 var partyprofiles=[];
103
104
105 /**
106 Refresh known domains using given profilesserver URL.
107 Called when user enters URL for domain server.
108 */
109 function connectDomain() {
110 if (domainwebsocket!=null) {
111 domainwebsocket.close();
112 domainwebsocket=null;
113 }
114 var url=document.getElementById("profilesserverurl").value;
115 var target = "ws://"+url+"/websocket/liststream";
116 if ('WebSocket' in window) {
117 domainwebsocket = new WebSocket(target);
118 } else if ('MozWebSocket' in window) {
119 domainwebsocket = new MozWebSocket(target);
120 } else {
121 alert('WebSocket is not supported by this browser. Please use a newer browser');
122 return;
123 }
124 domainwebsocket.onopen = function () {
125 // whatever.
126 };
127 domainwebsocket.onmessage = function (event) {
128 updateDomainComboBox(JSON.parse(event.data));
129 };
130 domainwebsocket.onclose = function (event) {
131 alert('Info: Server closed connection. Code: ' + event.code +
132 (event.reason == "" ? "" : ", Reason: " + event.reason));
133 domainwebsocket=null;
134 updateDomainComboBox({});
135 };
136 }
137
138 /**
139 Sets a new knowndomains value and Updates the contents of the domain selector combobox.
140 @param the known domains, a map of the form {"jobs":["jobs1","jobs2"]}
141 where the keys are the names of the available domains nd the values a list of the available profiles in that domain.
142
143 */
144 function updateDomainComboBox(newdomains) {
145 knowndomains=newdomains
146 var combobox = document.getElementById("domainselection");
147 combobox.options.length=0;
148 for (var domain in knowndomains) {
149 var option = document.createElement('option');
150 option.text = option.value = domain;
151 combobox.add(option, 0);
152 }
153 selectDomain();
154 }
155 /**
156 Refresh known parties using given partiesserver URL.
157 Called when user enters URL for parties server.
158 */
159 function connectParties() {
160 if (partieswebsocket!=null) {
161 partieswebsocket.close();
162 partieswebsocket=null;
163 }
164 var url=document.getElementById("partiesserverurl").value;
165 var target = "ws://"+url+"/available";
166 if ('WebSocket' in window) {
167 partieswebsocket = new WebSocket(target);
168 } else if ('MozWebSocket' in window) {
169 partieswebsocket = new MozWebSocket(target);
170 } else {
171 alert('WebSocket is not supported by this browser. Please use a newer browser');
172 return;
173 }
174 partieswebsocket.onopen = function () {
175 // whatever.
176 };
177 partieswebsocket.onmessage = function (event) {
178 updateParties(JSON.parse(event.data));
179 };
180 partieswebsocket.onclose = function (event) {
181 alert('Info: Server closed connection. Code: ' + event.code +
182 (event.reason == "" ? "" : ", Reason: " + event.reason));
183 partieswebsocket=null;
184 updateParties({});
185 };
186 }
187
188
189 /**
190 refresh table: copy all parties elements in there.
191 Typically parties is something like
192 [{"uri":"http:130.161.180.1:8080/partiesserver/run/randomparty-1.0.0",
193 "capabilities":{"protocols":["SAOP"]},
194 "description":"places random bids until it can accept an offer with utility >0.6",
195 "id":"randomparty-1.0.0",
196 "partyClass":"geniusweb.exampleparties.randomparty.RandomParty"},
197 ...]
198 */
199 function updateParties(parties) {
200 var combobox = document.getElementById("partyselection");
201 combobox.options.length=0;
202 for (var party in parties) {
203 var option = document.createElement('option');
204 option.text = option.value = parties[party].uri;
205 combobox.add(option, 0);
206 }
207 }
208
209
210
211
212 /**
213 Called when the selected domain changes. Assumes knowndomains has been set.
214 Updates the available profiles in the profile combobox.
215 @param selection the name of the selected domain.
216 */
217 function selectDomain() {
218 // determined current selection
219 var domaincombobox = document.getElementById("domainselection");
220 if (domaincombobox.options.length==0) return; // fixme clean profiles options?
221 var domain = domaincombobox.options[domaincombobox.selectedIndex].value;
222
223 var profilecombo = document.getElementById("profileselection");
224 profilecombo.options.length=0;
225 for (var profile in knowndomains[domain]) {
226 var option = document.createElement('option');
227 option.text = option.value = knowndomains[domain][profile];
228 profilecombo.add(option, 0);
229 }
230 }
231
232 /**
233 Called when user clicks "Add"
234 */
235 function addParty() {
236 var partycombo = document.getElementById("partyselection");
237 var profilecombo = document.getElementById("profileselection");
238
239 if (partycombo.options.length==0) {
240 alert("Please set partier server and select a party");
241 return;
242 }
243 if (profilecombo.options.length==0) {
244 alert("Please set domain/profile server and select a domain and a profile");
245 return;
246 }
247 var newpartyprof = {};
248 newpartyprof["party"]=partycombo.options[partycombo.selectedIndex].value;
249 newpartyprof["profile"]=profilecombo.options[profilecombo.selectedIndex].value;
250
251 partyprofiles.push(newpartyprof)
252 updatePartyProfileTable(); // what, MVC?
253 }
254
255 /** updates the party and profiles table, to match the #partyprofiles list. */
256 function updatePartyProfileTable() {
257 var table = document.getElementById("partiesList");
258 table.innerHTML = ""; // clear table
259 for ( var pp in partyprofiles) {
260 var row = table.insertRow(-1);
261 var cell1 = row.insertCell(-1);
262 var cell2 = row.insertCell(-1);
263 cell1.innerHTML = partyprofiles[pp]["party"];
264 cell2.innerHTML = partyprofiles[pp]["profile"];
265 }
266
267 }
268
269 /**
270 start the session as currently set on this page.
271 We need to send a SessionSettings object to the server, which typically looks like this
272 but is protocol dependent (currently we do SAOP)
273
274 {"SAOPSettings":
275 {"participants":[
276 {"party":"http://party1","profile":"ws://profile1"},
277 {"party":"http://party2","profile":"ws://profile2"}],
278 "deadline":{"deadlinetime":{"durationms":100}}}}
279
280 participants are already in the global partyprofiles dictionary
281 */
282 function start() {
283 if (Object.keys(partyprofiles).length <2) {
284 alert("At least 2 parties are needed to run a session.");
285 return;
286 }
287
288 // see https://www.w3schools.com/xml/dom_httprequest.asp
289 var xmlHttp = new XMLHttpRequest();
290 xmlHttp.onreadystatechange = function() {
291 if (this.readyState == 4) {
292 if (this.status == 200) {
293 document.getElementById("startbutton").disabled=true;
294 document.getElementById("started").setAttribute("style","");
295 document.getElementById("logref").href="log/"+this.responseText+".json";
296 document.getElementById("plotref").href="plotlog.xhtml?id="+this.responseText;
297
298 }
299 else
300 alert("request failed:"+this.statusText);
301 }
302 }
303 xmlHttp.open("POST", "run", true);
304 xmlHttp.send(makeRequest());
305
306 }
307
308
309 /**
310 @return a json request package for the run server
311 */
312 function makeRequest() {
313 var deadline={};
314 var value = document.getElementById("deadlinevalue").value;
315 var dtypecombo = document.getElementById("deadlinetype");
316 if (dtypecombo.options[dtypecombo.selectedIndex].value=="TIME") {
317 deadline["deadlinetime"] = { "durationms": 1000*value};
318 } else {
319 // ROUNDS
320 deadline["deadlinerounds"] = {"rounds": value, "durationms":10000};
321 }
322
323
324 return JSON.stringify({"SAOPSettings": { "participants": partyprofiles, "deadline":deadline }});
325
326 }
327
328
329 /**
330 Initialize the page after html is loaded.
331 */
332 function init() {
333 connectDomain();
334 connectParties();
335
336 }
337 ]]>
338
339
340</script>
341
342</html>
Note: See TracBrowser for help on using the repository browser.