diff --git a/.idea/libraries/mysql_connector_j.xml b/.idea/libraries/mysql_connector_j.xml new file mode 100644 index 0000000..890b81e --- /dev/null +++ b/.idea/libraries/mysql_connector_j.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/AAS_NewGen.iml b/AAS_NewGen.iml index 9040d70..ea0fd29 100644 --- a/AAS_NewGen.iml +++ b/AAS_NewGen.iml @@ -16,7 +16,6 @@ - @@ -35,5 +34,6 @@ + \ No newline at end of file diff --git a/html/webpage/assets/js/script.js b/html/webpage/assets/js/script.js index bd53ee3..38c84ec 100644 --- a/html/webpage/assets/js/script.js +++ b/html/webpage/assets/js/script.js @@ -212,7 +212,7 @@ function fill_messagebanktablebody(vv) { }); }); - console.log("loaded " + vv.length + " messagebank items"); + $('#tablesize').text("Table Size: " + vv.length); } /** @@ -246,7 +246,7 @@ function fill_languagebanktablebody(vv) { $('#btnEdit').prop('disabled', false); }); }); - console.log("loaded " + vv.length + " languagebank items"); + $('#tablesize').text("Table Size: " + vv.length); } /** @@ -286,7 +286,7 @@ function fill_schedulebanktablebody(vv) { $('#btnEdit').prop('disabled', false); }); }); - console.log("loaded " + vv.length + " schedulebank items"); + $('#tablesize').text("Table Size: " + vv.length); } /** @@ -306,7 +306,7 @@ function fill_logtablebody(vv) { `; $('#logtablebody').append(row); }); - console.log("loaded " + vv.length + " log items"); + $('#tablesize').text("Table Size: " + vv.length); } /** @@ -349,21 +349,21 @@ function fetchAPI(endpoint, method, headers = {}, body = null, cbOK, cbError) { options.headers['Content-Type'] = 'application/json'; } } - console.log("About to fetch from " + url + " with options", options); + //console.log("About to fetch from " + url + " with options", options); fetch(url, options) .then(response => { - console.log("fetchAPI: received response", response); + //console.log("fetchAPI: received response", response); if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } return response.json(); }) - .then(data => { - console.log("fetchAPI: received data", data); + .then(data => { + //console.log("fetchAPI: received data", data); cbOK(data); }) .catch(error => { - console.error('There was a problem with the fetch operation:', error); + // console.error('There was a problem with the fetch operation:', error); cbError(error); }); } @@ -374,9 +374,7 @@ function fetchAPI(endpoint, method, headers = {}, body = null, cbOK, cbError) { */ function reloadSoundBank(APIURL) { soundbankdata = []; - console.log("reloadSoundBank: fetching from " + APIURL + "List"); fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => { - console.log("reloadSoundBank: received data", okdata); if (Array.isArray(okdata)) { soundbankdata = okdata; selectedsoundrow = null; @@ -441,12 +439,17 @@ function reloadTimerBank(APIURL) { /** * Reload logs from server with date and filter * @param {String} APIURL API URL endpoint - * @param {String} date date in format dd/MM/yyyy + * @param {String} date date in format dd-mm-yyyy * @param {String} filter log filter text */ function reloadLogs(APIURL, date, filter) { - fetchAPI(APIURL + "List/" + date + "/" + filter, "GET", {}, null, (okdata) => { - $('#logcontent').val(okdata.data); + const params = new URLSearchParams({ + date: date, + filter: filter + }) + fetchAPI(APIURL + "List?" + params.toString(), "GET", {}, null, (okdata) => { + //console.log("Logs data received", okdata); + fill_logtablebody(okdata); }, (errdata) => { alert("Error loading logs: " + errdata.message); }); @@ -536,6 +539,24 @@ function getScheduledDays() { }); } +/** + * Clear database mechanism + * @param {String} APIURL API URL endpoint + * @param {String} whattoclear what to clear + * @param {Function} cbOK callback function on success + * @param {Function} cbError callback function on error + */ +function DoClear(APIURL, whattoclear, cbOK, cbError) { + if (confirm(`Are you sure want to clear ${whattoclear} ? This procedure is not reversible`)) { + fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => { + cbOK(okdata); + }, (errdata) => { + cbError(errdata); + }); + } +} + + /** * Export mechanism to XLSX file * @param {String} APIURL API URL endpoint @@ -550,27 +571,25 @@ function DoExport(APIURL, filename) { method: "GET", headers: {} }) - .then(response => { - if (!response.ok) throw new Error('Network response was not ok ' + response.statusText); - return response.blob(); - }) - .then(blob => { - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - }) - .catch(error => { - alert("Error export to " + filename + ": " + error.message); - }); + .then(response => { + if (!response.ok) throw new Error('Network response was not ok ' + response.statusText); + return response.blob(); + }) + .then(blob => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }) + .catch(error => { + alert("Error export to " + filename + ": " + error.message); + }); return; // prevent the rest of the function from running - - } /** @@ -704,17 +723,26 @@ $(document).ready(function () { reloadSoundBank(APIURL); + $('#findsoundbank').on('input', function () { + let searchTerm = $(this).val().trim().toLowerCase(); + if (searchTerm.length>0){ + let filtered = soundbankdata.filter(item => item.description.toLowerCase().includes(searchTerm) || item.tag.toLowerCase().includes(searchTerm) || item.path.toLowerCase().includes(searchTerm)); + fill_soundbanktablebody(filtered); + } else { + selectedsoundrow = null; + fill_soundbanktablebody(soundbankdata); + } + }); $btnClear.click(() => { - if (confirm(`Are you sure want to clear Soundbank ? This procedure is not reversible`)) { - fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => { - alert("Success clear soundbank" + okdata.message); + DoClear(APIURL, "Soundbank", (okdata) => { + alert("Success clear soundbank" + okdata.message); soundbankdata = [] selectedsoundrow = null; fill_soundbanktablebody(soundbankdata); - }, (errdata) => { - alert("Error clear soundbank: " + errdata.message); - }); - } + }, (errdata) => { + alert("Error clear soundbank: " + errdata.message); + }); + }); $btnAdd.click(() => { $('.js-example-basic-single').select2({ @@ -817,16 +845,15 @@ $(document).ready(function () { reloadMessageBank(APIURL); $btnClear.click(() => { - if (confirm(`Are you sure want to clear Messagebank ? This procedure is not reversible`)) { - fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => { - alert("Success clear messagebank" + okdata.message); - messagebankdata = [] - selectedmessagerow = null; - fill_messagebanktablebody(messagebankdata); - }, (errdata) => { - alert("Error clear messagebank: " + errdata.message); - }); - } + DoClear(APIURL, "Messagebank", (okdata) => { + alert("Success clear messagebank" + okdata.message); + messagebankdata = [] + selectedmessagerow = null; + fill_messagebanktablebody(messagebankdata); + }, (errdata) => { + alert("Error clear messagebank: " + errdata.message); + }); + }); $btnAdd.click(() => { let $modal = $('#messagebankmodal'); @@ -921,22 +948,21 @@ $(document).ready(function () { let $btnImport = $('#btnImport'); $btnRemove.prop('disabled', true); $btnEdit.prop('disabled', true); - let APIURL = "LanguageBank/"; + let APIURL = "LanguageLink/"; reloadLanguageBank(APIURL); $btnClear.click(() => { - if (confirm(`Are you sure want to clear Languagebank ? This procedure is not reversible`)) { - fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => { - alert("Success clear languagebank" + okdata.message); - languagebankdata = [] - selectedlanguagerow = null; - fill_languagebanktablebody(languagebankdata); - }, (errdata) => { - alert("Error clear languagebank: " + errdata.message); - }); - } + DoClear(APIURL, "LanguageLink", (okdata) => { + alert("Success clear languageLink" + okdata.message); + languagebankdata = [] + selectedlanguagerow = null; + fill_languagebanktablebody(languagebankdata); + }, (errdata) => { + alert("Error clear languagebank: " + errdata.message); + }); + }); $btnAdd.click(() => { // show modal with id 'languagemodal' @@ -1107,16 +1133,15 @@ $(document).ready(function () { reloadTimerBank(APIURL); $btnClear.click(() => { - if (confirm(`Are you sure want to clear Timerbank ? This procedure is not reversible`)) { - fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => { - alert("Success clear schedulebank" + okdata.message); - schedulebankdata = [] - selectedschedulerow = null; - fill_schedulebanktablebody(schedulebankdata); - }, (errdata) => { - alert("Error clear schedulebank: " + errdata.message); - }); - } + DoClear(APIURL, "Timerbank", (okdata) => { + alert("Success clear schedulebank" + okdata.message); + schedulebankdata = [] + selectedschedulerow = null; + fill_schedulebanktablebody(schedulebankdata); + }, (errdata) => { + alert("Error clear schedulebank: " + errdata.message); + }); + }); $btnAdd.click(() => { //TODO form add timer @@ -1190,9 +1215,11 @@ $(document).ready(function () { console.log("Log content loaded successfully"); const $logdate = $('#logdate'); const $searchfilter = $('#searchfilter'); + const $logtable = $('#logtablebody') let selectedlogdate = ""; let logfilter = ""; - let APIURL = "/api/Logs/"; + let APIURL = "Log/"; + $logtable.empty(); if (!$logdate.val()) { @@ -1201,13 +1228,14 @@ $(document).ready(function () { const mm = String(today.getMonth() + 1).padStart(2, '0'); const yyyy = today.getFullYear(); $logdate.val(`${yyyy}-${mm}-${dd}`); - selectedlogdate = `${dd}/${mm}/${yyyy}`; + selectedlogdate = `${dd}-${mm}-${yyyy}`; + reloadLogs(APIURL, selectedlogdate, logfilter); } $logdate.off('change').on('change', function () { const selected = $(this).val(); if (selected) { const [year, month, day] = selected.split('-'); - selectedlogdate = `${day}/${month}/${year}`; + selectedlogdate = `${day}-${month}-${year}`; reloadLogs(APIURL, selectedlogdate, logfilter); } }); diff --git a/html/webpage/language.html b/html/webpage/language.html index e313dd3..682cac1 100644 --- a/html/webpage/language.html +++ b/html/webpage/language.html @@ -24,40 +24,22 @@
+
+
+

Table Length : N/A

+
+
- - - - - - + + - - - - - - - - - - - - - - - - - - - - +
NoDescriptionTAGCategoryLanguageTypeFilenameTAGLanguages
Cell 1Cell 2Cell 3Cell 3Cell 5Cell 6Cell 7
Cell 3Cell 4Cell 3Cell 3Cell 5Cell 6Cell 7
diff --git a/html/webpage/log.html b/html/webpage/log.html index 4d1c641..2021f4f 100644 --- a/html/webpage/log.html +++ b/html/webpage/log.html @@ -27,6 +27,11 @@
+
+
+

Table Length : N/A

+
+
@@ -35,23 +40,11 @@ + - - - - - - - - - - - - - - +
No Date TimeMachine Description
Cell 1Cell 2Cell 3Cell 4
Cell 3Cell 4Cell 3Cell 4
diff --git a/html/webpage/messagebank.html b/html/webpage/messagebank.html index 80b7c50..c48fd9c 100644 --- a/html/webpage/messagebank.html +++ b/html/webpage/messagebank.html @@ -24,6 +24,11 @@
+
+
+

Table Length : N/A

+
+
@@ -38,26 +43,7 @@ - - - - - - - - - - - - - - - - - - - - +
Message Tags
Cell 1Cell 2Cell 3Cell 3Cell 5Cell 6Cell 7
Cell 3Cell 4Cell 3Cell 3Cell 5Cell 6Cell 7
diff --git a/html/webpage/soundbank.html b/html/webpage/soundbank.html index 0ee3d91..4223a34 100644 --- a/html/webpage/soundbank.html +++ b/html/webpage/soundbank.html @@ -50,26 +50,7 @@ Filename - - - Cell 1 - Cell 2 - Cell 3 - Cell 3 - Cell 5 - Cell 6 - Cell 7 - - - Cell 3 - Cell 4 - Cell 3 - Cell 3 - Cell 5 - Cell 6 - Cell 7 - - + diff --git a/html/webpage/timer.html b/html/webpage/timer.html index 9b56f88..f86cd3b 100644 --- a/html/webpage/timer.html +++ b/html/webpage/timer.html @@ -13,7 +13,7 @@
-

Timer

+

Schedule Bank

@@ -24,40 +24,27 @@
+
+
+

Table Length : N/A

+
+
- - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - +
NoDescriptionTAGCategoryLanguageTypeFilenameDescriptionDayTimeSound PathRepeatEnableBroadcast Zones
Cell 1Cell 2Cell 3Cell 3Cell 5Cell 6Cell 7
Cell 3Cell 4Cell 3Cell 3Cell 5Cell 6Cell 7
diff --git a/src/Main.kt b/src/Main.kt index 3725bb1..dd7698e 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -32,14 +32,14 @@ fun main() { CoroutineScope(Dispatchers.Default).launch { while (isActive) { delay(1000) - val broadcastzones = db.GetBroadcastZones() + // baca dulu queue paging, prioritas 1 db.Read_Queue_Paging().forEach { // cek apakah queue paging ada broadcast zone nya if (it.BroadcastZones.isNotBlank()) { val zz = it.BroadcastZones.split(";") // cek apakah semua target broadcast zone dari queue paging ada di dalam database broadcast zones - if (zz.all { z -> broadcastzones.any { bz -> bz.equals(z) } }) { + if (zz.all { z -> db.BroadcastZoneList.any { bz -> bz.equals(z) } }) { // semua target broadcast zone valid, sekarang cek apakah semua target broadcast zone idle } else { @@ -59,7 +59,7 @@ fun main() { if (it.BroadcastZones.isNotBlank()) { val zz = it.BroadcastZones.split(";") // cek apakah semua target broadcast zone dari queue table ada di dalam database broadcast zones - if (zz.all { z -> broadcastzones.any { bz -> bz.equals(z) } }) { + if (zz.all { z -> db.BroadcastZoneList.any { bz -> bz.equals(z) } }) { // semua target broadcast zone valid, sekarang cek apakah semua target broadcast zone idle } else { diff --git a/src/codes/Somecodes.kt b/src/codes/Somecodes.kt index 26a5746..3cd8959 100644 --- a/src/codes/Somecodes.kt +++ b/src/codes/Somecodes.kt @@ -24,6 +24,7 @@ class Somecodes { val memory : GlobalMemory = si.hardware.memory val datetimeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss") val dateformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy") + val dateformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy") val timeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss") val timeformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm") const val KB_threshold = 1024.0 @@ -180,6 +181,24 @@ class Somecodes { } } + /** + * Check if a string is a valid date in the format "dd-MM-yyyy". + * This format is used for log HTML files. + * @param value The string to check. + * @return True if the string is a valid date, false otherwise. + */ + fun ValiDateForLogHtml(value: String): Boolean{ + return try{ + if (ValidString(value)){ + dateformat2.parse(value) + true + } else throw Exception() + + } catch (_: Exception){ + false + } + } + /** * Check if a string is a valid time in the format "hh:mm:ss". * @param value The string to check. diff --git a/src/database/MariaDB.kt b/src/database/MariaDB.kt index 217ce77..6f0e2e4 100644 --- a/src/database/MariaDB.kt +++ b/src/database/MariaDB.kt @@ -1,12 +1,13 @@ package database +import codes.Somecodes.Companion.ValiDateForLogHtml import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.apache.poi.xssf.usermodel.XSSFWorkbook -import org.mariadb.jdbc.Connection import org.tinylog.Logger +import java.sql.Connection import java.sql.DriverManager import java.util.function.Consumer @@ -33,6 +34,7 @@ class MariaDB( var MessagebankList: ArrayList = ArrayList() var LanguageLinkList: ArrayList = ArrayList() var SchedulebankList: ArrayList = ArrayList() + var BroadcastZoneList: ArrayList = ArrayList() companion object { fun ValidDate(date: String): Boolean { @@ -56,7 +58,7 @@ class MariaDB( */ fun ArrayListtoString(list: ArrayList): String { return try { - objectMapper.writeValueAsString(list.toArray()) + objectMapper.writeValueAsString(list) } catch (e: Exception) { Logger.error("Error converting list to JSON: ${e.message}" as Any) "[]" @@ -68,7 +70,7 @@ class MariaDB( init { try { connection = - DriverManager.getConnection("jdbc:mariadb://$address:$port/$dbName", username, password) as Connection + DriverManager.getConnection("jdbc:mysql://$address:$port/$dbName?sslMode=REQUIRED", username, password) as Connection Logger.info("Connected to MariaDB" as Any) connected = true @@ -78,6 +80,7 @@ class MariaDB( Reload_Soundbank() Reload_LanguageLink() Reload_Schedulebank() + GetBroadcastZones() } } @@ -88,6 +91,7 @@ class MariaDB( Logger.info { "Messagebank count: ${MessagebankList.size}" } Logger.info { "LanguageLink count: ${LanguageLinkList.size}" } Logger.info { "Schedulebank count: ${SchedulebankList.size}" } + Logger.info { "BroadcastZones count: ${BroadcastZoneList.size}" } } catch (e: Exception) { @@ -195,7 +199,7 @@ class MariaDB( val logList = ArrayList() try { val statement = connection?.createStatement() - val resultSet = statement?.executeQuery("SELECT * FROM log") + val resultSet = statement?.executeQuery("SELECT * FROM logs") while (resultSet?.next() == true) { val log = Log( resultSet.getLong("index").toULong(), @@ -213,16 +217,18 @@ class MariaDB( } /** - * Get Log from database by date - * @param date The date to filter logs by (format: DD/MM/YYYY) + * Get Log from database by date for HTML usage + * @param date The date to filter logs by (format: DD-MM-YYYY) * @param consumer A Consumer that will receive the list of logs for the specified date */ - fun GetLog(date: String, consumer: Consumer>) { + fun GetLogForHtml(date: String, consumer: Consumer>) { val logList = ArrayList() - if (ValidDate(date)) { + if (ValiDateForLogHtml(date)) { try { - val statement = connection?.prepareStatement("SELECT * FROM log WHERE datenya = ?") - statement?.setString(1, date) + // must convert from DD-MM-YYYY to DD/MM/YYYY, because in database we use DD/MM/YYYY + val adjusteddate = date.replace("-", "/") + val statement = connection?.prepareStatement("SELECT * FROM logs WHERE datenya = ?") + statement?.setString(1, adjusteddate) val resultSet = statement?.executeQuery() while (resultSet?.next() == true) { val log = Log( @@ -242,13 +248,21 @@ class MariaDB( consumer.accept(logList) } - fun GetLog(date: String, filter: String, consumer: Consumer>) { + /** + * Get Log from database by date and filter for HTML usage + * @param date The date to filter logs by (format: DD-MM-YYYY) + * @param filter The filter string to search in description or machine + * @param consumer A Consumer that will receive the list of logs for the specified date and filter + */ + fun GetLogForHtml(date: String, filter: String, consumer: Consumer>) { val logList = ArrayList() - if (ValidDate(date)) { + if (ValiDateForLogHtml(date)) { try { + // must convert from DD-MM-YYYY to DD/MM/YYYY, because in database we use DD/MM/YYYY + val adjusteddate = date.replace("-", "/") val statement = - connection?.prepareStatement("SELECT * FROM log WHERE datenya = ? AND description LIKE ?") - statement?.setString(1, date) + connection?.prepareStatement("SELECT * FROM logs WHERE datenya = ? AND description LIKE ?") + statement?.setString(1, adjusteddate) statement?.setString(2, "%$filter%") val resultSet = statement?.executeQuery() while (resultSet?.next() == true) { @@ -559,7 +573,7 @@ class MariaDB( LanguageLinkList.clear() try { val statement = connection?.createStatement() - val resultSet = statement?.executeQuery("SELECT * FROM languagelink") + val resultSet = statement?.executeQuery("SELECT * FROM languagelinking") while (resultSet?.next() == true) { val languageLink = LanguageLink( resultSet.getLong("index").toUInt(), @@ -1378,11 +1392,11 @@ class MariaDB( * Get All Broadcast Zones from database * @return A list of BroadcastZones entries. */ - fun GetBroadcastZones(): List { - val zonesList = ArrayList() + fun GetBroadcastZones(){ + BroadcastZoneList.clear() try { val statement = connection?.createStatement() - val resultSet = statement?.executeQuery("SELECT * FROM broadcast_zones") + val resultSet = statement?.executeQuery("SELECT * FROM broadcastzones") while (resultSet?.next() == true) { val zone = BroadcastZones( resultSet.getLong("index").toUInt(), @@ -1391,12 +1405,11 @@ class MariaDB( resultSet.getString("Box"), resultSet.getString("Relay") ) - zonesList.add(zone) + BroadcastZoneList.add(zone) } } catch (e: Exception) { Logger.error("Error fetching broadcast zones: ${e.message}" as Any) } - return zonesList } /** diff --git a/src/web/WebApp.kt b/src/web/WebApp.kt index bb52447..e7afad7 100644 --- a/src/web/WebApp.kt +++ b/src/web/WebApp.kt @@ -2,6 +2,7 @@ package web import codes.Somecodes import codes.Somecodes.Companion.ListAudioFiles +import codes.Somecodes.Companion.ValiDateForLogHtml import codes.Somecodes.Companion.ValidDate import codes.Somecodes.Companion.ValidFile import codes.Somecodes.Companion.ValidScheduleDay @@ -123,11 +124,11 @@ class WebApp(val listenPort: Int, val userlist: List>, val } "getPagingQueue" ->{ - SendReply(wsMessageContext, cmd.command, MariaDB.ArrayListtoString(db.Read_Queue_Paging())) + SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(db.Read_Queue_Paging())) } "getAASQueue" ->{ - SendReply(wsMessageContext, cmd.command, MariaDB.ArrayListtoString(db.Read_Queue_Table())) + SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(db.Read_Queue_Table())) } else -> { @@ -187,7 +188,6 @@ class WebApp(val listenPort: Int, val userlist: List>, val } path("SoundBank") { get("List") { - // get soundbank list it.result(MariaDB.ArrayListtoString(db.SoundbankList)) } get("ListFiles"){ @@ -719,21 +719,24 @@ class WebApp(val listenPort: Int, val userlist: List>, val } } path("Log") { - get("List//") { get1 -> - val logdate = get1.pathParam("logdate") - val logfilter = get1.pathParam("logfilter") - if (ValidDate(logdate)) { + get("List") { get1 -> + val logdate = get1.queryParam("date") ?: "" + val logfilter = get1.queryParam("filter") ?: "" + if (ValiDateForLogHtml(logdate)) { if (ValidString(logfilter)) { // ada log filter - db.GetLog(logdate, logfilter) { + db.GetLogForHtml(logdate, logfilter) { get1.result(MariaDB.ArrayListtoString(it)) } } else { - db.GetLog(logdate) { + db.GetLogForHtml(logdate) { get1.result(MariaDB.ArrayListtoString(it)) } } - } else get1.status(400).result("Invalid logdate") + } else { + println("Invalid logdate=$logdate") + get1.status(400).result("Invalid logdate") + } } get("ExportXLSX//") { get1 -> val logdate = get1.pathParam("logdate")