diff --git a/.idea/libraries/fasterxml_jackson_core_databind.xml b/.idea/libraries/fasterxml_jackson_core_databind.xml new file mode 100644 index 0000000..89ea02e --- /dev/null +++ b/.idea/libraries/fasterxml_jackson_core_databind.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/fasterxml_jackson_module_kotlin.xml b/.idea/libraries/fasterxml_jackson_module_kotlin.xml new file mode 100644 index 0000000..ef4f2f3 --- /dev/null +++ b/.idea/libraries/fasterxml_jackson_module_kotlin.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/slf4j_simple.xml b/.idea/libraries/slf4j_simple.xml new file mode 100644 index 0000000..06b1109 --- /dev/null +++ b/.idea/libraries/slf4j_simple.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/tools_jackson_core_databind.xml b/.idea/libraries/tools_jackson_core_databind.xml new file mode 100644 index 0000000..7cca5ce --- /dev/null +++ b/.idea/libraries/tools_jackson_core_databind.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/tools_jackson_module_kotlin.xml b/.idea/libraries/tools_jackson_module_kotlin.xml new file mode 100644 index 0000000..e52274e --- /dev/null +++ b/.idea/libraries/tools_jackson_module_kotlin.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FarmToAAS.iml b/FarmToAAS.iml index 19726ed..2c8a374 100644 --- a/FarmToAAS.iml +++ b/FarmToAAS.iml @@ -16,5 +16,8 @@ + + + \ No newline at end of file diff --git a/config.properties b/config.properties new file mode 100644 index 0000000..85459ca --- /dev/null +++ b/config.properties @@ -0,0 +1,18 @@ +#Configuration saved on 2026-01-21T17:17:53.684082100 +#Wed Jan 21 17:17:53 WIB 2026 +activemq_brokerurl=tcp\://localhost\:61616 +activemq_password=admin +activemq_queuename=TEST.QUEUE +activemq_username=admin +mysql_aas1=jdbc\:mysql\://192.168.10.10\:3306/aas +mysql_aas1_password=admin +mysql_aas1_username=admin +mysql_aas2=jdbc\:mysql\://192.168.10.11\:3306/aas +mysql_aas2_password=admin +mysql_aas2_username=admin +mysql_aas3=\ jdbc\:mysql\://192.168.10.12\:3306/aas +mysql_aas3_password=admin +mysql_aas3_username=admin +webpassword=admin +webport=7000 +webusername=admin diff --git a/html/assets/js/home.js b/html/assets/js/home.js new file mode 100644 index 0000000..e873aea --- /dev/null +++ b/html/assets/js/home.js @@ -0,0 +1,15 @@ +$(document).ready(function() { + // Your code here + console.log("home.js is loaded and ready."); + $('#logoutbtn').on('click', function() { + // Clear session storage on logout + fetch('/logout').then(() => { + window.location.href = '/login.html'; + }); + }); +}); + +$(window).on('beforeunload', function() { + console.log("User is leaving home.html"); + // Your cleanup code here +}); \ No newline at end of file diff --git a/html/assets/js/log.js b/html/assets/js/log.js new file mode 100644 index 0000000..3dbbff4 --- /dev/null +++ b/html/assets/js/log.js @@ -0,0 +1,15 @@ +$(document).ready(function() { + // Your code here + console.log("log.js is loaded and ready."); + $('#logoutbtn').on('click', function() { + // Clear session storage on logout + fetch('/logout').then(() => { + window.location.href = '/login.html'; + }); + }); +}); + +$(window).on('beforeunload', function() { + console.log("User is leaving log.html"); + // Your cleanup code here +}); \ No newline at end of file diff --git a/html/assets/js/login.js b/html/assets/js/login.js new file mode 100644 index 0000000..d13ba5e --- /dev/null +++ b/html/assets/js/login.js @@ -0,0 +1,13 @@ +$(document).ready(function() { + // Your code here + console.log("login.js is loaded and ready."); + const params = new URLSearchParams(window.location.search); + if (params.get("error")) { + alert("Login failed. Please try again."); + } +}); + +$(window).on('beforeunload', function() { + console.log("User is leaving login.html"); + // Your cleanup code here +}); \ No newline at end of file diff --git a/html/assets/js/script.js b/html/assets/js/script.js new file mode 100644 index 0000000..42cbd22 --- /dev/null +++ b/html/assets/js/script.js @@ -0,0 +1,77 @@ +/** + * Checks if a string is valid (not null and not empty) + * @param {string} str + * @returns true if valid, false otherwise + */ +function ValidString(str) { + if (str) { + if (str.length > 0) { + return true; + } + } + return false; +} + +/** + * Performs a POST request to the specified URL with the given data. + * @param {string} url Service endpoint URL + * @param {object} data Data to be sent in the request body + * @param {function} onSuccess callback for successful response + * @param {function} onError callback for error response + */ +function Post(url, data, onSuccess, onError) { + fetch(url, { + method: "POST", + body: JSON.stringify(data) + }).then(response => { + if (response.ok) { + return response.json(); + } else { + let str = `POST request to ${url} failed. Status: ${response.statusText}`; + throw new Error(str); + } + }).then(data => { + if (onSuccess) { + onSuccess(data); + } + }).catch(error => { + if (ValidString(error.message)) { + if (onError) { + onError(error.message); + } else { + console.error(error.message); + } + } else console.log("An unknown error occurred during POST request."); + + }); +} + +/** + * Performs a GET request to the specified URL. + * @param {string} url Service endpoint URL + * @param {function} onSuccess callback for successful response + * @param {function} onError callback for error response + */ +function Get(url, onSuccess, onError) { + fetch(url).then(response => { + if (response.ok) { + return response.json(); + } else { + let str = `GET request to ${url} failed. Status: ${response.statusText}`; + throw new Error(str); + } + }).then(data => { + if (onSuccess) { + onSuccess(data); + } + }).catch(error => { + if (ValidString(error.message)) { + if (onError) { + onError(error.message); + } else { + console.error(error.message); + } + } + else console.log("An unknown error occurred during GET request."); + }); +} \ No newline at end of file diff --git a/html/assets/js/setting.js b/html/assets/js/setting.js new file mode 100644 index 0000000..622d351 --- /dev/null +++ b/html/assets/js/setting.js @@ -0,0 +1,168 @@ +$(document).ready(function () { + // Your code here + console.log("setting.js is loaded and ready."); + + loadSetting(); + + $('#logoutbtn').on('click', function () { + // Clear session storage on logout + fetch('/logout').then(() => { + window.location.href = '/login.html'; + }); + }); + + $('#savefarm').on('click', function () { + saveFarmParameter(); + }); + + $('#saveaas').on('click', function () { + saveAASParameter(); + }); +}); + +$(window).on('beforeunload', function () { + console.log("User is leaving setting.html"); + // Your cleanup code here +}); + +function loadSetting() { + Get("getSetting", function (data) { + if (data) { + if (data.farm) { + if (data.aas1) { + if (data.aas2) { + if (data.aas3) { + // all good + $('#brokerurl').val(data.farm.url); + $('#brokerusername').val(data.farm.username); + $('#brokerpassword').val(data.farm.password); + $('#brokerqueue').val(data.farm.queue); + $('#aas1url').val(data.aas1.url); + $('#aas1username').val(data.aas1.username); + $('#aas1password').val(data.aas1.password); + $('#aas2url').val(data.aas2.url); + $('#aas2username').val(data.aas2.username); + $('#aas2password').val(data.aas2.password); + $('#aas3url').val(data.aas3.url); + $('#aas3username').val(data.aas3.username); + $('#aas3password').val(data.aas3.password); + } else console.log("No AAS 3 data received"); + } else console.log("No AAS 2 data received"); + } else console.log("No AAS 1 data received"); + } else console.log("No FARM data received"); + } else console.log("No data received"); + + }, function (error) { + alert(error); + }) + +} + +function saveFarmParameter() { + let url = $('#brokerurl').val(); + let username = $('#brokerusername').val(); + let password = $('#brokerpassword').val(); + let queue = $('#brokerqueue').val(); + + if (ValidString(url) == false) { + alert("FARM Broker URL is required."); + return; + } + if (ValidString(username) == false) { + alert("FARM Broker Username is required."); + return; + } + if (ValidString(password) == false) { + alert("FARM Broker Password is required."); + return; + } + if (ValidString(queue) == false) { + alert("FARM Broker Queue is required."); + return; + } + + + Post("saveFARM", { + farm: { + url: url, + username: username, + password: password, + queue: queue + } + + }, function (data) { + alert(data.message); + }, function (error) { + alert(error); + }); + +} +function saveAASParameter() { + let aas1URL = $('#aas1url').val(); + let aas1username = $('#aas1username').val(); + let aas1password = $('#aas1password').val(); + let aas2URL = $('#aas2url').val(); + let aas2username = $('#aas2username').val(); + let aas2password = $('#aas2password').val(); + let aas3URL = $('#aas3url').val(); + let aas3username = $('#aas3username').val(); + let aas3password = $('#aas3password').val(); + + if (ValidString(aas1URL) == false) { + alert("AAS1 URL is required."); + return; + } + if (ValidString(aas1username) == false) { + alert("AAS1 Username is required."); + return; + } + if (ValidString(aas1password) == false) { + alert("AAS1 Password is required."); + return; + } + if (ValidString(aas2URL) == false) { + alert("AAS2 URL is required."); + return; + } + if (ValidString(aas2username) == false) { + alert("AAS2 Username is required."); + return; + } + if (ValidString(aas2password) == false) { + alert("AAS2 Password is required."); + return; + } + if (ValidString(aas3URL) == false) { + alert("AAS3 URL is required."); + return; + } + if (ValidString(aas3username) == false) { + alert("AAS3 Username is required."); + return; + } + if (ValidString(aas3password) == false) { + alert("AAS3 Password is required."); + return; + } + Post("saveAAS", { + aas1: { + url: aas1URL, + username: aas1username, + password: aas1password + }, + aas2: { + url: aas2URL, + username: aas2username, + password: aas2password + }, + aas3: { + url: aas3URL, + username: aas3username, + password: aas3password + } + }, function (data) { + alert(data.message); + }, function (error) { + alert(error) + }); +} \ No newline at end of file diff --git a/html/home.html b/html/home.html index fb9d987..8c5dc16 100644 --- a/html/home.html +++ b/html/home.html @@ -15,9 +15,9 @@ @@ -30,6 +30,8 @@
+ + \ No newline at end of file diff --git a/html/log.html b/html/log.html index 63d0945..5cfa056 100644 --- a/html/log.html +++ b/html/log.html @@ -14,10 +14,10 @@
Farm To AAS
@@ -45,6 +45,8 @@ + + \ No newline at end of file diff --git a/html/login.html b/html/login.html index 9d8fc45..ad7d26b 100644 --- a/html/login.html +++ b/html/login.html @@ -28,7 +28,6 @@
-

