Skip to content

Commit 710fbae

Browse files
author
Anders Breid
authored
Improved design for better useability (#70)
* Fix multiple users may use frontend, request outside web gui. - Funktion to sent backend url as parameter added. - Gui users may now switch backend without affecting each other. - Before saving new instances the code will check if any new instances has been added to not overwrite instances created by other users. - switch-backend delete now recieves the backend to delete and not the backends to not delete. - If file is invalid or non existand it will be recreated. - Default back end properties may be specified in application-properties. - Default parameters may not be removed from gui but must be removed from application-properties first. - Unit tests have been added and updated. * Modified functional tests to work with the new utils changes. * Fixed some functional tests. * fixed code comments * Updated after comments * Fixed minor issues with switching back end * Added unittest for curl commando possibilities. * Extended time out to 11s * fixed some duplicated functions from comments. * updated after comments * updated after comments * Fixed functional tests * Missed to add 2 changes * updated after comments * Improved design for better useability. - Added loading indicator for buttons instead of displaying all then removing few. - Added refresh on change of back end instance. - Added more restfull way of working on front end back end details endpoints. - Better handeling of some error/messages sent to GUI from front end service. - Changed name of "Subscription Handeling" to just "Subscriptions" to be more generic. * Merge * Fix of path variable name * Improved useability and reduced read from disk * Improved useability and reduced read from disk * .
1 parent 98590b4 commit 710fbae

File tree

13 files changed

+165
-61
lines changed

13 files changed

+165
-61
lines changed

src/main/java/com/ericsson/ei/frontend/BackEndInformationController.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,31 +38,31 @@ public class BackEndInformationController {
3838
@Autowired
3939
private BackEndInfoirmationControllerUtils backEndInfoContUtils;
4040

41-
@RequestMapping(value = "/get-instances", method = RequestMethod.GET)
41+
@RequestMapping(value = "/backend", method = RequestMethod.GET)
4242
public ResponseEntity<String> getInstances(Model model, HttpServletRequest request) {
4343
LOG.debug("Recieved request for instances.");
4444
ResponseEntity<String> response = backEndInfoContUtils.handleRequestForInstances(request);
4545
return response;
4646
}
4747

48-
@RequestMapping(value = "/switch-backend", method = RequestMethod.POST)
48+
@RequestMapping(value = "/backend", method = RequestMethod.PUT)
4949
public ResponseEntity<String> switchBackEndInstance(Model model, HttpServletRequest request) {
5050
LOG.debug("Recieved request to switch back end.");
5151
ResponseEntity<String> response = backEndInfoContUtils.handleRequestToSwitchBackEnd(request);
5252
return response;
5353

5454
}
5555

56-
@RequestMapping(value = "/switch-backend", method = RequestMethod.DELETE)
56+
@RequestMapping(value = "/backend", method = RequestMethod.DELETE)
5757
public ResponseEntity<String> deleteBackEndInstance(Model model, HttpServletRequest request) {
5858
LOG.debug("Recieved request to delete back end.");
5959
ResponseEntity<String> response = backEndInfoContUtils.handleRequestToDeleteBackEnd(request);
6060
return response;
6161
}
6262

63-
@RequestMapping(value = "/add-instances", method = RequestMethod.POST)
63+
@RequestMapping(value = "/backend", method = RequestMethod.POST)
6464
public ResponseEntity<String> addInstanceInformation(Model model, HttpServletRequest request) {
65-
LOG.debug("Recieved request to add instance.");
65+
LOG.debug("Recieved request to add back end.");
6666
ResponseEntity<String> response = backEndInfoContUtils.handleRequestToAddBackEnd(request);
6767
return response;
6868
}

src/main/java/com/ericsson/ei/frontend/EIRequestsController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ private ResponseEntity<String> getResponse(HttpRequestBase request) {
162162
try (CloseableHttpResponse eiResponse = client.execute(request)) {
163163
responseBody = StringUtils.defaultIfBlank(EntityUtils.toString(eiResponse.getEntity(), "utf-8"), "[]");
164164
statusCode = eiResponse.getStatusLine().getStatusCode();
165-
LOG.info("EI Http response status code: " + statusCode
165+
LOG.debug("EI Http response status code: " + statusCode
166166
+ "\nEI Received response body:\n" + responseBody
167167
+ "\nForwarding response back to EI Frontend WebUI.");
168168
} catch (IOException e) {

src/main/java/com/ericsson/ei/frontend/utils/BackEndInfoirmationControllerUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.net.URI;
21+
import java.util.Iterator;
2122
import java.util.NoSuchElementException;
2223
import java.util.stream.Collectors;
2324

@@ -67,6 +68,7 @@ public ResponseEntity<String> handleRequestForInstances(HttpServletRequest reque
6768
allAvailableInstances.toString(),
6869
getHeaders(), HttpStatus.OK);
6970
} catch (Exception e) {
71+
LOG.error("ERROR!\n" + e.getMessage());
7072
return new ResponseEntity<>(
7173
"[{\"name\":\"Unable to load instances\",\"host\":\"NO HOST\",\"port\":\"NO PORT\",\"path\":\"/\"}]",
7274
getHeaders(), HttpStatus.OK);

src/main/java/com/ericsson/ei/frontend/utils/BackEndInstancesUtils.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class BackEndInstancesUtils {
4646
private static final String PORT = "port";
4747
private static final String PATH = "path";
4848
private static final String HTTPS = "https";
49+
private static final long SECONDS_BETWEEN_PARSING = 20;
4950

5051
@Value("${ei.backendServerName:#{null}}")
5152
private String defaultBackEndInstanceName;
@@ -57,6 +58,10 @@ public class BackEndInstancesUtils {
5758
private BackEndInstanceFileUtils backEndInstanceFileUtils;
5859

5960
private List<BackEndInformation> backEndInformationList = new ArrayList<>();
61+
private boolean parsing = false;
62+
private boolean isRunningTests = false;
63+
private long nextTimeToParse = 0;
64+
private boolean savedSinceLastParsing = false;
6065

6166
/**
6267
* Function to check weather an instance host, port, path and https is
@@ -215,9 +220,15 @@ private JsonArray parseBackEndsAsJsonArray() {
215220
private void saveBackEndInformationList() {
216221
JsonArray jsonArrayToDump = parseBackEndsAsJsonArray();
217222
backEndInstanceFileUtils.dumpJsonArray(jsonArrayToDump);
223+
savedSinceLastParsing = true;
218224
}
219225

220226
private void parseBackEndInstances() {
227+
if (!parsingIsApplicable()) {
228+
return;
229+
}
230+
parsing = true;
231+
221232
try {
222233
JsonArray instances = backEndInstanceFileUtils.getInstancesFromFile();
223234
backEndInformationList.clear();
@@ -228,6 +239,38 @@ private void parseBackEndInstances() {
228239
} catch (IOException e) {
229240
LOG.error("Failure when trying to parse json " + e.getMessage());
230241
}
242+
243+
parsing = false;
244+
savedSinceLastParsing = false;
245+
nextTimeToParse = System.currentTimeMillis() + (SECONDS_BETWEEN_PARSING * 1000);
246+
}
247+
248+
private boolean parsingIsApplicable() {
249+
// Parse for tests
250+
if (isRunningTests) {
251+
return true;
252+
}
253+
254+
// Check if we currently are parsing.
255+
if (parsing) {
256+
long stopTime = System.currentTimeMillis() + 10000;
257+
while (parsing && stopTime > System.currentTimeMillis()) {
258+
// Do nothing for maximum of 10 seconds.
259+
}
260+
return false;
261+
}
262+
263+
// Check if we did not parse for some time.
264+
if (nextTimeToParse <= System.currentTimeMillis()) {
265+
return true;
266+
}
267+
268+
// Check if we did any save after last parsing.
269+
if (savedSinceLastParsing ) {
270+
return true;
271+
}
272+
273+
return false;
231274
}
232275

233276
private void ensureDefaultBackEnd() {
@@ -245,6 +288,5 @@ private void ensureDefaultBackEnd() {
245288
}
246289
}
247290
backEndInformationList.add(defaultBackendInformation);
248-
saveBackEndInformationList();
249291
}
250292
}

src/main/resources/static/css/style.css

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
white-space: normal;
1515
}
1616
.card-switch-backend {
17-
max-width: 40rem;
17+
max-width: 40rem;
1818
}
1919
.table-responsive>.table-bordered {
2020
border: 1px solid #dee2e6;
@@ -40,6 +40,30 @@
4040
align-items: center;
4141
flex-flow: column;
4242
}
43+
.subButtons {
44+
display: none;
45+
}
46+
.loader {
47+
border-width: 7px;
48+
border-radius: 50%;
49+
border-style: dotted;
50+
border-top-color: #007bff;
51+
border-right-color: #28a745;
52+
border-bottom-color: #dc3545;
53+
border-left-color: #17a2b8;
54+
width: 45px;
55+
height: 45px;
56+
animation: spin 1s cubic-bezier(.86,0,.07,1) infinite;
57+
}
58+
/* Safari */
59+
@-webkit-keyframes spin {
60+
0% { -webkit-transform: rotate(0deg); }
61+
100% { -webkit-transform: rotate(360deg); }
62+
}
63+
@keyframes spin {
64+
0% { transform: rotate(0deg); }
65+
100% { transform: rotate(360deg); }
66+
}
4367
@media (max-width: 576px) {
4468
.container {
4569
max-width: 480px;

src/main/resources/static/js/add-instances.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
jQuery(document).ready(function() {
22
var frontendServiceUrl = $('#frontendServiceUrl').text();
3+
var frontendServicePath = "/backend";
34
function instanceModel() {
45
var self = this;
56
self.instance = {
@@ -19,16 +20,16 @@ function instanceModel() {
1920
$.jGrowl("Port value should be from 1 to 65535", {sticky: false, theme: 'Error'});
2021
} else {
2122
$.ajax({
22-
url: frontendServiceUrl + "/add-instances",
23+
url: frontendServiceUrl + frontendServicePath,
2324
type: "POST",
2425
data: data,
2526
contentType: 'application/json; charset=utf-8',
2627
cache: false,
2728
error: function (XMLHttpRequest, textStatus, errorThrown) {
28-
window.logMessages(XMLHttpRequest.responseText);
29+
window.logMessages(JSON.parse(XMLHttpRequest.responseText)["message"]);
2930
},
3031
success: function (responseData, XMLHttpRequest, textStatus) {
31-
$.jGrowl("Added new backend instance", {sticky: false, theme: 'Notify'});
32+
$.jGrowl(responseData.message, {sticky: false, theme: 'Notify'});
3233
$("#mainFrame").load("switch-backend.html");
3334
}
3435
});

src/main/resources/static/js/main.js

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,24 @@ jQuery(document).ready(function() {
1515
// Fetch injected URL from DOM
1616
var eiffelDocumentationUrlLinks = $('#eiffelDocumentationUrlLinks').text();
1717
var frontendServiceUrl = $('#frontendServiceUrl').text();
18+
var frontendServiceBackEndPath = "/backend";
1819

1920
function loadMainPage() {
21+
updateBackEndInstanceList();
2022
$("#navbarResponsive").removeClass("show");
2123
$("#selectInstances").visible();
2224
$("#mainFrame").load("subscriptionpage.html");
2325
}
2426

2527
$("#testRulesBtn").click(function() {
28+
updateBackEndInstanceList();
2629
$("#navbarResponsive").removeClass("show");
2730
$("#selectInstances").visible();
2831
$("#mainFrame").load("testRules.html");
2932
});
3033

3134
$("#eiInfoBtn").click(function() {
35+
updateBackEndInstanceList();
3236
$("#navbarResponsive").removeClass("show");
3337
$("#selectInstances").visible();
3438
$("#mainFrame").load("eiInfo.html");
@@ -138,35 +142,42 @@ jQuery(document).ready(function() {
138142
self.onChange = function(){
139143
if(typeof self.selectedActive() !== "undefined"){
140144
$.ajax({
141-
url: frontendServiceUrl + "/switch-backend",
142-
type: "POST",
145+
url: frontendServiceUrl + frontendServiceBackEndPath,
146+
type: "PUT",
143147
data: self.selectedActive(),
144148
contentType: 'application/json; charset=utf-8',
145149
cache: false,
146150
error: function (XMLHttpRequest, textStatus, errorThrown) {
147151
window.logMessages(XMLHttpRequest.responseText);
148152
},
149153
success: function (responseData, XMLHttpRequest, textStatus) {
150-
$.jGrowl(XMLHttpRequest.responseText, {sticky: false, theme: 'Notify'});
154+
console.log("Response from IE front end back end: " + responseData.message);
155+
$.jGrowl(responseData.message, {sticky: false, theme: 'Notify'});
156+
$("#navbarResponsive").removeClass("show");
157+
$("#selectInstances").visible();
158+
$("#mainFrame").load("subscriptionpage.html");
151159
}
152160
});
153161
} else {
154162
$.jGrowl("Please chose backend instance", {sticky: false, theme: 'Error'});
155163
}
156164
}
157-
}
158-
$.ajax({
159-
url: frontendServiceUrl + "/get-instances",
160-
type: "GET",
161-
contentType: 'application/json; charset=utf-8',
162-
cache: false,
163-
error: function (XMLHttpRequest, textStatus, errorThrown) {
164-
window.logMessages("Failure when trying to load backend instances");
165-
},
166-
success: function (responseData, XMLHttpRequest, textStatus) {
167-
var observableObject = $("#selectInstances")[0];
168-
ko.cleanNode(observableObject);
169-
ko.applyBindings(new viewModel(responseData),observableObject);
170-
}
171-
});
165+
}
166+
function updateBackEndInstanceList() {
167+
$.ajax({
168+
url: frontendServiceUrl + frontendServiceBackEndPath,
169+
type: "GET",
170+
contentType: 'application/json; charset=utf-8',
171+
cache: false,
172+
error: function (XMLHttpRequest, textStatus, errorThrown) {
173+
window.logMessages("Failure when trying to load backend instances");
174+
},
175+
success: function (responseData, XMLHttpRequest, textStatus) {
176+
var observableObject = $("#selectInstances")[0];
177+
ko.cleanNode(observableObject);
178+
ko.applyBindings(new viewModel(responseData),observableObject);
179+
}
180+
});
181+
}
182+
updateBackEndInstanceList();
172183
});

src/main/resources/static/js/subscription.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -560,17 +560,17 @@ jQuery(document).ready(function () {
560560
success: function (data, textStatus) {
561561
var returnData = [data];
562562
if (returnData.length > 0) {
563-
$.jGrowl("Subscriptions are successfully created", {
563+
$.jGrowl("Subscriptions were successfully created.", {
564564
sticky: false,
565565
theme: 'Error'
566566
});
567567
reload_table();
568568
}
569569
},
570570
error: function (XMLHttpRequest, textStatus, errorThrown) {
571-
window.logMessages("Failed to create next Subscriptions");
571+
window.logMessages("Failed to create Subscriptions.");
572572
reload_table();
573-
$.jGrowl("Failed to create next Subscriptions", { sticky: false, theme: 'Error' });
573+
$.jGrowl("Failed to create Subscriptions.", { sticky: false, theme: 'Error' });
574574
var responseJSON = JSON.parse(XMLHttpRequest.responseText);
575575
for (var i = 0; i < responseJSON.length; i++) {
576576
$.jGrowl(responseJSON[i].subscription + " :: " + responseJSON[i].reason, { sticky: true, theme: 'Error' });
@@ -615,7 +615,7 @@ jQuery(document).ready(function () {
615615
validateJsonAndCreateSubscriptions(file);
616616
}
617617

618-
// If MS Internet Explorer -> special handling for creating download file window.
618+
// If MS Internet Explorer -> special handling for creating download file window.
619619
if (window.navigator.msSaveOrOpenBlob) {
620620
createUploadWindowMSExplorer();
621621
}
@@ -916,4 +916,11 @@ jQuery(document).ready(function () {
916916
});
917917
});
918918
// /Stop ## Delete Subscription #########################################
919+
920+
// Delay display buttons
921+
setTimeout(showButtons, 800);
922+
function showButtons() {
923+
$(".loadingAnimation").hide();
924+
$(".subButtons").show();
925+
}
919926
});

src/main/resources/static/js/switch-instances.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
jQuery(document).ready(function() {
22
var frontendServiceUrl = $('#frontendServiceUrl').text();
3+
var frontendServiceBackEndPath = "/backend";
34
var sendbtn = document.getElementById('switcher').disabled = true;
45
function singleInstanceModel(name, host, port, path, https, active) {
56
this.name = ko.observable(name),
@@ -27,7 +28,7 @@ function multipleInstancesModel(data) {
2728
self.removeInstance = function() {
2829
self.instances.remove(this);
2930
$.ajax({
30-
url: frontendServiceUrl + "/switch-backend",
31+
url: frontendServiceUrl + frontendServiceBackEndPath,
3132
type: "DELETE",
3233
data: ko.toJSON(this),
3334
contentType: 'application/json; charset=utf-8',
@@ -36,7 +37,7 @@ function multipleInstancesModel(data) {
3637
window.logMessages(XMLHttpRequest.responseText);
3738
},
3839
success: function (responseData, XMLHttpRequest, textStatus) {
39-
$.jGrowl("Backend instance was deleted", {sticky: false, theme: 'Notify'});
40+
$.jGrowl(responseData.message, {sticky: false, theme: 'Notify'});
4041
}
4142
});
4243
}
@@ -53,22 +54,26 @@ function multipleInstancesModel(data) {
5354
self.instances.push(instance);
5455
}
5556
$.ajax({
56-
url: frontendServiceUrl + "/switch-backend",
57-
type: "POST",
57+
url: frontendServiceUrl + frontendServiceBackEndPath,
58+
type: "PUT",
5859
data: ko.toJSON(self.instances),
5960
contentType: 'application/json; charset=utf-8',
6061
cache: false,
6162
error: function (XMLHttpRequest, textStatus, errorThrown) {
6263
window.logMessages(XMLHttpRequest.responseText);
6364
},
6465
success: function (responseData, XMLHttpRequest, textStatus) {
65-
$(location).attr('href', frontendServiceUrl)
66+
console.log("Response from IE front end back end: " + responseData.message);
67+
$.jGrowl(responseData.message, {sticky: false, theme: 'Notify'});
68+
$("#navbarResponsive").removeClass("show");
69+
$("#selectInstances").visible();
70+
$("#mainFrame").load("subscriptionpage.html");
6671
}
6772
});
6873
}
6974
}
7075
$.ajax({
71-
url: frontendServiceUrl + "/get-instances",
76+
url: frontendServiceUrl + frontendServiceBackEndPath,
7277
type: "GET",
7378
contentType: 'application/json; charset=utf-8',
7479
cache: false,

0 commit comments

Comments
 (0)