Compare commits
10 Commits
8046dd0e62
...
9252b2fee5
Author | SHA1 | Date | |
---|---|---|---|
9252b2fee5 | |||
76bf6f2847 | |||
d3ab9c4766 | |||
46df0377ee | |||
20d91d5c47 | |||
c62c233778 | |||
21a3f61152 | |||
5715030c7a | |||
0516c2c964 | |||
48877ddcec |
22
.run/ApplicationKt.run.xml
Normal file
22
.run/ApplicationKt.run.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="ApplicationKt" type="KtorApplicationConfigurationType" factoryName="Ktor" nameIsGenerated="true">
|
||||||
|
<envs>
|
||||||
|
<env name="KTOR_ENV" value="dev" />
|
||||||
|
<env name="DB_PASSWORD" value="pacs_db" />
|
||||||
|
</envs>
|
||||||
|
<option name="MAIN_CLASS_NAME" value="net.ipksindia.ApplicationKt" />
|
||||||
|
<module name="neft-server.main" />
|
||||||
|
<option name="alternativeJrePath" />
|
||||||
|
<option name="alternativeJrePathEnabled" value="false" />
|
||||||
|
<option name="includeProvidedScope" value="false" />
|
||||||
|
<option name="mainClass" value="net.ipksindia.ApplicationKt" />
|
||||||
|
<option name="passParentEnvs" value="true" />
|
||||||
|
<option name="programParameters" value="" />
|
||||||
|
<option name="shortenCommandLine" />
|
||||||
|
<option name="vmParameters" />
|
||||||
|
<option name="workingDirectory" value="D:\work\neft-server" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@ -1,4 +1,3 @@
|
|||||||
val kotlin_version: String by project
|
|
||||||
val logback_version: String by project
|
val logback_version: String by project
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@ -32,6 +31,5 @@ dependencies {
|
|||||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
|
||||||
implementation("org.slf4j:slf4j-api:2.0.16")
|
implementation("org.slf4j:slf4j-api:2.0.16")
|
||||||
testImplementation("io.ktor:ktor-server-test-host-jvm")
|
implementation("com.zaxxer:HikariCP:6.0.0")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package net.ipksindia
|
package net.ipksindia
|
||||||
|
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.engine.*
|
|
||||||
import io.ktor.server.netty.*
|
import io.ktor.server.netty.*
|
||||||
import net.ipksindia.plugins.*
|
import net.ipksindia.config.configureApplication
|
||||||
|
import net.ipksindia.plugins.configureRouting
|
||||||
|
import net.ipksindia.plugins.configureSerialization
|
||||||
|
|
||||||
fun main() {
|
fun main(args: Array<String>):Unit = EngineMain.main(args)
|
||||||
embeddedServer(Netty, port = 8083, host = "0.0.0.0", module = Application::module)
|
|
||||||
.start(wait = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Application.module() {
|
fun Application.module() {
|
||||||
|
configureApplication()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting()
|
configureRouting()
|
||||||
}
|
}
|
||||||
|
3
src/main/kotlin/net/ipksindia/ItemNotFoundException.kt
Normal file
3
src/main/kotlin/net/ipksindia/ItemNotFoundException.kt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package net.ipksindia
|
||||||
|
|
||||||
|
class ItemNotFoundException(type: String, name: String) : Exception("Not Found $type: $name")
|
@ -1,90 +1,114 @@
|
|||||||
package net.ipksindia
|
package net.ipksindia
|
||||||
|
|
||||||
import dao.TellerDao
|
import model.TransactionRequest
|
||||||
|
import net.ipksindia.config.AppConfig
|
||||||
|
import net.ipksindia.dao.TellerDao
|
||||||
import net.ipksindia.dao.TransactionDao
|
import net.ipksindia.dao.TransactionDao
|
||||||
|
import net.ipksindia.model.NeftTransaction
|
||||||
|
import net.ipksindia.model.OutwardNeftResponse
|
||||||
|
import net.ipksindia.model.TransferTransaction
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import response.TransactionFailureResponse
|
import response.TransactionFailureResponse
|
||||||
|
import response.TransactionResponse
|
||||||
import response.TransactionSuccessResponse
|
import response.TransactionSuccessResponse
|
||||||
|
|
||||||
class NeftRequestProcessor {
|
class NeftRequestProcessor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(NeftRequestProcessor::class.java)
|
private val logger: Logger = LoggerFactory.getLogger(NeftRequestProcessor::class.java)
|
||||||
private val migratedDCCBCodes = listOf("0003","0015")
|
private val migratedDCCBCodes = AppConfig.bankCodes
|
||||||
val bankDccbToSftpMap = mutableMapOf<String, String>(
|
|
||||||
"0015" to "0005", //Tamluk
|
|
||||||
"0003" to "0021", //Balageria
|
|
||||||
// "0016" to "0001", //WBSCB
|
|
||||||
)
|
|
||||||
|
|
||||||
fun process(transactionNumber: String): Pair<String, String>? {
|
/**
|
||||||
|
* Process the transaction request based on the transaction number.
|
||||||
|
* @param transactionNumber The transaction number to be processed.
|
||||||
|
* @return A pair of transferQueueNumber and neftQueueNumber if successful, null otherwise.
|
||||||
|
*/
|
||||||
|
fun process(transactionNumber: String): OutwardNeftResponse {
|
||||||
|
return try {
|
||||||
|
val transactionRequest = fetchTransactionRequest(transactionNumber)
|
||||||
|
val dccbCode = transactionRequest.dccbCode.padStart(4, '0')
|
||||||
|
val branchCode = transactionRequest.branchCode.padStart(5, '0')
|
||||||
|
|
||||||
val outwardTransaction = TransactionDao().getTransactionRequest(transactionNumber) ?: run {
|
if (!isDCCBCodeMigrated(dccbCode)) {
|
||||||
logger.error("TXN: #{} FAILED REASON: Transaction not found", transactionNumber)
|
logDCCBCodeNotMigrated(transactionNumber)
|
||||||
return null
|
return OutwardNeftResponse(0, "DCCB NOT MIGRATED", null, null)
|
||||||
}
|
}
|
||||||
logger.info("TXN: #{} FOUND", transactionNumber)
|
|
||||||
|
|
||||||
val dccbCode = outwardTransaction.dccbCode.padStart(4, '0')
|
val teller = TellerDao().getTeller(dccbCode, branchCode)
|
||||||
val branchCode = outwardTransaction.branchCode.padStart(5, '0')
|
val transactionPair = TransactionFactory(transactionRequest, teller)
|
||||||
|
.createTransactionPair()
|
||||||
|
|
||||||
if(dccbCode !in migratedDCCBCodes) {
|
executeAndProcessTransaction(transactionNumber, transactionRequest, transactionPair)
|
||||||
logger.error("TXN: #{} FAILED REASON: DCCB Code not migrated", transactionNumber)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val makerTeller = TellerDao.getTeller(dccbCode, branchCode) ?: run {
|
|
||||||
logger.error("TXN: #{} FAILED REASON: Teller not found", transactionNumber)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val transactionPair = TransactionFactory(outwardTransaction, makerTeller).createTransactionPair()
|
|
||||||
logger.info("TXN: #{} TRANSFER RRN: {} NEFT RRN: {}", transactionNumber, transactionPair.first.rrn, transactionPair.second.rrn)
|
|
||||||
val (transferResponse, neftResponse) = try {
|
|
||||||
TransactionExecutor().executePair(transactionPair)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.error("TXN: #{} FAILED REASON: {}", transactionNumber, e.message)
|
logger.error("TXN: #{} FAILED REASON: {}", transactionNumber, e.toString())
|
||||||
return null
|
OutwardNeftResponse(0, "ERROR OCCURRED DURING PROCESSING", null, null)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.info(
|
/**
|
||||||
"TXN: #{} TRF_TXN: {} NEFT_TXN: {}",
|
* Fetch the transaction request using the transaction number.
|
||||||
transactionNumber,
|
*/
|
||||||
transferResponse.status,
|
private fun fetchTransactionRequest(transactionNumber: String): TransactionRequest {
|
||||||
neftResponse.status
|
val transactionRequest = TransactionDao().getTransactionRequest(transactionNumber)
|
||||||
)
|
logger.info("TXN: #{} FOUND", transactionNumber)
|
||||||
|
return transactionRequest
|
||||||
|
}
|
||||||
|
|
||||||
if (transferResponse.status == "SUCCESS" && neftResponse.status == "SUCCESS") {
|
/**
|
||||||
|
* Check if the DCCB code is not migrated.
|
||||||
|
*/
|
||||||
|
private fun isDCCBCodeMigrated(dccbCode: String)= dccbCode in migratedDCCBCodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an error if the DCCB code is not migrated.
|
||||||
|
*/
|
||||||
|
private fun logDCCBCodeNotMigrated(transactionNumber: String) {
|
||||||
|
logger.error("TXN: #{} FAILED REASON: DCCB Code not migrated", transactionNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the transaction pair and process the results.
|
||||||
|
*/
|
||||||
|
private fun executeAndProcessTransaction(
|
||||||
|
transactionNumber: String,
|
||||||
|
transactionRequest: TransactionRequest,
|
||||||
|
transactionPair: Pair<TransferTransaction, NeftTransaction>
|
||||||
|
): OutwardNeftResponse {
|
||||||
|
val (transferResponse, neftResponse) = TransactionExecutor().executePair(transactionPair)
|
||||||
|
|
||||||
|
return if (isSuccess(transferResponse, neftResponse)) {
|
||||||
val transferQueueNumber = (transferResponse as TransactionSuccessResponse).queueNumber
|
val transferQueueNumber = (transferResponse as TransactionSuccessResponse).queueNumber
|
||||||
val neftQueueNumber = (neftResponse as TransactionSuccessResponse).queueNumber
|
val neftQueueNumber = (neftResponse as TransactionSuccessResponse).queueNumber
|
||||||
try {
|
TransactionDao().updateSuccessTransaction(transactionRequest, transferQueueNumber, neftQueueNumber)
|
||||||
TransactionDao().updateSuccessTransaction(outwardTransaction, transferQueueNumber, neftQueueNumber)
|
|
||||||
logger.info("TXN: #{} UPDATED RESULTS SUCCESSFULLY", transactionNumber)
|
logger.info("TXN: #{} UPDATED RESULTS SUCCESSFULLY", transactionNumber)
|
||||||
} catch (e: Exception) {
|
OutwardNeftResponse(1, "transaction successful", transferQueueNumber, neftQueueNumber)
|
||||||
logger.error(
|
|
||||||
"TXN: #{} QUEUE INITIATED BUT FAILED TO UPDATE RESULT: {}",
|
|
||||||
transactionNumber,
|
|
||||||
e.message
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return Pair(transferQueueNumber, neftQueueNumber)
|
|
||||||
} else {
|
} else {
|
||||||
val transferErrorMsg = (transferResponse as TransactionFailureResponse).errorMsg
|
logTransactionFailure(transactionNumber, transferResponse, neftResponse)
|
||||||
val neftErrorMsg = (neftResponse as TransactionFailureResponse).errorMsg
|
OutwardNeftResponse(0, "TRANSACTION FAILED", null, null)
|
||||||
logger.error(
|
|
||||||
"TXN: #{} TRANSFER TXN FAILED DUE TO: {}",
|
|
||||||
transactionNumber,
|
|
||||||
transferErrorMsg
|
|
||||||
)
|
|
||||||
logger.error(
|
|
||||||
"TXN: #{} NEFT TXN FAILED DUE TO: {}",
|
|
||||||
transactionNumber,
|
|
||||||
neftErrorMsg
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return null
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if both transfer and NEFT responses are successful.
|
||||||
|
*/
|
||||||
|
private fun isSuccess(transferResponse: TransactionResponse, neftResponse: TransactionResponse) = transferResponse is TransactionSuccessResponse && neftResponse is TransactionSuccessResponse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log errors if the transaction fails.
|
||||||
|
*/
|
||||||
|
private fun logTransactionFailure(
|
||||||
|
transactionNumber: String,
|
||||||
|
transferResponse: Any,
|
||||||
|
neftResponse: Any
|
||||||
|
) {
|
||||||
|
val transferErrorMsg = (transferResponse as? TransactionFailureResponse)?.errorMsg ?: "Unknown Error"
|
||||||
|
val neftErrorMsg = (neftResponse as? TransactionFailureResponse)?.errorMsg ?: "Unknown Error"
|
||||||
|
|
||||||
|
logger.error("TXN: #{} TRANSFER TXN FAILED DUE TO: {}", transactionNumber, transferErrorMsg)
|
||||||
|
logger.error("TXN: #{} NEFT TXN FAILED DUE TO: {}", transactionNumber, neftErrorMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
class TellerNotFoundException(s: String) : Exception(s)
|
|
@ -1,76 +1,76 @@
|
|||||||
package net.ipksindia
|
package net.ipksindia
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import net.ipksindia.config.AppConfig
|
||||||
import net.ipksindia.model.NeftTransaction
|
import net.ipksindia.model.NeftTransaction
|
||||||
import net.ipksindia.model.TransferTransaction
|
import net.ipksindia.model.TransferTransaction
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.json.JSONException
|
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import response.TransactionFailureResponse
|
import response.TransactionFailureResponse
|
||||||
import response.TransactionResponse
|
import response.TransactionResponse
|
||||||
import response.TransactionSuccessResponse
|
import response.TransactionSuccessResponse
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.net.ssl.HostnameVerifier
|
|
||||||
|
|
||||||
|
|
||||||
class TransactionExecutor() {
|
class TransactionExecutor() {
|
||||||
|
private val logger = LoggerFactory.getLogger(TransactionExecutor::class.java)
|
||||||
private val protocol = "https"
|
private val transactionUrl = AppConfig.remoteServerConfig.transactionUrl
|
||||||
private val host = "180.179.110.185"
|
|
||||||
private val port = "443"
|
|
||||||
private val rootRoute = "IPKS_Queue_Generation"
|
|
||||||
private val remoteUrl = "$protocol://$host:$port/$rootRoute"
|
|
||||||
|
|
||||||
fun executePair(transactionPair: Pair<TransferTransaction, NeftTransaction>): Pair<TransactionResponse, TransactionResponse> {
|
fun executePair(transactionPair: Pair<TransferTransaction, NeftTransaction>): Pair<TransactionResponse, TransactionResponse> {
|
||||||
|
|
||||||
val transferTransaction = transactionPair.first
|
val transferTransaction = transactionPair.first
|
||||||
val neftTransaction = transactionPair.second
|
val neftTransaction = transactionPair.second
|
||||||
|
|
||||||
val transferResponse = execute(Json.encodeToString(transferTransaction))
|
val transferResponseString = execute(Json.encodeToString(transferTransaction))
|
||||||
val neftResponse = execute(Json.encodeToString(neftTransaction))
|
logger.debug("TRANSFER-RRN: {} - CBS Response: {}", transferTransaction.rrn, transferResponseString)
|
||||||
|
val transferResponse = processResponse(transferResponseString)
|
||||||
|
val neftResponseString = execute(Json.encodeToString(neftTransaction))
|
||||||
|
logger.debug("NEFT-RRN: {}, CBS Response: {}", neftTransaction.rrn, neftResponseString)
|
||||||
|
val neftResponse = processResponse(neftResponseString)
|
||||||
return Pair(transferResponse, neftResponse)
|
return Pair(transferResponse, neftResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun execute(postBody: String): TransactionResponse {
|
private fun execute(postBody: String): String {
|
||||||
// println(postBody)
|
|
||||||
val transferRoute = "IpksApi"
|
|
||||||
val transferURL = "$remoteUrl/$transferRoute"
|
|
||||||
val jsonMediaType = "application/json; charset=utf-8".toMediaType()
|
val jsonMediaType = "application/json; charset=utf-8".toMediaType()
|
||||||
|
|
||||||
val httpClient = OkHttpClient
|
val httpClient = OkHttpClient
|
||||||
.Builder()
|
.Builder()
|
||||||
.hostnameVerifier(HostnameVerifier { _, _ -> true })
|
.hostnameVerifier { _, _ -> true }
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = Request
|
val request = Request
|
||||||
.Builder()
|
.Builder()
|
||||||
.url(transferURL)
|
.url(transactionUrl)
|
||||||
.post(postBody.toRequestBody(jsonMediaType))
|
.post(postBody.toRequestBody(jsonMediaType))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val responseBody = httpClient.newCall(request).execute().use { response ->
|
return httpClient.newCall(request).execute().use { response ->
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
throw IOException("Unexpected response: ${response.body}")
|
throw IOException("Unexpected response: ${response.body}")
|
||||||
}
|
}
|
||||||
response.body?.string() ?: throw IOException("no response body")
|
response.body?.string() ?: throw IOException("no response body")
|
||||||
}
|
}
|
||||||
|
|
||||||
val responseObj = JSONObject(responseBody)
|
|
||||||
val status = try {responseObj.getString("status") } catch(_: JSONException) { "" }
|
|
||||||
val message = try { responseObj.getString("message") }catch(_: JSONException) { "" }
|
|
||||||
val error = try { responseObj.getInt("error") } catch(_: JSONException) { 1 }
|
|
||||||
|
|
||||||
val response = if(responseBody.contains("SUCCESS")) {
|
|
||||||
val queueNo = try { responseObj.getJSONObject("response").getString("QueueId") } catch(_: JSONException) { "" }
|
|
||||||
return TransactionSuccessResponse(status, message, queueNo, error)
|
|
||||||
} else {
|
|
||||||
val errorMsg = try { responseObj.getJSONObject("response").getString("errorMsg") } catch(_: JSONException) { responseBody }
|
|
||||||
return TransactionFailureResponse(status, message, errorMsg, error)
|
|
||||||
}
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processResponse(responseBody: String): TransactionResponse {
|
||||||
|
val responseObj = JSONObject(responseBody)
|
||||||
|
val status = responseObj.getString("status")
|
||||||
|
val message = responseObj.getString("message")
|
||||||
|
val error = responseObj.getInt("error")
|
||||||
|
|
||||||
|
if(responseBody.contains("SUCCESS")) {
|
||||||
|
val queueNo = responseObj.getJSONObject("response").getString("QueueId")
|
||||||
|
return TransactionSuccessResponse(status, message, queueNo, error)
|
||||||
|
} else {
|
||||||
|
val errorMsg = responseObj.getJSONObject("response").getString("errorMsg")
|
||||||
|
return TransactionFailureResponse(status, message, errorMsg, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -5,19 +5,18 @@ import net.ipksindia.model.NeftTransaction
|
|||||||
import model.Teller
|
import model.Teller
|
||||||
import model.TransactionRequest
|
import model.TransactionRequest
|
||||||
import net.ipksindia.model.TransferTransaction
|
import net.ipksindia.model.TransferTransaction
|
||||||
import net.ipksindia.NeftRequestProcessor.Companion.bankDccbToSftpMap
|
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
class TransactionFactory(private val transactionRequest: TransactionRequest, private val teller: Teller) {
|
class TransactionFactory(private val transactionRequest: TransactionRequest, private val teller: Teller) {
|
||||||
|
private val bankDccbToSftpMap = mutableMapOf("0015" to "0005", "0003" to "0021")
|
||||||
private val date = transactionRequest.date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))
|
private val date = transactionRequest.date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))
|
||||||
private val rrn = transactionRequest.date.format(DateTimeFormatter.ofPattern("ddMM")) + transactionRequest.transactionNumber.takeLast(4)
|
private val rrn = transactionRequest.date.format(DateTimeFormatter.ofPattern("ddMM")) + transactionRequest.transactionNumber.takeLast(4)
|
||||||
|
|
||||||
private fun createTransferTransaction(): TransferTransaction {
|
private fun createTransferTransaction(): TransferTransaction {
|
||||||
|
val bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')] ?: throw ItemNotFoundException("SFTP code for", transactionRequest.dccbCode)
|
||||||
return TransferTransaction(
|
return TransferTransaction(
|
||||||
bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')]!!,
|
bankCode = bankCode,
|
||||||
branchCode = transactionRequest.branchCode.padStart(3,'0'),
|
branchCode = transactionRequest.branchCode.padStart(3,'0'),
|
||||||
// branchCode = "99999", for UAT
|
|
||||||
cbsTellerId = teller.tellerId,
|
cbsTellerId = teller.tellerId,
|
||||||
cbsTellerUserType = teller.userType,
|
cbsTellerUserType = teller.userType,
|
||||||
queIdType = "5",
|
queIdType = "5",
|
||||||
@ -42,10 +41,10 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createNEFTTransaction(): NeftTransaction {
|
private fun createNEFTTransaction(): NeftTransaction {
|
||||||
|
val bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')] ?: throw ItemNotFoundException("SFTP code for", transactionRequest.dccbCode)
|
||||||
return NeftTransaction(
|
return NeftTransaction(
|
||||||
bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')]!!,
|
bankCode = bankCode,
|
||||||
branchCode = transactionRequest.branchCode.padStart(3,'0'),
|
branchCode = transactionRequest.branchCode.padStart(3,'0'),
|
||||||
// branchCode = "99999", for UAT
|
|
||||||
cbsTellerId = teller.tellerId,
|
cbsTellerId = teller.tellerId,
|
||||||
cbsTellerUserType = teller.userType,
|
cbsTellerUserType = teller.userType,
|
||||||
queIdType = "5",
|
queIdType = "5",
|
||||||
|
92
src/main/kotlin/net/ipksindia/config/AppConfig.kt
Normal file
92
src/main/kotlin/net/ipksindia/config/AppConfig.kt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package net.ipksindia.config
|
||||||
|
|
||||||
|
import com.typesafe.config.Config
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
import net.ipksindia.config.AppConfig.config
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
object AppConfig {
|
||||||
|
|
||||||
|
private val environment = ConfigFactory.load().getString("ktor.environment")
|
||||||
|
val config: Config = when (environment) {
|
||||||
|
"prod" -> ConfigFactory.load("application-prod.conf")
|
||||||
|
else -> ConfigFactory.load("application-dev.conf")
|
||||||
|
}
|
||||||
|
|
||||||
|
val databaseConfig by lazy { DatabaseConfig(
|
||||||
|
config.getString("database.host"),
|
||||||
|
config.getInt("database.port"),
|
||||||
|
config.getString("database.name"),
|
||||||
|
config.getString("database.user"),
|
||||||
|
config.getString("database.password")
|
||||||
|
)}
|
||||||
|
|
||||||
|
val remoteServerConfig by lazy {
|
||||||
|
RemoteServerConfig(
|
||||||
|
config.getString("bank.server.protocol"),
|
||||||
|
config.getString("bank.server.host"),
|
||||||
|
config.getInt("bank.server.port"),
|
||||||
|
config.getString("bank.server.rootRoute"),
|
||||||
|
config.getString("bank.server.transactionRoute")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bankCodes: MutableList<String> by lazy { config.getStringList("bank.codes")}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class RemoteServerConfig(
|
||||||
|
val protocol: String,
|
||||||
|
val host: String,
|
||||||
|
val port: Int,
|
||||||
|
val rootRoute: String,
|
||||||
|
val transactionRoute: String
|
||||||
|
) {
|
||||||
|
val transactionUrl = "$protocol://$host:$port/$rootRoute/$transactionRoute"
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DatabaseConfig(
|
||||||
|
val host: String,
|
||||||
|
val port: Int,
|
||||||
|
val name: String,
|
||||||
|
val user: String,
|
||||||
|
val password: String
|
||||||
|
) {
|
||||||
|
val url = "jdbc:oracle:thin:@$host:$port:$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validateAppConfigs() {
|
||||||
|
val logger = LoggerFactory.getLogger(AppConfig::class.java)
|
||||||
|
val requiredKeys = listOf(
|
||||||
|
"database.host",
|
||||||
|
"database.port",
|
||||||
|
"database.name",
|
||||||
|
"database.user",
|
||||||
|
"database.password",
|
||||||
|
"bank.server.protocol",
|
||||||
|
"bank.server.host",
|
||||||
|
"bank.server.port",
|
||||||
|
"bank.server.rootRoute",
|
||||||
|
"bank.server.transactionRoute",
|
||||||
|
"bank.codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
val missingKeys = requiredKeys.filterNot { config.hasPath(it) }
|
||||||
|
|
||||||
|
if (missingKeys.isNotEmpty()) {
|
||||||
|
logger.error("Missing configuration keys: {}", missingKeys.toString())
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dbPort = config.getInt("database.port")
|
||||||
|
val remoteServerPort = config.getInt("bank.server.port")
|
||||||
|
if (dbPort !in 1..65535) {
|
||||||
|
logger.error("Invalid database port: {}", dbPort)
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteServerPort !in 1..65535) {
|
||||||
|
logger.error("Invalid remote server port: {}", remoteServerPort)
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
}
|
13
src/main/kotlin/net/ipksindia/config/Configuration.kt
Normal file
13
src/main/kotlin/net/ipksindia/config/Configuration.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package net.ipksindia.config
|
||||||
|
|
||||||
|
import io.ktor.server.application.*
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
|
||||||
|
fun Application.configureApplication() {
|
||||||
|
val logger = LoggerFactory.getLogger(AppConfig::class.java)
|
||||||
|
environment.config.propertyOrNull("ktor.environment")?.getString()?.let {
|
||||||
|
logger.info("Application running on environment: $it")
|
||||||
|
}
|
||||||
|
validateAppConfigs()
|
||||||
|
}
|
25
src/main/kotlin/net/ipksindia/dao/DatabaseFactory.kt
Normal file
25
src/main/kotlin/net/ipksindia/dao/DatabaseFactory.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package net.ipksindia.dao
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariConfig
|
||||||
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
|
import net.ipksindia.config.AppConfig
|
||||||
|
import java.sql.Connection
|
||||||
|
|
||||||
|
class DatabaseFactory private constructor() {
|
||||||
|
private val dataSource: HikariDataSource
|
||||||
|
|
||||||
|
init {
|
||||||
|
val config = HikariConfig()
|
||||||
|
config.jdbcUrl = AppConfig.databaseConfig.url
|
||||||
|
config.username = AppConfig.databaseConfig.user
|
||||||
|
config.password = AppConfig.databaseConfig.password
|
||||||
|
config.maximumPoolSize = 5
|
||||||
|
dataSource = HikariDataSource(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getConnection(): Connection = dataSource.connection
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val instance = DatabaseFactory()
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +1,58 @@
|
|||||||
package dao
|
package net.ipksindia.dao
|
||||||
|
|
||||||
import model.Teller
|
import model.Teller
|
||||||
|
import net.ipksindia.ItemNotFoundException
|
||||||
|
|
||||||
class TellerDao {
|
class TellerDao {
|
||||||
companion object {
|
|
||||||
|
|
||||||
private val tellerMap = mapOf(
|
private val tellerMap = mapOf(
|
||||||
"0003" to mapOf(
|
"0003" to mapOf(
|
||||||
"00012" to "312",
|
"00012" to "312",
|
||||||
"00017" to "317",
|
"00017" to "317",
|
||||||
"00013" to "313",
|
"00013" to "313",
|
||||||
"00014" to "314",
|
"00014" to "314",
|
||||||
"00015" to "315",
|
"00015" to "315",
|
||||||
"00016" to "316",
|
"00016" to "316",
|
||||||
"00019" to "319",
|
"00019" to "319",
|
||||||
"00020" to "320",
|
"00020" to "320",
|
||||||
"00026" to "11126",
|
"00026" to "11126",
|
||||||
"00010" to "310"
|
"00010" to "310"
|
||||||
),
|
),
|
||||||
"0015" to mapOf(
|
"0015" to mapOf(
|
||||||
"00006" to "11106",
|
"00006" to "11106",
|
||||||
"00005" to "11105",
|
"00005" to "11105",
|
||||||
"00002" to "11102",
|
"00002" to "11102",
|
||||||
"00004" to "11104",
|
"00004" to "11104",
|
||||||
"00023" to "1234",
|
"00023" to "1234",
|
||||||
"00008" to "11108",
|
"00008" to "11108",
|
||||||
"00017" to "11117",
|
"00017" to "11117",
|
||||||
"00011" to "10111",
|
"00011" to "10111",
|
||||||
"00021" to "1234",
|
"00021" to "1234",
|
||||||
"00001" to "1234",
|
"00001" to "1234",
|
||||||
"00018" to "11118",
|
"00018" to "11118",
|
||||||
"00012" to "11112",
|
"00012" to "11112",
|
||||||
"00019" to "11119",
|
"00019" to "11119",
|
||||||
"00003" to "11103",
|
"00003" to "11103",
|
||||||
"00009" to "11109",
|
"00009" to "11109",
|
||||||
"00015" to "11115",
|
"00015" to "11115",
|
||||||
"00020" to "11120",
|
"00020" to "11120",
|
||||||
"00013" to "11113",
|
"00013" to "11113",
|
||||||
"00014" to "1234",
|
"00014" to "1234",
|
||||||
"00016" to "11116",
|
"00016" to "11116",
|
||||||
"00010" to "11110",
|
"00010" to "11110",
|
||||||
"00007" to "11107",
|
"00007" to "11107",
|
||||||
"00022" to "1234",
|
"00022" to "1234",
|
||||||
"00026" to "11126"
|
"00026" to "11126"
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun getTeller(dccbCode: String, branchCode: String): Teller {
|
||||||
|
val branchList = tellerMap[dccbCode] ?: throw ItemNotFoundException("Branch Code", branchCode)
|
||||||
|
val tellerId = branchList[branchCode] ?: throw ItemNotFoundException("DCCB Code", branchCode)
|
||||||
|
val teller = Teller(
|
||||||
|
tellerId, dccbCode, branchCode
|
||||||
)
|
)
|
||||||
|
return teller
|
||||||
fun getTeller(dccbCode: String, branchCode: String): Teller? {
|
|
||||||
val branchList = tellerMap[dccbCode] ?: return null
|
|
||||||
val tellerId = branchList[branchCode] ?: return null
|
|
||||||
val teller = Teller(
|
|
||||||
tellerId,
|
|
||||||
dccbCode,
|
|
||||||
branchCode
|
|
||||||
)
|
|
||||||
return teller
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,44 +1,12 @@
|
|||||||
package net.ipksindia.dao
|
package net.ipksindia.dao
|
||||||
|
|
||||||
import model.TransactionRequest
|
import model.TransactionRequest
|
||||||
|
import net.ipksindia.ItemNotFoundException
|
||||||
import java.sql.Date
|
import java.sql.Date
|
||||||
import java.sql.DriverManager
|
|
||||||
import java.sql.ResultSet
|
import java.sql.ResultSet
|
||||||
import java.util.*
|
import java.sql.SQLException
|
||||||
|
|
||||||
class TransactionDao {
|
class TransactionDao {
|
||||||
private val transactionRequestQuery = """
|
|
||||||
SELECT
|
|
||||||
txn_no,
|
|
||||||
TRIM(src_ac_no) AS src_ac_no,
|
|
||||||
TRIM(dest_ac_no) AS dest_ac_no,
|
|
||||||
ifsc_code,
|
|
||||||
txn_amt,
|
|
||||||
txn_date,
|
|
||||||
t.teller_id,
|
|
||||||
CASE
|
|
||||||
WHEN t.ifsc_code LIKE 'WBSC%' THEN 'FAILED'
|
|
||||||
ELSE 'RECEIVED'
|
|
||||||
END AS status,
|
|
||||||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(beneficiary_name), '[^A-Z0-9 ]', ''), ' {2,}', ' '), 1, 35) AS beneficiary_name,
|
|
||||||
beneficiary_add,
|
|
||||||
t.pacs_id,
|
|
||||||
comm_txn_no,
|
|
||||||
comm_txn_amt,
|
|
||||||
dccb_code,
|
|
||||||
TO_NUMBER(cbs_br_code) AS br_code,
|
|
||||||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(remm_name), '[^A-Z0-9 ]', ''), ' {2,}', ' '),1,35) AS remitter_name,
|
|
||||||
ipks_accno AS pacs_acc_no,
|
|
||||||
da.link_accno AS cbs_sb_acc_no,
|
|
||||||
'pacs_db' AS db_name
|
|
||||||
FROM neft_rtgs_txn t
|
|
||||||
JOIN dep_account da ON t.ipks_accno = da.key_1
|
|
||||||
WHERE
|
|
||||||
t.txn_date = (SELECT system_date FROM system_date)
|
|
||||||
AND t.STATUS = 'A'
|
|
||||||
AND t.bank_channel = 'SCB'
|
|
||||||
AND da.link_accno IS NOT NULL
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
private val singleTransactionRequestQuery = """
|
private val singleTransactionRequestQuery = """
|
||||||
SELECT
|
SELECT
|
||||||
@ -97,120 +65,73 @@ class TransactionDao {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
fun updateSuccessTransaction(request: TransactionRequest, transferQueueNumber: String, neftQueueNumber: String) {
|
fun updateSuccessTransaction(request: TransactionRequest, transferQueueNumber: String, neftQueueNumber: String) {
|
||||||
val dbUrl = getDatabaseUrl()
|
try {
|
||||||
val (dbUser, dbPassword) = getUserCredentials()
|
DatabaseFactory.instance.getConnection().use { connection ->
|
||||||
|
connection.prepareStatement(transactionUpdateQuery).also {
|
||||||
DriverManager.getConnection(dbUrl, dbUser, dbPassword).use { connection ->
|
it.setString(1, request.transactionNumber)
|
||||||
connection.prepareStatement(transactionUpdateQuery).also {
|
it.setString(2, request.pacsCurrentAccountNumber)
|
||||||
it.setString(1, request.transactionNumber)
|
it.setString(3, request.neftBeneficiaryAccountNumber)
|
||||||
it.setString(2, request.pacsCurrentAccountNumber)
|
it.setString(4, request.ifscCode)
|
||||||
it.setString(3, request.neftBeneficiaryAccountNumber)
|
it.setString(5, request.amount)
|
||||||
it.setString(4, request.ifscCode)
|
it.setDate(6, Date.valueOf(request.date))
|
||||||
it.setString(5, request.amount)
|
it.setString(7, request.tellerId)
|
||||||
it.setDate(6, Date.valueOf(request.date))
|
it.setString(8, "PROCESSED")
|
||||||
it.setString(7, request.tellerId)
|
it.setString(9, request.beneficiaryName)
|
||||||
it.setString(8, "PROCESSED")
|
it.setString(10, request.beneficiaryAddress)
|
||||||
it.setString(9, request.beneficiaryName)
|
it.setString(11, request.pacsId)
|
||||||
it.setString(10, request.beneficiaryAddress)
|
it.setString(12, request.commissionTransactionNumber)
|
||||||
it.setString(11, request.pacsId)
|
it.setString(13, request.commissionAmount)
|
||||||
it.setString(12, request.commissionTransactionNumber)
|
it.setString(14, request.dccbCode)
|
||||||
it.setString(13, request.commissionAmount)
|
it.setString(15, request.branchCode)
|
||||||
it.setString(14, request.dccbCode)
|
it.setString(16, request.remitterName)
|
||||||
it.setString(15, request.branchCode)
|
it.setString(17, transferQueueNumber)
|
||||||
it.setString(16, request.remitterName)
|
it.setString(18, request.pacsAccountNumber)
|
||||||
it.setString(17, transferQueueNumber)
|
it.setString(19, neftQueueNumber)
|
||||||
it.setString(18, request.pacsAccountNumber)
|
}.use { it.executeUpdate() }
|
||||||
it.setString(19, neftQueueNumber)
|
|
||||||
}.use {
|
|
||||||
it.executeUpdate()
|
|
||||||
}
|
}
|
||||||
|
}catch (e: ExceptionInInitializerError) {
|
||||||
|
throw SQLException("Failed to connect to the database")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun getTransactionRequests(): List<TransactionRequest> {
|
|
||||||
|
|
||||||
val transactionList: List<TransactionRequest>
|
fun getTransactionRequest(transactionNumber: String): TransactionRequest {
|
||||||
val dbUrl = getDatabaseUrl()
|
return try {
|
||||||
val (dbUser, dbPassword) = getUserCredentials()
|
DatabaseFactory.instance.getConnection().use { connection ->
|
||||||
|
connection.prepareStatement(singleTransactionRequestQuery).apply { setString(1, transactionNumber) }
|
||||||
DriverManager.getConnection(dbUrl, dbUser, dbPassword).use { connection ->
|
.executeQuery()
|
||||||
connection.prepareStatement(transactionRequestQuery).executeQuery().use {
|
.use { mapToObject(it) ?: throw ItemNotFoundException("Transaction Number", transactionNumber) }
|
||||||
transactionList = mapToObject(it)
|
}
|
||||||
}
|
} catch (e: ExceptionInInitializerError) {
|
||||||
}
|
throw SQLException("Failed to connect to the database")
|
||||||
|
|
||||||
return transactionList
|
|
||||||
}
|
|
||||||
fun getTransactionRequest(transactionNumber: String): TransactionRequest? {
|
|
||||||
val dbUrl = getDatabaseUrl()
|
|
||||||
val (dbUser, dbPassword) = getUserCredentials()
|
|
||||||
|
|
||||||
return DriverManager.getConnection(dbUrl, dbUser, dbPassword).use { connection ->
|
|
||||||
connection.prepareStatement(singleTransactionRequestQuery).apply {
|
|
||||||
setString(1, transactionNumber)
|
|
||||||
}.executeQuery().use {
|
|
||||||
mapToObject(it).firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun getDatabaseUrl(): String {
|
}
|
||||||
val prop = loadProp()
|
|
||||||
|
|
||||||
val dbHost = getProp(prop, "DB_HOST")
|
|
||||||
val dbPort = getProp(prop, "DB_PORT")
|
|
||||||
val dbName = getProp(prop, "DB_NAME")
|
|
||||||
|
|
||||||
return "jdbc:oracle:thin:@$dbHost:$dbPort:$dbName"
|
private fun mapToObject(rs: ResultSet): TransactionRequest? {
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
return TransactionRequest(
|
||||||
|
transactionNumber = rs.getString("txn_no"),
|
||||||
|
pacsCurrentAccountNumber = rs.getString("src_ac_no"),
|
||||||
|
neftBeneficiaryAccountNumber = rs.getString("dest_ac_no"),
|
||||||
|
ifscCode = rs.getString("ifsc_code"),
|
||||||
|
amount = rs.getString("txn_amt"),
|
||||||
|
date = rs.getDate("txn_date").toLocalDate(),
|
||||||
|
tellerId = rs.getString("teller_id"),
|
||||||
|
status = rs.getString("status"),
|
||||||
|
beneficiaryName = rs.getString("beneficiary_name"),
|
||||||
|
beneficiaryAddress = rs.getString("beneficiary_add"),
|
||||||
|
pacsId = rs.getString("pacs_id"),
|
||||||
|
commissionTransactionNumber = rs.getString("comm_txn_no"),
|
||||||
|
commissionAmount = rs.getString("comm_txn_amt"),
|
||||||
|
dccbCode = rs.getString("dccb_code"),
|
||||||
|
branchCode = rs.getString("br_Code"),
|
||||||
|
remitterName = rs.getString("remitter_name"),
|
||||||
|
pacsAccountNumber = rs.getString("pacs_acc_no"),
|
||||||
|
linkedCBSAccountNumber = rs.getString("cbs_sb_acc_no"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun getUserCredentials(): Pair<String, String> {
|
|
||||||
val prop = loadProp()
|
|
||||||
|
|
||||||
val dbUser = getProp(prop, "DB_USER")
|
|
||||||
val dbPassword = getProp(prop, "DB_PASSWORD")
|
|
||||||
|
|
||||||
return Pair(dbUser, dbPassword)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadProp(): Properties {
|
|
||||||
|
|
||||||
val props = javaClass.classLoader.getResourceAsStream("application.properties").use {
|
|
||||||
Properties().apply { load(it) }
|
|
||||||
}
|
|
||||||
return props
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getProp(prop: Properties, key: String): String {
|
|
||||||
return prop.getProperty(key) ?: throw RuntimeException("property $prop not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mapToObject(rs: ResultSet): List<TransactionRequest> {
|
|
||||||
val list = mutableListOf<TransactionRequest>()
|
|
||||||
while (rs.next()) {
|
|
||||||
val transactionRequest = TransactionRequest(
|
|
||||||
transactionNumber = rs.getString("txn_no"),
|
|
||||||
pacsCurrentAccountNumber = rs.getString("src_ac_no"),
|
|
||||||
neftBeneficiaryAccountNumber = rs.getString("dest_ac_no"),
|
|
||||||
ifscCode = rs.getString("ifsc_code"),
|
|
||||||
amount = rs.getString("txn_amt"),
|
|
||||||
date = rs.getDate("txn_date").toLocalDate(),
|
|
||||||
tellerId = rs.getString("teller_id"),
|
|
||||||
status = rs.getString("status"),
|
|
||||||
beneficiaryName = rs.getString("beneficiary_name"),
|
|
||||||
beneficiaryAddress = rs.getString("beneficiary_add"),
|
|
||||||
pacsId = rs.getString("pacs_id"),
|
|
||||||
commissionTransactionNumber = rs.getString("comm_txn_no"),
|
|
||||||
commissionAmount = rs.getString("comm_txn_amt"),
|
|
||||||
dccbCode = rs.getString("dccb_code"),
|
|
||||||
branchCode = rs.getString("br_Code"),
|
|
||||||
remitterName = rs.getString("remitter_name"),
|
|
||||||
pacsAccountNumber = rs.getString("pacs_acc_no"),
|
|
||||||
linkedCBSAccountNumber = rs.getString("cbs_sb_acc_no"),
|
|
||||||
)
|
|
||||||
list.add(transactionRequest)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
11
src/main/kotlin/net/ipksindia/model/OutwardNeftResponse.kt
Normal file
11
src/main/kotlin/net/ipksindia/model/OutwardNeftResponse.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package net.ipksindia.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class OutwardNeftResponse(
|
||||||
|
val status: Int,
|
||||||
|
val message: String,
|
||||||
|
val transferQueueNumber: String?,
|
||||||
|
val neftQueueNumber: String?
|
||||||
|
)
|
@ -13,8 +13,8 @@ fun Application.configureRouting() {
|
|||||||
post {
|
post {
|
||||||
val neftRequest = call.receive<OutwardNeftRequest>()
|
val neftRequest = call.receive<OutwardNeftRequest>()
|
||||||
val transactionNumber = neftRequest.transactionNumber
|
val transactionNumber = neftRequest.transactionNumber
|
||||||
val response = NeftRequestProcessor.process(transactionNumber) ?: Pair("500", "Error doing outward neft" )
|
val response = NeftRequestProcessor.process(transactionNumber)
|
||||||
call.respond("${response.first}\n${response.second}")
|
call.respond(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,16 +3,9 @@ package net.ipksindia.plugins
|
|||||||
import io.ktor.serialization.kotlinx.json.*
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.plugins.contentnegotiation.*
|
import io.ktor.server.plugins.contentnegotiation.*
|
||||||
import io.ktor.server.response.*
|
|
||||||
import io.ktor.server.routing.*
|
|
||||||
|
|
||||||
fun Application.configureSerialization() {
|
fun Application.configureSerialization() {
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json()
|
json()
|
||||||
}
|
}
|
||||||
routing {
|
|
||||||
get("/json/kotlinx-serialization") {
|
|
||||||
call.respond(mapOf("hello" to "world"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
18
src/main/resources/application-dev.conf
Normal file
18
src/main/resources/application-dev.conf
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
database {
|
||||||
|
host = "localhost"
|
||||||
|
port = 1521
|
||||||
|
name = "IPKSDB"
|
||||||
|
user = "pacs_db"
|
||||||
|
password = "pacs_db"
|
||||||
|
}
|
||||||
|
|
||||||
|
bank {
|
||||||
|
server {
|
||||||
|
protocol = "http"
|
||||||
|
host = "localhost"
|
||||||
|
port = 8080
|
||||||
|
rootRoute = "IPKS_Queue_Generation"
|
||||||
|
transactionRoute = "IpksApi"
|
||||||
|
}
|
||||||
|
codes = ["0003", "0015"]
|
||||||
|
}
|
17
src/main/resources/application-prod.conf
Normal file
17
src/main/resources/application-prod.conf
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
database {
|
||||||
|
host = "ipksprod3.c7q7defafeea.ap-south-1.rds.amazonaws.com"
|
||||||
|
port = 1521
|
||||||
|
name = "IPKS"
|
||||||
|
user = ${DB_USER}
|
||||||
|
password = ${DB_PASSWORD}
|
||||||
|
}
|
||||||
|
|
||||||
|
bank {
|
||||||
|
server {
|
||||||
|
protocol = "https"
|
||||||
|
host = "180.179.110.185"
|
||||||
|
port = 443
|
||||||
|
rootRoute = "IPKS_Queue_Generation"
|
||||||
|
transactionRoute = "IpksApi"
|
||||||
|
}
|
||||||
|
}
|
10
src/main/resources/application.conf
Normal file
10
src/main/resources/application.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
ktor {
|
||||||
|
environment = ${KTOR_ENV}
|
||||||
|
deployment {
|
||||||
|
port = 8083
|
||||||
|
watch = [ classes ]
|
||||||
|
}
|
||||||
|
application {
|
||||||
|
modules = [ net.ipksindia.ApplicationKt.module ]
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
DB_NAME=IPKS
|
|
||||||
#DB_HOST=testipksdb.c7q7defafeea.ap-south-1.rds.amazonaws.com
|
|
||||||
#DB_HOST=localhost
|
|
||||||
DB_HOST=ipksprod3.c7q7defafeea.ap-south-1.rds.amazonaws.com
|
|
||||||
DB_PORT=1521
|
|
||||||
DB_USER=pacs_db
|
|
||||||
DB_PASSWORD=pacs_db
|
|
@ -23,8 +23,7 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- <logger name="org.eclipse.jetty" level="WARN"/>-->
|
<logger name="io.netty" level="WARN"/>
|
||||||
<!-- <logger name="io.netty" level="WARN"/>-->
|
|
||||||
<logger name="net.ipksindia" level="DEBUG" additivity="false">
|
<logger name="net.ipksindia" level="DEBUG" additivity="false">
|
||||||
<appender-ref ref="FILE-ROLLING"/>
|
<appender-ref ref="FILE-ROLLING"/>
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package net.ipksindia
|
|
||||||
|
|
||||||
import io.ktor.client.request.*
|
|
||||||
import io.ktor.client.statement.*
|
|
||||||
import io.ktor.http.*
|
|
||||||
import io.ktor.server.testing.*
|
|
||||||
import kotlin.test.*
|
|
||||||
import net.ipksindia.plugins.*
|
|
||||||
|
|
||||||
class ApplicationTest {
|
|
||||||
@Test
|
|
||||||
fun testRoot() = testApplication {
|
|
||||||
application {
|
|
||||||
configureRouting()
|
|
||||||
}
|
|
||||||
client.get("/").apply {
|
|
||||||
assertEquals(HttpStatusCode.OK, status)
|
|
||||||
assertEquals("Hello World!", bodyAsText())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user