Forgot your password?

@@ -38,6 +37,8 @@ + + \ No newline at end of file diff --git a/html/setting.html b/html/setting.html index 355ffc7..141b245 100644 --- a/html/setting.html +++ b/html/setting.html @@ -14,10 +14,10 @@
Farm To AAS
@@ -49,25 +49,27 @@

AAS Setting

-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+ + \ No newline at end of file diff --git a/src/Main.kt b/src/Main.kt index 3131d01..8f09496 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -11,7 +11,7 @@ fun main() { val webUI = WebUI() webUI.Start() val activeclient = ActiveMQClient() - activeclient.Start() + //activeclient.Start() val mysql = MySQLInjector() mysql.Start() diff --git a/src/Web/WebUI.kt b/src/Web/WebUI.kt index 8f2eb78..2ad259a 100644 --- a/src/Web/WebUI.kt +++ b/src/Web/WebUI.kt @@ -2,6 +2,7 @@ package Web import config import io.javalin.Javalin +import io.javalin.apibuilder.ApiBuilder.before import io.javalin.apibuilder.ApiBuilder.get import io.javalin.apibuilder.ApiBuilder.path import io.javalin.apibuilder.ApiBuilder.post @@ -14,49 +15,99 @@ import org.tinylog.Logger */ class WebUI{ private var app : Javalin = Javalin.create { cfg -> - cfg.staticFiles.add("/html") + cfg.staticFiles.add("/") cfg.router.apiBuilder { path("/"){ get { if (config.WebUsername==it.cookie("username")){ + Logger.info{"${it.ip()} logged in as ${it.cookie("username")}, forward to home.html"} it.redirect("home.html") } else{ + Logger.info{"${it.ip()} have not logged in, forward to login.html"} it.redirect("login.html") } } } - path("login"){ + path("login.html"){ post{ val username = it.formParam("username") val password = it.formParam("password") if (config.WebUsername==username && config.WebPassword==password) { + Logger.info { "${it.ip()} login successful for user $username" } it.cookie("username", username) it.redirect("home.html") } else { + Logger.info { "${it.ip()} Login failed for user $username" } it.redirect("/login.html?error=1") } } } path("logout"){ get { + Logger.info{"${it.ip()} User ${it.cookie("username")} logged out"} it.removeCookie("username") it.redirect("login.html") } } - path("login.html"){ - get { - it.removeCookie("username") + + get("getSetting"){ + val fd = farmData(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password, config.ActiveMQ_QueueName) + val aas1 = aasData(config.MySQL_AAS1, config.MySQL_AAS1_Username, config.MySQL_AAS1_Password) + val aas2 = aasData(config.MySQL_AAS2, config.MySQL_AAS2_Username, config.MySQL_AAS2_Password) + val aas3 = aasData(config.MySQL_AAS3, config.MySQL_AAS3_Username, config.MySQL_AAS3_Password) + val setting = getSetting(fd, aas1, aas2, aas3) + it.json(setting) + } + post("saveFARM"){ + + try{ + val fd = it.bodyAsClass(saveFARM::class.java) + config.ActiveMQ_BrokerURL = fd.farm.url + config.ActiveMQ_Username = fd.farm.username + config.ActiveMQ_Password = fd.farm.password + config.ActiveMQ_QueueName = fd.farm.queue + config.Save() + it.json(webReply("success")) + } catch (e: Exception){ + val str = "Error saving FARM settings: ${e.message}" + Logger.error { str } + it.status(500).json(webReply(str)) } } - path("home.html"){ + post("saveAAS"){ - get { - if (config.WebUsername!=it.cookie("username")){ - it.redirect("login.html") - return@get - } + try { + val ax = it.bodyAsClass(saveAAS::class.java) + config.MySQL_AAS1 = ax.aas1.url + config.MySQL_AAS1_Username = ax.aas1.username + config.MySQL_AAS1_Password = ax.aas1.password + config.MySQL_AAS2 = ax.aas2.url + config.MySQL_AAS2_Username = ax.aas2.username + config.MySQL_AAS2_Password = ax.aas2.password + config.MySQL_AAS3 = ax.aas3.url + config.MySQL_AAS3_Username = ax.aas3.username + config.MySQL_AAS3_Password = ax.aas3.password + config.Save() + it.json(webReply("success")) + } catch (e: Exception){ + val str = "Error saving AAS settings: ${e.message}" + Logger.error { str } + it.status(500).json(webReply(str)) } + } + + path("home.html"){ + before{ + if (config.WebUsername!=it.cookie("username")){ + Logger.info {"${it.ip()} Have not logged in, forward to login.html"} + it.redirect("login.html") + return@before + } + } + + + ws("/ws"){ ws -> ws.onConnect { wsconnectcontext -> Logger.info { "WebSocket connected: ${wsconnectcontext.sessionId()}"; wsconnectcontext.enableAutomaticPings() } } ws.onClose { wsclosecontext -> Logger.info { "WebSocket closed: ${wsclosecontext.sessionId()}" } } @@ -68,27 +119,26 @@ class WebUI{ } path("log.html"){ - get { + before{ if (config.WebUsername!=it.cookie("username")){ + Logger.info{"${it.ip()} Have not logged in, forward to login.html"} it.redirect("login.html") - return@get + return@before } - val logdate = it.queryParam("logdate") - if (logdate.isNullOrEmpty()) return@get - } + + } path("setting.html"){ - get { + before{ if (config.WebUsername!=it.cookie("username")){ + Logger.info{"${it.ip()} Have not logged in, forward to login.html"} it.redirect("login.html") - return@get + return@before } - // TODO send config values in JSON format - } - post { - // TODO save config values from form parameters } + + } } diff --git a/src/Web/aasData.kt b/src/Web/aasData.kt new file mode 100644 index 0000000..df92651 --- /dev/null +++ b/src/Web/aasData.kt @@ -0,0 +1,3 @@ +package Web + +data class aasData(val url: String, val username: String, val password: String) diff --git a/src/Web/farmData.kt b/src/Web/farmData.kt new file mode 100644 index 0000000..8e34540 --- /dev/null +++ b/src/Web/farmData.kt @@ -0,0 +1,3 @@ +package Web + +data class farmData(val url: String, val username: String, val password: String, val queue: String) diff --git a/src/Web/getSetting.kt b/src/Web/getSetting.kt new file mode 100644 index 0000000..606dbd5 --- /dev/null +++ b/src/Web/getSetting.kt @@ -0,0 +1,3 @@ +package Web + +data class getSetting(val farm: farmData, val aas1: aasData, val aas2: aasData, val aas3: aasData) diff --git a/src/Web/saveAAS.kt b/src/Web/saveAAS.kt new file mode 100644 index 0000000..c506a98 --- /dev/null +++ b/src/Web/saveAAS.kt @@ -0,0 +1,3 @@ +package Web + +data class saveAAS(val aas1: aasData, val aas2: aasData, val aas3: aasData) diff --git a/src/Web/saveFARM.kt b/src/Web/saveFARM.kt new file mode 100644 index 0000000..89b83d9 --- /dev/null +++ b/src/Web/saveFARM.kt @@ -0,0 +1,3 @@ +package Web + +data class saveFARM(val farm: farmData) diff --git a/src/Web/webReply.kt b/src/Web/webReply.kt new file mode 100644 index 0000000..8c941e3 --- /dev/null +++ b/src/Web/webReply.kt @@ -0,0 +1,4 @@ +package Web + +class webReply(val message: String) { +} \ No newline at end of file