commit 23/01/2026

This commit is contained in:
2026-01-23 17:43:42 +07:00
parent 36d39c5c47
commit f7d05b5d82
9 changed files with 702 additions and 74 deletions

View File

@@ -21,6 +21,7 @@
<option name="processLiterals" value="true" /> <option name="processLiterals" value="true" />
<option name="processComments" value="true" /> <option name="processComments" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TestFunctionName" enabled="false" level="WEAK WARNING" enabled_by_default="false" /> <inspection_tool class="TestFunctionName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile> </profile>
</component> </component>

View File

@@ -16,10 +16,10 @@ import java.util.function.Consumer
@Suppress("unused") @Suppress("unused")
class ActiveMQClient { class ActiveMQClient {
private lateinit var connection: Connection private var connection: Connection? = null
private lateinit var session: Session private var session: Session? = null
private lateinit var destination : Queue private var destination : Queue? = null
private lateinit var consumer: MessageConsumer private var consumer: MessageConsumer? = null
var MessageConsumer : Consumer<Message>?= null var MessageConsumer : Consumer<Message>?= null
/** /**
@@ -28,11 +28,11 @@ class ActiveMQClient {
fun Start(){ fun Start(){
try{ try{
connection = ActiveMQConnectionFactory(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password).createConnection() connection = ActiveMQConnectionFactory(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password).createConnection()
connection.start() connection?.start()
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE) session = connection?.createSession(false, Session.AUTO_ACKNOWLEDGE)
destination = session.createQueue(config.ActiveMQ_QueueName) destination = session?.createQueue(config.ActiveMQ_QueueName)
consumer = session.createConsumer(destination) consumer = session?.createConsumer(destination)
consumer.messageListener = MessageListener { message -> consumer?.messageListener = MessageListener { message ->
MessageConsumer?.accept(message) MessageConsumer?.accept(message)
when (message) { when (message) {
is TextMessage -> Logger.info { "Received Text Message : ${message.text}" } is TextMessage -> Logger.info { "Received Text Message : ${message.text}" }
@@ -69,9 +69,12 @@ class ActiveMQClient {
*/ */
fun Stop(){ fun Stop(){
try{ try{
consumer.close() if (consumer==null) throw Exception("Consumer is null")
session.close() if (session==null) throw Exception("Session is null")
connection.close() if (connection==null) throw Exception("Connection is null")
consumer?.close()
session?.close()
connection?.close()
Logger.info { "Connection closed to Broker" } Logger.info { "Connection closed to Broker" }
} catch (e : Exception){ } catch (e : Exception){
Logger.error { "Failed to close connection, Message : ${e.message}" } Logger.error { "Failed to close connection, Message : ${e.message}" }

View File

@@ -2,19 +2,69 @@ import ActiveMQ.ActiveMQClient
import Other.Config import Other.Config
import Web.WebUI import Web.WebUI
import database.MySQLAdapter import database.MySQLAdapter
import org.tinylog.Logger
import org.tinylog.provider.ProviderRegistry import org.tinylog.provider.ProviderRegistry
import java.util.function.Consumer import java.util.function.Consumer
lateinit var config : Config lateinit var config : Config
var aas1 : MySQLAdapter? = null
var aas2 : MySQLAdapter? = null
var aas3 : MySQLAdapter? = null
fun main() { fun main() {
config = Config() config = Config()
config.Load() config.Load()
val webUI = WebUI() val webUI = WebUI()
webUI.Start() webUI.Start()
val activeclient = ActiveMQClient() val activeclient = ActiveMQClient()
//activeclient.Start() activeclient.Start()
val mysql = MySQLAdapter()
mysql.Start() aas1 = MySQLAdapter(1)
aas1!!.VerifyConnection { success ->
if (success) {
Logger.info {"Database 1 connection verified."}
aas1!!.CreateFlightFilterTable { success ->
if (success) {
Logger.info {"Flight Filter Table ensured in Database 1."}
} else {
Logger.error {"Failed to ensure Flight Filter Table in Database 1."}
}
}
} else {
Logger.error {"Failed to verify Database 1 connection." }
}
}
aas2 = MySQLAdapter(2)
aas2!!.VerifyConnection { success ->
if (success) {
Logger.info { "Database 2 connection verified." }
aas2!!.CreateFlightFilterTable { success ->
if (success) {
Logger.info { "Flight Filter Table ensured in Database 2." }
} else {
Logger.error { "Failed to ensure Flight Filter Table in Database 2." }
}
}
} else {
Logger.error { "Failed to verify Database 2 connection." }
}
}
aas3 = MySQLAdapter(3)
aas3!!.VerifyConnection { success ->
if (success) {
Logger.info {"Database 3 connection verified."}
aas3!!.CreateFlightFilterTable { success ->
if (success) {
Logger.info { "Flight Filter Table ensured in Database 3." }
} else {
Logger.error { "Failed to ensure Flight Filter Table in Database 3." }
}
}
} else {
Logger.error { "Failed to verify Database 3 connection." }
}
}
activeclient.MessageConsumer = Consumer{ message -> activeclient.MessageConsumer = Consumer{ message ->
@@ -23,8 +73,7 @@ fun main() {
Runtime.getRuntime().addShutdownHook(Thread { Runtime.getRuntime().addShutdownHook(Thread {
webUI.Stop() webUI.Stop()
activeclient.Stop() activeclient.Stop()
mysql.Stop()
// shutdown tinylog properly // shutdown tinylog properly
ProviderRegistry.getLoggingProvider().shutdown(); ProviderRegistry.getLoggingProvider().shutdown()
}) })
} }

View File

@@ -1,7 +1,13 @@
package Web package Web
import Log.LogGetter import Log.LogGetter
import aas1
import aas2
import aas3
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import config import config
import database.FlightFilter
import io.javalin.Javalin import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.before import io.javalin.apibuilder.ApiBuilder.before
import io.javalin.apibuilder.ApiBuilder.get import io.javalin.apibuilder.ApiBuilder.get
@@ -12,26 +18,26 @@ import org.tinylog.Logger
/** /**
* Start WebUI Server * Start WebUI Server
*/ */
class WebUI{ class WebUI {
// regex untuk date dengan format YYYY-MM-DD // regex untuk date dengan format YYYY-MM-DD
private val dateRegex1 = """\d{4}-\d{2}-\d{2}""".toRegex() private val dateRegex1 = """\d{4}-\d{2}-\d{2}""".toRegex()
private val mapper = ObjectMapper().registerKotlinModule()
private var app : Javalin = Javalin.create { cfg -> private var app: Javalin = Javalin.create { cfg ->
cfg.staticFiles.add("/") cfg.staticFiles.add("/")
cfg.router.apiBuilder { cfg.router.apiBuilder {
get("/"){ get("/") {
if (config.WebUsername==it.cookie("username")){ if (config.WebUsername == it.cookie("username")) {
Logger.info{"${it.ip()} logged in as ${it.cookie("username")}, forward to home.html"} Logger.info { "${it.ip()} logged in as ${it.cookie("username")}, forward to home.html" }
it.redirect("home.html") it.redirect("home.html")
} else{ } else {
Logger.info{"${it.ip()} have not logged in, forward to login.html"} Logger.info { "${it.ip()} have not logged in, forward to login.html" }
it.redirect("login.html") it.redirect("login.html")
} }
} }
post("login.html"){ post("login.html") {
val username = it.formParam("username") val username = it.formParam("username")
val password = it.formParam("password") val password = it.formParam("password")
if (config.WebUsername==username && config.WebPassword==password) { if (config.WebUsername == username && config.WebPassword == password) {
Logger.info { "${it.ip()} login successful for user $username" } Logger.info { "${it.ip()} login successful for user $username" }
it.cookie("username", username) it.cookie("username", username)
it.redirect("home.html") it.redirect("home.html")
@@ -41,55 +47,60 @@ class WebUI{
} }
} }
get("getLogs"){ get("getLogs") {
var date = it.queryParam("date") var date = it.queryParam("date")
Logger.info{"${it.ip()} User ${it.cookie("username")} requested logs for date: $date"} Logger.info { "${it.ip()} User ${it.cookie("username")} requested logs for date: $date" }
if (date!=null){ if (date != null) {
if (date.isNotEmpty()){ if (date.isNotEmpty()) {
if (dateRegex1.matches(date)){ if (dateRegex1.matches(date)) {
// ketemu format YYYY-MM-DD, convert format ke dd/MM/yyyy // ketemu format YYYY-MM-DD, convert format ke dd/MM/yyyy
val parts = date.split("-") val parts = date.split("-")
date = "${parts[2]}/${parts[1]}/${parts[0]}" date = "${parts[2]}/${parts[1]}/${parts[0]}"
} }
val logs = LogGetter().getLog(date) val logs = LogGetter().getLog(date)
if (logs.isNotEmpty()){ if (logs.isNotEmpty()) {
it.json(logs) it.json(logs)
} else it.status(404).json(webReply("No logs found for the specified date")) } else it.status(404).json(webReply(message = "No logs found for the specified date"))
} else it.status(400).json(webReply("Date parameter is empty")) } else it.status(400).json(webReply(message = "Date parameter is empty"))
} else it.status(400).json(webReply("Please provide a date")) } else it.status(400).json(webReply(message = "Please provide a date"))
} }
get("logout"){ get("logout") {
Logger.info{"${it.ip()} User ${it.cookie("username")} logged out"} Logger.info { "${it.ip()} User ${it.cookie("username")} logged out" }
it.removeCookie("username") it.removeCookie("username")
it.redirect("login.html") it.redirect("login.html")
} }
get("getSetting"){ get("getSetting") {
val fd = farmData(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password, config.ActiveMQ_QueueName) 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 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 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 aas3 = aasData(config.MySQL_AAS3, config.MySQL_AAS3_Username, config.MySQL_AAS3_Password)
val setting = getSetting(fd, aas1, aas2, aas3) val setting = getSetting(fd, aas1, aas2, aas3)
it.json(setting) it.json(setting)
} }
post("saveFARM"){ post("saveFARM") {
try{ try {
val fd = it.bodyAsClass(saveFARM::class.java) val fd = it.bodyAsClass(saveFARM::class.java)
config.ActiveMQ_BrokerURL = fd.farm.url config.ActiveMQ_BrokerURL = fd.farm.url
config.ActiveMQ_Username = fd.farm.username config.ActiveMQ_Username = fd.farm.username
config.ActiveMQ_Password = fd.farm.password config.ActiveMQ_Password = fd.farm.password
config.ActiveMQ_QueueName = fd.farm.queue config.ActiveMQ_QueueName = fd.farm.queue
config.Save() config.Save()
it.json(webReply("success")) it.json(webReply(message = "success"))
} catch (e: Exception){ } catch (e: Exception) {
val str = "Error saving FARM settings: ${e.message}" val str = "Error saving FARM settings: ${e.message}"
Logger.error { str } Logger.error { str }
it.status(500).json(webReply(str)) it.status(500).json(webReply(message = str))
} }
} }
post("saveAAS"){ post("saveAAS") {
try { try {
val ax = it.bodyAsClass(saveAAS::class.java) val ax = it.bodyAsClass(saveAAS::class.java)
@@ -103,34 +114,138 @@ class WebUI{
config.MySQL_AAS3_Username = ax.aas3.username config.MySQL_AAS3_Username = ax.aas3.username
config.MySQL_AAS3_Password = ax.aas3.password config.MySQL_AAS3_Password = ax.aas3.password
config.Save() config.Save()
it.json(webReply("success")) it.json(webReply(message = "success"))
} catch (e: Exception){ } catch (e: Exception) {
val str = "Error saving AAS settings: ${e.message}" val str = "Error saving AAS settings: ${e.message}"
Logger.error { str } Logger.error { str }
it.status(500).json(webReply(str)) it.status(500).json(webReply(message = str))
} }
} }
before("home.html"){ get("getBroadcastZones") {
if (config.WebUsername!=it.cookie("username")){ val id = it.queryParam("id")?.toIntOrNull() ?: 0
Logger.info {"${it.ip()} Have not logged in, forward to login.html"} val aas = when (id) {
it.redirect("login.html") 1 -> aas1
return@before 2 -> aas2
3 -> aas3
else -> null
}
if (aas != null) {
aas.GetBroadcastZones { success, zones ->
if (success) {
it.json(zones)
} else {
it.status(500).json(webReply(message = "Failed to retrieve broadcast zones"))
}
}
} else it.status(400).json(webReply(message = "Invalid AAS id"))
}
get("getAirlineCodes") {
val id = it.queryParam("id")?.toIntOrNull() ?: 0
val aas = when (id) {
1 -> aas1
2 -> aas2
3 -> aas3
else -> null
}
if (aas != null) {
aas.GetAirlineCode { success, codes ->
if (success) {
it.json(codes)
} else {
it.status(500).json(webReply(message = "Failed to retrieve airline codes"))
}
}
} else it.status(400).json(webReply(message = "Invalid AAS id"))
}
post("FlightFilter") {
try {
val req = it.bodyAsClass(webRequest::class.java)
val aas_id = req.aas_id.toIntOrNull() ?: 0
val aas = when (aas_id) {
1 -> aas1
2 -> aas2
3 -> aas3
else -> throw Exception("Invalid AAS id")
}
when (req.command) {
"get" -> {
if (aas != null) {
aas.GetFlightFilterTable { success, filters ->
if (success) {
it.json(webReply(command = req.command, message = "success"))
} else throw Exception("Failed to retrieve Flight Filter data")
}
} else throw Exception("Invalid AAS id")
}
"clear" ->{
if (aas != null) {
aas.ClearFlightFilterTable { success ->
if (success) {
it.json(webReply(command = req.command, message = "success"))
} else throw Exception("Failed to clear Flight Filter data")
}
} else throw Exception("Invalid AAS id")
}
"add" ->{
val data = mapper.readValue(req.data, FlightFilter::class.java)
if (aas != null) {
aas.InsertFlightFilter(data) { success ->
if (success) {
it.json(webReply(command = req.command, data=req.data, message = "success"))
} else throw Exception("Failed to add Flight Filter data")
}
} else throw Exception("Invalid AAS id")
}
"delete"->{
// data is index of flight filter to delete
val data = req.data.toIntOrNull() ?: 0
if (aas != null) {
aas.DeleteFlightFilter(data) { success ->
if (success) {
it.json(webReply(command = req.command, data=req.data, message = "success"))
} else throw Exception("Failed to delete Flight Filter data")
}
} else throw Exception("Invalid AAS id")
}
"patch"->{
val data = mapper.readValue(req.data, FlightFilter::class.java)
if (aas != null) {
aas.PatchFlightFilter(data.id, data) { success ->
if (success) {
it.json(webReply(command = req.command, data=req.data, message = "success"))
} else throw Exception("Failed to patch Flight Filter data")
}
} else throw Exception("Invalid AAS id")
}
else -> throw Exception("Invalid FlightFilter command")
}
} catch (e: Exception) {
val str = "Error parsing FlightFilter request: ${e.message}"
Logger.error { str }
it.status(500).json(webReply(message = str))
} }
} }
before("log.html"){
if (config.WebUsername!=it.cookie("username")){ before("home.html") {
Logger.info{"${it.ip()} Have not logged in, forward to login.html"} if (config.WebUsername != it.cookie("username")) {
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
it.redirect("login.html") it.redirect("login.html")
return@before
} }
} }
before("setting.html"){ before("log.html") {
if (config.WebUsername!=it.cookie("username")){ if (config.WebUsername != it.cookie("username")) {
Logger.info{"${it.ip()} Have not logged in, forward to login.html"} Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
it.redirect("login.html")
}
}
before("setting.html") {
if (config.WebUsername != it.cookie("username")) {
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
it.redirect("login.html") it.redirect("login.html")
return@before
} }
} }
} }
@@ -140,13 +255,14 @@ class WebUI{
/** /**
* Start WebUI Server * Start WebUI Server
*/ */
fun Start(){ fun Start() {
app.start(config.WebPort) app.start(config.WebPort)
} }
/** /**
* Stop WebUI Server * Stop WebUI Server
*/ */
fun Stop(){ fun Stop() {
app.stop() app.stop()
} }

View File

@@ -1,4 +1,3 @@
package Web package Web
class webReply(val message: String) { class webReply(var command: String?=null, val message: String, val data: String?=null)
}

3
src/Web/webRequest.kt Normal file
View File

@@ -0,0 +1,3 @@
package Web
data class webRequest(val command: String, val aas_id: String, val data: String)

View File

@@ -0,0 +1,3 @@
package database
data class FlightFilter(val id: Int,val Description: String, val AirlineCode: String, val FlightNumber: String, val DepartureZone: String, val ArrivalZone: String)

View File

@@ -5,6 +5,7 @@ import java.sql.DriverManager
import config import config
import org.tinylog.Logger import org.tinylog.Logger
import java.util.function.BiConsumer import java.util.function.BiConsumer
import java.util.function.Consumer
@Suppress("UNUSED") @Suppress("UNUSED")
/** /**
@@ -12,6 +13,30 @@ import java.util.function.BiConsumer
* @param aas_id The AAS ID (1, 2, or 3) * @param aas_id The AAS ID (1, 2, or 3)
*/ */
class MySQLAdapter(val aas_id: Int) { class MySQLAdapter(val aas_id: Int) {
private var _verified = false
private var _successcount = 0
private var _failcount = 0
private val _broadcastzones = ArrayList<String>()
private val _airlinecodes = ArrayList<String>()
private val _queueTableData = ArrayList<QueueTableData>()
/**
* Connection Verified
*/
val ConnectionVerified : Boolean
get() = _verified
/**
* Successful transactions count
*/
val SuccessCount: Int
get() = _successcount
/**
* Failed transactions count
*/
val FailCount: Int
get() = _failcount
init{ init{
require(aas_id in 1..3){ require(aas_id in 1..3){
@@ -19,6 +44,24 @@ class MySQLAdapter(val aas_id: Int) {
} }
} }
/**
* Last Result of Get Broadcast Zones
*/
val BroadcastZones : ArrayList<String>
get() = _broadcastzones
/**
* Last Result of Get Airline Codes
*/
val AirlineCodes : ArrayList<String>
get() = _airlinecodes
/**
* Last Result of Get Queue Table
*/
val QueueTable: ArrayList<QueueTableData>
get() = _queueTableData
/** /**
* Try to connect to MySQL Database * Try to connect to MySQL Database
* @param cb Callback function with parameters (success: Boolean, connection: Connection) * @param cb Callback function with parameters (success: Boolean, connection: Connection)
@@ -33,18 +76,73 @@ class MySQLAdapter(val aas_id: Int) {
} }
if (conn != null){ if (conn != null){
cb.accept(true, conn) cb.accept(true, conn)
_verified = true
} else throw Exception("Connection is null") } else throw Exception("Connection is null")
} catch (e : Exception){ } catch (e : Exception){
Logger.error { "Failed to connect MySQL Adapter for AAS$aas_id: ${e.message}" } Logger.error { "Failed to connect MySQL Adapter for AAS$aas_id: ${e.message}" }
_verified = false
cb.accept(false, null) cb.accept(false, null)
} }
} }
/** /**
* Get Airline Codes * Verify Connection to MySQL Database
* @param cb Callback function with parameters (success: Boolean, codes: ArrayList<String>) * @param cb Callback function with parameter (success: Boolean)
*/ */
fun GetAirlineCode(cb: BiConsumer<Boolean, ArrayList<String>>){ fun VerifyConnection(cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
connection!!.close()
_verified = true
cb.accept(true)
} else {
_verified = false
cb.accept(false)
}
}
}
/**
* Get Broadcast Zones
* @param cb Callback function (optional) with parameters (success: Boolean, zones: ArrayList<String
*/
fun GetBroadcastZones(cb: BiConsumer<Boolean, ArrayList<String>>? = null){
Connect { success, connection ->
if (success){
try {
connection!!.prepareStatement("SELECT DISTINCT description from aas.broadcastzones").use { statement ->
val result = ArrayList<String>()
statement.executeQuery().use { rs ->
while (rs.next()){
result.add(rs.getString("ZONE"))
}
}
connection.close()
Logger.info { "GetBroadcastZones succeeded, found ${result.size} zones" }
cb?.accept(true, result)
_successcount++
_broadcastzones.clear()
_broadcastzones.addAll(result)
}
} catch (e: Exception){
Logger.error { "GetBroadcastZones failed, exception: ${e.message}" }
cb?.accept(false, arrayListOf())
_failcount++
}
} else {
Logger.error { "GetBroadcastZones failed, no Connection" }
cb?.accept(false, arrayListOf())
_failcount++
}
}
}
/**
* Get Airline Codes
* @param cb Callback function (optional) with parameters (success: Boolean, codes: ArrayList<String>)
*/
fun GetAirlineCode(cb: BiConsumer<Boolean, ArrayList<String>>? = null){
Connect { success, connection -> Connect { success, connection ->
if (success){ if (success){
try { try {
@@ -57,16 +155,133 @@ class MySQLAdapter(val aas_id: Int) {
} }
connection.close() connection.close()
Logger.info { "GetAirlineCode succeeded, found ${result.size} codes" } Logger.info { "GetAirlineCode succeeded, found ${result.size} codes" }
cb.accept(true, result) cb?.accept(true, result)
_successcount++
_airlinecodes.clear()
_airlinecodes.addAll(result)
} }
} catch (e: Exception){ } catch (e: Exception){
Logger.error { "GetAirlineCode failed, exception: ${e.message}" } Logger.error { "GetAirlineCode failed, exception: ${e.message}" }
cb.accept(false, arrayListOf()) cb?.accept(false, arrayListOf())
_failcount++
} }
} else { } else {
Logger.error { "GetAirlineCode failed, no Connection" } Logger.error { "GetAirlineCode failed, no Connection" }
cb.accept(false, arrayListOf()) cb?.accept(false, arrayListOf())
_failcount++
}
}
}
/**
* Get Queue Table records
* @param cb Callback function (optional) with parameters (success: Boolean, records: ArrayList<QueueTableData>)
*/
fun GetQueueTable(cb: BiConsumer<Boolean, ArrayList<QueueTableData>>? = null){
Connect { success, connection ->
if (success){
try {
connection!!.prepareStatement("SELECT * from aas.queue_table").use { statement ->
val result = ArrayList<QueueTableData>()
statement.executeQuery().use { rs ->
while (rs.next()){
result.add(
QueueTableData(
Date_Time = rs.getString("Date_Time"),
Source = rs.getString("Source"),
Tipe = rs.getString("Type"),
Message = rs.getString("Message"),
SB_Tags = rs.getString("SB_TAGS"),
BroadcastZones = rs.getString("BroadcastZones"),
Language = rs.getString("Language")
)
)
}
}
connection.close()
Logger.info { "GetQueueTable succeeded, found ${result.size} records" }
cb?.accept(true, result)
_successcount++
_queueTableData.clear()
_queueTableData.addAll(result)
}
} catch (e: Exception){
Logger.error { "GetQueueTable failed, exception: ${e.message}" }
cb?.accept(false, arrayListOf())
_failcount++
}
} else {
Logger.error { "GetQueueTable failed, no Connection" }
cb?.accept(false, arrayListOf())
_failcount++
}
}
}
/**
* Clear Queue Table
* @param cb Callback function with parameter (success: Boolean)
*/
fun ClearQueueTable(cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try {
connection!!.prepareStatement("TRUNCATE TABLE aas.queue_table").use { statement ->
val rowsAffected = statement.executeUpdate()
connection.close()
Logger.info { "ClearQueueTable succeeded, deleted $rowsAffected records" }
cb.accept(true)
_successcount++
}
} catch (e: Exception){
Logger.error { "ClearQueueTable failed, exception: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "ClearQueueTable failed, no Connection" }
cb.accept(false)
_failcount++
}
}
}
/**
* Delete records from Queue Table by index
* @param index Vararg of record IDs to delete
* @param cb Callback function with parameter (success: Boolean)
*/
fun DeleteQueueTable(vararg index: Int, cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try{
var updatecount : IntArray
connection!!.prepareStatement("DELETE FROM aas.queue_table WHERE id = ?").use { ps ->
index.forEach { id ->
ps.setInt(1, id)
ps.addBatch()
}
updatecount = ps.executeBatch()
ps.close()
}
connection.close()
Logger.info { "Deleted ${index.size} records from AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" }
cb.accept(true)
_successcount++
} catch (e : Exception){
Logger.error { "Failed to delete MySQL Adapter for AAS$aas_id: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "DeleteQueueTable failed , no Connection" }
cb.accept(false)
_failcount++
} }
} }
} }
@@ -74,8 +289,9 @@ class MySQLAdapter(val aas_id: Int) {
/** /**
* Insert records to Queue Table * Insert records to Queue Table
* @param queue Vararg of QueueTableData to insert * @param queue Vararg of QueueTableData to insert
* @param cb Callback function with parameter (success: Boolean)
*/ */
fun InsertToQueueTable(vararg queue: QueueTableData){ fun InsertToQueueTable(vararg queue: QueueTableData, cb: Consumer<Boolean>){
Connect { success, connection -> Connect { success, connection ->
if (success){ if (success){
var updatecount : IntArray var updatecount : IntArray
@@ -98,13 +314,250 @@ class MySQLAdapter(val aas_id: Int) {
connection.close() connection.close()
Logger.info { "Inserted ${queue.size} records to AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" } Logger.info { "Inserted ${queue.size} records to AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" }
cb.accept(true)
_successcount++
} catch (e : Exception){ } catch (e : Exception){
Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id: ${e.message}" } Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id: ${e.message}" }
cb.accept(false)
_failcount++
} }
} else Logger.error { "InsertToQueueTable failed , no Connection" } } else {
Logger.error { "InsertToQueueTable failed , no Connection" }
cb.accept(false)
_failcount++
}
} }
} }
/**
* Create Flight Filter Table if not exists
* @param cb Callback function with parameter (success: Boolean)
*/
fun CreateFlightFilterTable(cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try {
connection!!.prepareStatement(
"""
CREATE TABLE IF NOT EXISTS aas.tblFlightFilter (
id INT AUTO_INCREMENT PRIMARY KEY,
description VARCHAR(35) NOT NULL,
airlineCode VARCHAR(4) NOT NULL,
flightNumber VARCHAR(4) NOT NULL,
departureZone VARCHAR(512) NOT NULL,
arrivalZone VARCHAR(512) NOT NULL
);
""".trimIndent()
).use { statement ->
statement.executeUpdate()
connection.close()
Logger.info { "CreateFlightFilterTable succeeded or already exists" }
cb.accept(true)
_successcount++
}
} catch (e: Exception){
Logger.error { "CreateFlightFilterTable failed, exception: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "CreateFlightFilterTable failed, no Connection" }
cb.accept(false)
_failcount++
}
}
}
/**
* Clear Flight Filter Table
* @param cb Callback function with parameter (success: Boolean)
*/
fun ClearFlightFilterTable(cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try {
connection!!.prepareStatement("TRUNCATE TABLE aas.tblFlightFilter").use { statement ->
val rowsAffected = statement.executeUpdate()
connection.close()
Logger.info { "ClearFlightFilterTable succeeded, deleted $rowsAffected records" }
cb.accept(true)
_successcount++
}
} catch (e: Exception){
Logger.error { "ClearFlightFilterTable failed, exception: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "ClearFlightFilterTable failed, no Connection" }
cb.accept(false)
_failcount++
}
}
}
/**
* Get Flight Filter Table records
* @param cb Callback function with parameters (success: Boolean, records: ArrayList<FlightFilter>)
*/
fun GetFlightFilterTable(cb: BiConsumer<Boolean, ArrayList<FlightFilter>>){
Connect { success, connection ->
if (success){
try{
connection!!.prepareStatement("SELECT * FROM aas.tblFlightFilter").use { statement ->
statement.executeQuery().use { rs ->
val result = ArrayList<FlightFilter>()
while (rs.next()){
result.add(
FlightFilter(
id = rs.getInt("id"),
Description = rs.getString("description"),
AirlineCode = rs.getString("airlineCode"),
FlightNumber = rs.getString("flightNumber"),
DepartureZone = rs.getString("departureZone"),
ArrivalZone = rs.getString("arrivalZone")
)
)
}
connection.close()
Logger.info { "GetFlightFilterTable succeeded, found ${result.size} records" }
cb.accept(true, result)
_successcount++
}
}
} catch (e : Exception){
Logger.error { "GetFlightFilterTable failed, exception: ${e.message}" }
cb.accept(false, arrayListOf())
_failcount++
}
} else {
Logger.error { "GetFlightFilterTable failed, no Connection" }
cb.accept(false, arrayListOf())
_failcount++
}
}
}
/**
* Patch record in Flight Filter Table by index
* @param index Record ID to patch
* @param flight FlightFilter data to update
* @param cb Callback function with parameter (success: Boolean)
*/
fun PatchFlightFilter(index: Int, flight : FlightFilter, cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try{
connection!!.prepareStatement("UPDATE aas.tblFlightFilter SET description = ?, airlineCode = ?, flightNumber = ?, departureZone = ?, arrivalZone = ? WHERE id = ?").use { ps ->
ps.setString(1, flight.Description)
ps.setString(2, flight.AirlineCode)
ps.setString(3, flight.FlightNumber)
ps.setString(4, flight.DepartureZone)
ps.setString(5, flight.ArrivalZone)
ps.setInt(6, index)
val updatecount = ps.executeUpdate()
ps.close()
connection.close()
Logger.info { "Patched record $index in AAS$aas_id Flight Filter Table, update count: $updatecount" }
cb.accept(true)
_successcount++
}
} catch (e : Exception){
Logger.error { "Failed to patch MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "PatchFlightFilter failed , no Connection" }
cb.accept(false)
_failcount++
}
}
}
/**
* Delete records from Flight Filter Table by index
* @param index Vararg of record IDs to delete
* @param cb Callback function with parameter (success: Boolean)
*/
fun DeleteFlightFilter(vararg index: Int, cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try{
var updatecount : IntArray
connection!!.prepareStatement("DELETE FROM aas.tblFlightFilter WHERE id = ?").use { ps ->
index.forEach { id ->
ps.setInt(1, id)
ps.addBatch()
}
updatecount = ps.executeBatch()
ps.close()
}
connection.close()
Logger.info { "Deleted ${index.size} records from AAS$aas_id Flight Filter Table, update counts: ${updatecount.joinToString()}" }
cb.accept(true)
_successcount++
} catch (e : Exception){
Logger.error { "Failed to delete MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "DeleteFlightFilter failed , no Connection" }
cb.accept(false)
_failcount++
}
}
}
/**
* Insert records to Flight Filter Table
* @param ff Vararg of FlightFilter to insert
* @param cb Callback function with parameter (success: Boolean)
*/
fun InsertFlightFilter(vararg ff: FlightFilter, cb: Consumer<Boolean>){
Connect { success, connection ->
if (success){
try{
var updatecount : IntArray
connection!!.prepareStatement("INSERT INTO aas.tblFlightFilter (description, airlineCode, flightNumber, departureZone, arrivalZone) VALUES (?,?,?,?,?)").use { ps ->
ff.forEach { data ->
ps.setString(1, data.Description)
ps.setString(2, data.AirlineCode)
ps.setString(3, data.FlightNumber)
ps.setString(4, data.DepartureZone)
ps.setString(5, data.ArrivalZone)
ps.addBatch()
}
updatecount = ps.executeBatch()
ps.close()
}
connection.close()
Logger.info { "Inserted ${ff.size} records to AAS$aas_id Flight Filter Table, update counts: ${updatecount.joinToString()}" }
cb.accept(true)
_successcount++
} catch (e : Exception){
Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
cb.accept(false)
_failcount++
}
} else {
Logger.error { "InsertFlightFilter failed , no Connection" }
cb.accept(false)
_failcount++
}
}
}
} }

View File

@@ -1,3 +1,4 @@
package database package database
data class QueueTableData(val Date_Time: String, val Source: String, val Tipe: String, val Message: String, val SB_Tags: String, val BroadcastZones: String, val Language: String) data class QueueTableData(val Date_Time: String, val Source: String, val Tipe: String, val Message: String, val SB_Tags: String, val BroadcastZones: String, val Language: String)