Skip to content

Commit ef13940

Browse files
committed
Beautify and cleanup
1 parent 28f950d commit ef13940

File tree

3 files changed

+433
-29
lines changed

3 files changed

+433
-29
lines changed

src/main/resources/SampleRoutes.html

Lines changed: 334 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,341 @@
33
<head>
44
<meta charset="utf-8">
55
<title>Sample routes for akka-http</title>
6+
<style>
7+
body {
8+
font-family: Arial, sans-serif;
9+
max-width: 800px;
10+
margin: 0 auto;
11+
padding: 20px;
12+
}
13+
14+
.section {
15+
margin: 20px 0;
16+
padding: 15px;
17+
border: 1px solid #ddd;
18+
border-radius: 5px;
19+
}
20+
21+
.section h3 {
22+
margin-top: 0;
23+
color: #333;
24+
}
25+
26+
form {
27+
margin: 10px 0;
28+
}
29+
30+
input, textarea, select {
31+
margin: 5px;
32+
padding: 5px;
33+
}
34+
35+
button, input[type="submit"] {
36+
background-color: #4CAF50;
37+
color: white;
38+
padding: 8px 16px;
39+
border: none;
40+
border-radius: 4px;
41+
cursor: pointer;
42+
}
43+
44+
button:hover, input[type="submit"]:hover {
45+
background-color: #45a049;
46+
}
47+
48+
.result {
49+
margin: 10px 0;
50+
padding: 10px;
51+
background-color: #f9f9f9;
52+
border-left: 4px solid #4CAF50;
53+
display: none;
54+
}
55+
56+
.error {
57+
border-left-color: #f44336;
58+
background-color: #ffebee;
59+
}
60+
</style>
661
</head>
762
<body>
8-
<a href="http://127.0.0.1:6002/entries">entries</a>
9-
<br>
10-
<a href="http://127.0.0.1:6002/faultyActor">faultyActor</a>
11-
<br>
12-
<form method="post" action="http://127.0.0.1:6002/post">
13-
<label for="color">Color:</label><br>
14-
<input type="text" id="color" name="color"><br>
15-
<label for="age">Age:</label><br>
16-
<input type="text" id="age" name="age"><br>
17-
<input type="submit" value="Submit">
18-
</form>
63+
<h1>Akka HTTP Sample Routes Demo</h1>
64+
65+
<div class="section">
66+
<h3>Browse Directory Entries</h3>
67+
<p>Browse files in the system temp directory:</p>
68+
<a href="http://127.0.0.1:6002/entries" target="_blank">
69+
<button type="button">Browse Entries</button>
70+
</a>
71+
</div>
72+
73+
<div class="section">
74+
<h3>Form Data Submission</h3>
75+
<p>Submit form data with validation (age must be > 18):</p>
76+
<form method="post" action="http://127.0.0.1:6002/post">
77+
<label for="color">Color:</label><br>
78+
<input type="text" id="color" name="color" placeholder="Enter a color" required><br><br>
79+
<label for="age">Age:</label><br>
80+
<input type="number" id="age" name="age" placeholder="Enter age" required><br><br>
81+
<input type="submit" value="Submit Form Data">
82+
</form>
83+
</div>
84+
85+
<div class="section">
86+
<h3>Faulty Actor Test</h3>
87+
<p>Test the faulty actor that demonstrates error handling:</p>
88+
<p><em>Note: This actor may behave differently on first vs subsequent requests</em></p>
89+
<button onclick="testFaultyActor()">Test Faulty Actor</button>
90+
<button onclick="testFaultyActorMultiple()">Test Multiple Times (5x)</button>
91+
<button onclick="clearFaultyResults()">Clear Results</button>
92+
<div id="faultyResult" class="result"></div>
93+
<div id="faultyHistory" style="margin-top: 10px;"></div>
94+
</div>
95+
96+
<div class="section">
97+
<h3>Accept Header Test</h3>
98+
<p>Test different Accept headers (always returns JSON):</p>
99+
<button onclick="testAcceptHeader('application/json')">Test JSON Accept</button>
100+
<button onclick="testAcceptHeader('text/csv')">Test CSV Accept</button>
101+
<button onclick="testAcceptHeader('text/plain')">Test Plain Text Accept</button>
102+
<button onclick="testAcceptHeader('text/xml')">Test XML Accept</button>
103+
<div id="acceptResult" class="result"></div>
104+
</div>
105+
106+
<div class="section">
107+
<h3>Raw JSON POST</h3>
108+
<p>Send raw JSON data via POST:</p>
109+
<textarea id="jsonInput" rows="4" cols="50" placeholder='{"account":{"name":"TEST"}}'></textarea><br>
110+
<button onclick="sendRawJson()">Send Raw JSON</button>
111+
<div id="jsonResult" class="result"></div>
112+
</div>
113+
114+
<div class="section">
115+
<h3>XML Response Test</h3>
116+
<p>Get a sample XML response:</p>
117+
<button onclick="getXmlResponse()">Get XML Response</button>
118+
<div id="xmlResult" class="result"></div>
119+
</div>
120+
121+
<div class="section">
122+
<h3>User Path Matching</h3>
123+
<p>Test different user path patterns:</p>
124+
<div style="background-color: #f0f8ff; padding: 10px; margin: 10px 0; border-left: 4px solid #2196F3; font-family: monospace;">
125+
<strong>Path Patterns:</strong><br>
126+
<code>/users</code> - All users<br>
127+
<code>/users/{userId}</code> - Single user (e.g., /users/123)<br>
128+
<code>/users/{userId}/{action}</code> - User action (e.g., /users/123/edit)<br>
129+
<code>/users/{userId}/{action}/...</code> - Complex nested paths
130+
</div>
131+
<div>
132+
<a href="http://127.0.0.1:6002/users" target="_blank">
133+
<button type="button">All Users</button>
134+
</a>
135+
</div>
136+
<div>
137+
<input type="text" id="userId" placeholder="Enter user ID" value="123">
138+
<button onclick="testUserPath()">Test Single User</button>
139+
</div>
140+
<div>
141+
<input type="text" id="userIdAction" placeholder="User ID" value="123">
142+
<input type="text" id="userAction" placeholder="Action" value="edit">
143+
<button onclick="testUserAction()">Test User Action</button>
144+
</div>
145+
<div>
146+
<input type="text" id="complexPath" placeholder="users/123/edit/profile/settings"
147+
value="users/123/edit/profile/settings">
148+
<button onclick="testComplexPath()">Test Complex Path</button>
149+
</div>
150+
</div>
151+
152+
<script>
153+
function showResult(elementId, content, isError = false) {
154+
const resultDiv = document.getElementById(elementId);
155+
resultDiv.innerHTML = content;
156+
resultDiv.className = isError ? 'result error' : 'result';
157+
resultDiv.style.display = 'block';
158+
}
159+
160+
function testAcceptHeader(acceptType) {
161+
fetch('http://127.0.0.1:6002/acceptAll', {
162+
method: 'GET',
163+
headers: {
164+
'Accept': acceptType
165+
}
166+
})
167+
.then(response => response.json())
168+
.then(data => {
169+
showResult('acceptResult', `Accept: ${acceptType}<br>Response: ${JSON.stringify(data)}`);
170+
})
171+
.catch(error => {
172+
showResult('acceptResult', `Error: ${error.message}`, true);
173+
});
174+
}
175+
176+
function sendRawJson() {
177+
const jsonData = document.getElementById('jsonInput').value || '{"account":{"name":"TEST"}}';
178+
179+
fetch('http://127.0.0.1:6002/jsonRaw', {
180+
method: 'POST',
181+
headers: {
182+
'Content-Type': 'application/json'
183+
},
184+
body: jsonData
185+
})
186+
.then(response => {
187+
if (response.ok) {
188+
showResult('jsonResult', `JSON sent successfully!<br>Data: ${jsonData}`);
189+
} else {
190+
showResult('jsonResult', `Error: ${response.status} ${response.statusText}`, true);
191+
}
192+
})
193+
.catch(error => {
194+
showResult('jsonResult', `Error: ${error.message}`, true);
195+
});
196+
}
197+
198+
function getXmlResponse() {
199+
fetch('http://127.0.0.1:6002/okResponseXml')
200+
.then(response => response.text())
201+
.then(data => {
202+
// Create a temporary element to safely escape the XML content
203+
const tempDiv = document.createElement('div');
204+
tempDiv.textContent = data;
205+
showResult('xmlResult', `XML Response:<br><pre>${tempDiv.innerHTML}</pre>`);
206+
})
207+
.catch(error => {
208+
showResult('xmlResult', `Error: ${error.message}`, true);
209+
});
210+
}
211+
212+
function testUserPath() {
213+
const userId = document.getElementById('userId').value || '123';
214+
window.open(`http://127.0.0.1:6002/users/${userId}`, '_blank');
215+
}
216+
217+
function testUserAction() {
218+
const userId = document.getElementById('userIdAction').value || '123';
219+
const action = document.getElementById('userAction').value || 'edit';
220+
window.open(`http://127.0.0.1:6002/users/${userId}/${action}`, '_blank');
221+
}
222+
223+
function testComplexPath() {
224+
const path = document.getElementById('complexPath').value || 'users/123/edit/profile/settings';
225+
window.open(`http://127.0.0.1:6002/${path}`, '_blank');
226+
}
227+
228+
// Set default JSON in textarea
229+
document.getElementById('jsonInput').value = '{"account":{"name":"TEST"}}';
230+
231+
let faultyTestCount = 0;
232+
let faultyHistory = [];
233+
234+
function testFaultyActor() {
235+
faultyTestCount++;
236+
const startTime = new Date();
237+
238+
showResult('faultyResult', `Testing faulty actor (Request #${faultyTestCount})...`);
239+
240+
fetch('http://127.0.0.1:6002/faultyActor', {
241+
method: 'GET'
242+
})
243+
.then(response => {
244+
const endTime = new Date();
245+
const duration = endTime - startTime;
246+
247+
if (response.ok) {
248+
return response.text().then(text => {
249+
const result = `✅ Request #${faultyTestCount} - SUCCESS (${duration}ms)<br>Response: ${text}`;
250+
showResult('faultyResult', result);
251+
addToHistory(faultyTestCount, 'SUCCESS', duration, text);
252+
});
253+
} else {
254+
// Handle error responses (4xx, 5xx status codes)
255+
return response.text().then(text => {
256+
let errorDisplay = `${response.status} ${response.statusText}`;
257+
try {
258+
const errorResponse = JSON.parse(text);
259+
if (errorResponse.error && errorResponse.message) {
260+
errorDisplay = `${errorResponse.error}: ${errorResponse.message}`;
261+
} else if (text) {
262+
errorDisplay = text;
263+
}
264+
} catch (parseError) {
265+
if (text) {
266+
errorDisplay = text;
267+
}
268+
}
269+
270+
const result = `❌ Request #${faultyTestCount} - ERROR (${duration}ms)<br>Status: ${response.status}<br>Error: ${errorDisplay}`;
271+
showResult('faultyResult', result, true);
272+
addToHistory(faultyTestCount, 'ERROR', duration, errorDisplay);
273+
});
274+
}
275+
})
276+
.catch(error => {
277+
const endTime = new Date();
278+
const duration = endTime - startTime;
279+
const result = `❌ Request #${faultyTestCount} - FAILED (${duration}ms)<br>Network Error: ${error.message}`;
280+
showResult('faultyResult', result, true);
281+
addToHistory(faultyTestCount, 'FAILED', duration, error.message);
282+
});
283+
}
284+
285+
function testFaultyActorMultiple() {
286+
const delay = 500; // 500ms delay between requests
287+
for (let i = 0; i < 5; i++) {
288+
setTimeout(() => {
289+
testFaultyActor();
290+
}, i * delay);
291+
}
292+
}
293+
294+
function addToHistory(requestNum, status, duration, response) {
295+
const timestamp = new Date().toLocaleTimeString();
296+
faultyHistory.unshift({
297+
requestNum,
298+
status,
299+
duration,
300+
response,
301+
timestamp
302+
});
303+
304+
// Keep only last 10 results
305+
if (faultyHistory.length > 10) {
306+
faultyHistory = faultyHistory.slice(0, 10);
307+
}
308+
309+
updateHistoryDisplay();
310+
}
311+
312+
function updateHistoryDisplay() {
313+
const historyDiv = document.getElementById('faultyHistory');
314+
if (faultyHistory.length === 0) {
315+
historyDiv.innerHTML = '';
316+
return;
317+
}
318+
319+
let historyHtml = '<h4>Request History:</h4><div style="font-family: monospace; font-size: 12px;">';
320+
faultyHistory.forEach(entry => {
321+
const statusColor = entry.status === 'SUCCESS' ? '#4CAF50' : '#f44336';
322+
historyHtml += `
323+
<div style="margin: 5px 0; padding: 5px; border-left: 3px solid ${statusColor}; background-color: #f9f9f9;">
324+
<strong>#${entry.requestNum}</strong> [${entry.timestamp}]
325+
<span style="color: ${statusColor};">${entry.status}</span>
326+
(${entry.duration}ms)<br>
327+
<small>${entry.response}</small>
328+
</div>
329+
`;
330+
});
331+
historyHtml += '</div>';
332+
historyDiv.innerHTML = historyHtml;
333+
}
334+
335+
function clearFaultyResults() {
336+
faultyTestCount = 0;
337+
faultyHistory = [];
338+
document.getElementById('faultyResult').style.display = 'none';
339+
document.getElementById('faultyHistory').innerHTML = '';
340+
}
341+
</script>
19342
</body>
20343
</html>

0 commit comments

Comments
 (0)