ready for prod

This commit is contained in:
Md Asif 2024-09-19 00:53:02 +05:30
parent dfa85ede7e
commit 66dde20601
14 changed files with 152 additions and 107 deletions

View File

@ -6,7 +6,7 @@ import io.ktor.server.netty.*
import net.ipksindia.plugins.*
fun main() {
embeddedServer(Netty, port = 8088, host = "0.0.0.0", module = Application::module)
embeddedServer(Netty, port = 8082, host = "0.0.0.0", module = Application::module)
.start(wait = true)
}

View File

@ -1,20 +1,22 @@
package net.ipksindia
import TransactionExecutor
import TransactionFactory
import dao.TellerDao
import net.ipksindia.dao.TransactionDao
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import redis.clients.jedis.JedisPooled
import response.TransactionFailureResponse
import response.TransactionSuccessResponse
class NeftRequestProcessor {
companion object {
private val logger: Logger = LoggerFactory.getLogger(NeftRequestProcessor::class.java)
private const val PROCESSED_TRANSACTION_LIST = "ipks:processed_outward_transactions"
private val migratedDCCBCodes = listOf("0012")
private val migratedDCCBCodes = listOf("0003","0015", "0016")
val bankDccbToSftpMap = mutableMapOf<String, String>(
"0015" to "0005", //Tamluk
"0003" to "0021", //Balageria
"0016" to "0001", //WBSCB
)
fun process(transactionNumber: String): Pair<String, String>? {
@ -23,18 +25,16 @@ class NeftRequestProcessor {
return null
}
logger.info("TXN: #{} FOUND", transactionNumber)
val jedis = JedisPooled("localhost", 6379)
val processedTransactionList = jedis.smembers(PROCESSED_TRANSACTION_LIST)
val dccbCode = outwardTransaction.dccbCode.padStart(4, '0')
val branchCode = outwardTransaction.branchCode.padStart(5, '0')
if(dccbCode !in migratedDCCBCodes) {
logger.error("TXN: #{} FAILED REASON: DCCB Code not migrated", transactionNumber)
return null
}
val branchCode = outwardTransaction.branchCode.padStart(3, '0')
if (transactionNumber in processedTransactionList) {
logger.error("TXN: #{} FAILED REASON: Transaction already processed", transactionNumber)
return null
}
val makerTeller = TellerDao.getTeller(dccbCode, branchCode) ?: run {
logger.error("TXN: #{} FAILED REASON: Teller not found", transactionNumber)
return null
@ -54,11 +54,9 @@ class NeftRequestProcessor {
neftResponse.status
)
jedis.sadd(PROCESSED_TRANSACTION_LIST, outwardTransaction.transactionNumber)
if (transferResponse.status == "SUCCESS" && neftResponse.status == "SUCCESS") {
val transferQueueNumber = (transferResponse as TransactionSuccessResponse).response.queueId
val neftQueueNumber = (neftResponse as TransactionSuccessResponse).response.queueId
val transferQueueNumber = (transferResponse as TransactionSuccessResponse).queueNumber
val neftQueueNumber = (neftResponse as TransactionSuccessResponse).queueNumber
try {
TransactionDao().updateSuccessTransaction(outwardTransaction, transferQueueNumber, neftQueueNumber)
logger.info("TXN: #{} UPDATED RESULTS SUCCESSFULLY", transactionNumber)
@ -69,12 +67,22 @@ class NeftRequestProcessor {
e.message
)
}
return Pair(transferQueueNumber, neftQueueNumber)
} else {
logger.error("TXN: #{} QUEUE INITIATED BUT FAILED TO UPDATE RESULT", transactionNumber)
val transferErrorMsg = (transferResponse as TransactionFailureResponse).errorMsg
val neftErrorMsg = (neftResponse as TransactionFailureResponse).errorMsg
logger.error(
"TXN: #{} TRANSFER TXN FAILED DUE TO: {}",
transactionNumber,
transferErrorMsg
)
logger.error(
"TXN: #{} NEFT TXN FAILED DUE TO: {}",
transactionNumber,
neftErrorMsg
)
}
return null
}
}
}
}

View File

@ -1,24 +1,27 @@
package net.ipksindia
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import model.NeftTransaction
import model.TransferTransaction
import net.ipksindia.model.NeftTransaction
import net.ipksindia.model.TransferTransaction
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONException
import org.json.JSONObject
import response.TransactionFailureResponse
import response.TransactionResponse
import response.TransactionSuccessResponse
import java.io.IOException
import javax.net.ssl.HostnameVerifier
class TransactionExecutor() {
private val protocol = "http"
private val host = "localhost"
private val port = "8080"
private val rootRoute = "WESTBANGAL/api"
private val protocol = "https"
private val host = "180.179.119.227"
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> {
@ -31,13 +34,18 @@ class TransactionExecutor() {
}
private fun execute(postBody: String): TransactionResponse {
val transferRoute = "IPKSNeftRtgsApiTransfer"
val transferRoute = "Ipks"
val transferURL = "$remoteUrl/$transferRoute"
val jsonMediaType = "application/json; charset=utf-8".toMediaType()
val httpClient = OkHttpClient()
val httpClient = OkHttpClient
.Builder()
.hostnameVerifier(HostnameVerifier { _, _ -> true })
.build()
val request = Request.Builder()
val request = Request
.Builder()
.url(transferURL)
.post(postBody.toRequestBody(jsonMediaType))
.build()
@ -49,10 +57,17 @@ class TransactionExecutor() {
response.body!!.string()
}
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")) {
Json.decodeFromString<TransactionSuccessResponse>(responseBody)
val queueNo = try { responseObj.getJSONObject("response").getString("QueueId") } catch(_: JSONException) { "" }
return TransactionSuccessResponse(status, message, queueNo, error)
} else {
Json.decodeFromString<TransactionFailureResponse>(responseBody)
val errorMsg = try { responseObj.getJSONObject("response").getString("errorMsg") } catch(_: JSONException) { "no error message provided" }
return TransactionFailureResponse(status, message, errorMsg, error)
}
return response
}

View File

@ -1,9 +1,11 @@
package net.ipksindia
import enums.TransactionType
import model.NeftTransaction
import net.ipksindia.model.NeftTransaction
import model.Teller
import model.TransactionRequest
import model.TransferTransaction
import net.ipksindia.model.TransferTransaction
import net.ipksindia.NeftRequestProcessor.Companion.bankDccbToSftpMap
import java.time.format.DateTimeFormatter
class TransactionFactory(private val transactionRequest: TransactionRequest, private val teller: Teller) {
@ -13,10 +15,10 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
private fun createTransferTransaction(): TransferTransaction {
return TransferTransaction(
bankCode = transactionRequest.dccbCode.padStart(4, '0'),
bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')]!!,
branchCode = transactionRequest.branchCode.padStart(3,'0'),
cbsTellerId = teller.tellerId,
cbsTellerUserIdType = teller.userType,
cbsTellerUserType = teller.userType,
queIdType = "5",
description = "${TransactionType.TRANSFER.code}For Checking",
priority = "1",
@ -25,12 +27,14 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
txnAmt = transactionRequest.amount,
txnDate = date,
sourceAcctNo = transactionRequest.pacsCurrentAccountNumber,
cbsSbAcctNo = "",
destinationAcctNo = transactionRequest.linkedCBSAccountNumber,
narration = "TRF to member A/C for NEFT RTGS",
sourceTxnNo = "1045",
sourceTxnNo = TransactionType.TRANSFER.code,
sourceStat = "A/P",
apiType = "OUTWARD_QUEUE_POSTING",
remitterName = transactionRequest.remitterName,
ifscCode = "ABCD0000000",
rrn = rrn + "1"
)
@ -38,10 +42,10 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
private fun createNEFTTransaction(): NeftTransaction {
return NeftTransaction(
bankCode = transactionRequest.dccbCode,
bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')]!!,
branchCode = transactionRequest.branchCode.padStart(3,'0'),
cbsTellerId = teller.tellerId,
cbsTellerUserIdType = teller.userType,
cbsTellerUserType = teller.userType,
queIdType = "5",
description = "${TransactionType.NEFT.code}For Checking",
priority = "1",
@ -50,6 +54,7 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
txnAmt = transactionRequest.amount,
txnDate = date,
sourceAcctNo = transactionRequest.linkedCBSAccountNumber,
cbsSbAcctNo = "",
destinationAcctNo = transactionRequest.neftBeneficiaryAccountNumber,
narration = "TRF to member A/C for NEFT RTGS",
sourceTxnNo = TransactionType.NEFT.code,

View File

@ -4,37 +4,42 @@ import model.Teller
class TellerDao {
companion object {
private val tellerMap = mapOf(
"0016" to mapOf(
"008" to "118"
),
"0012" to mapOf(
"008" to "8",
"022" to "22",
"012" to "12",
"014" to "14",
"003" to "1003",
"015" to "15",
"013" to "13",
"018" to "18",
"001" to "1001",
"004" to "4",
"017" to "1234",
"005" to "5",
"011" to "11",
"020" to "1234",
"021" to "1234",
"016" to "016",
"009" to "9",
"010" to "10",
"007" to "7",
"006" to "6"
)
private val tellerMap = mapOf(
"0003" to mapOf(
"00008" to "8",
"00022" to "22",
"00012" to "12",
"00014" to "14",
"00003" to "1003",
"00015" to "15",
"00013" to "13",
"00018" to "18",
"00001" to "1001",
"00004" to "4",
"00017" to "1234",
"00005" to "5",
"00011" to "11",
"00020" to "1234",
"00021" to "1234",
"00016" to "016",
"00009" to "9",
"00010" to "10",
"00007" to "7",
"00006" to "6",
),
"0015" to mapOf(
"00008" to "118",
"00002" to "249",
),
"0016" to mapOf(
"00001" to "249",
"00002" to "249"
)
)
fun getTeller(dccbCode: String, branchCode: String): Teller? {
val branchList = tellerMap[dccbCode] ?: return null
val tellerId = branchList[branchCode] ?: return null
val tellerId = branchList[branchCode] ?: "249"
val teller = Teller(
tellerId,
dccbCode,

View File

@ -1,7 +1,6 @@
package model
package net.ipksindia.model
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.ipks.model.Transaction
@Serializable
@ -9,7 +8,7 @@ class NeftTransaction(
override val bankCode: String,
override val branchCode: String,
override val cbsTellerId: String,
override val cbsTellerUserIdType: String,
override val cbsTellerUserType: String,
override val queIdType: String,
override val description: String,
override val priority: String,
@ -18,13 +17,13 @@ class NeftTransaction(
override val txnAmt: String,
override val txnDate: String,
override val sourceAcctNo: String,
override val cbsSbAcctNo: String,
override val destinationAcctNo: String,
override val narration: String,
override val sourceTxnNo: String,
override val sourceStat: String,
override val apiType: String,
override val remitterName: String,
val ifscCode: String,
override val ifscCode: String,
override val rrn: String,
@Transient override var queueNo: String = ""
) : Transaction

View File

@ -4,7 +4,7 @@ interface Transaction {
val bankCode: String
val branchCode: String
val cbsTellerId: String
val cbsTellerUserIdType: String
val cbsTellerUserType: String
val queIdType: String
val description: String
val priority: String
@ -13,12 +13,13 @@ interface Transaction {
val txnAmt: String
val txnDate: String
val sourceAcctNo: String
val cbsSbAcctNo: String
val destinationAcctNo: String
val narration: String
val sourceTxnNo: String
val sourceStat: String
val apiType: String
val remitterName: String
val ifscCode: String
val rrn: String
val queueNo: String?
}

View File

@ -1,7 +1,6 @@
package model
package net.ipksindia.model
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.ipks.model.Transaction
@Serializable
@ -9,7 +8,7 @@ class TransferTransaction(
override val bankCode: String,
override val branchCode: String,
override val cbsTellerId: String,
override val cbsTellerUserIdType: String,
override val cbsTellerUserType: String,
override val queIdType: String,
override val description: String,
override val priority: String,
@ -18,12 +17,13 @@ class TransferTransaction(
override val txnAmt: String,
override val txnDate: String,
override val sourceAcctNo: String,
override val cbsSbAcctNo: String,
override val destinationAcctNo: String,
override val narration: String,
override val sourceTxnNo: String,
override val sourceStat: String,
override val apiType: String,
override val remitterName: String,
override val ifscCode: String,
override val rrn: String,
@Transient override var queueNo: String = ""
) : Transaction

View File

@ -9,11 +9,14 @@ import net.ipksindia.model.OutwardNeftRequest
fun Application.configureRouting() {
routing {
post("/neftOutward") {
route("/neftOutward") {
post {
val neftRequest = call.receive<OutwardNeftRequest>()
val transactionNumber = neftRequest.transactionNumber
val response = NeftRequestProcessor.process(transactionNumber) ?: Pair("500", "Error doing outward neft" )
call.respond("${response.first}\n${response.second}")
}
}
}
}

View File

@ -1,16 +0,0 @@
package response
import kotlinx.serialization.Serializable
@Serializable
data class ResponseData (
val transactionDate: Int,
val sourceStat: String,
val journalId: Int,
val queueId: String,
val error: Int,
val apiType: String,
val errorMsg: String,
val txnScreenNo: Int
)

View File

@ -7,6 +7,6 @@ import kotlinx.serialization.Serializable
data class TransactionFailureResponse(
override val status: String,
override val message: String,
val response: String,
val errorMsg: String,
override val error: Int
): TransactionResponse

View File

@ -6,6 +6,6 @@ import kotlinx.serialization.Serializable
data class TransactionSuccessResponse(
override val status: String,
override val message: String,
val response: ResponseData,
val queueNumber: String,
override val error: Int
): TransactionResponse

View File

@ -1,5 +1,6 @@
DB_NAME=IPKSDB
DB_HOST=localhost
DB_HOST=testipksdb.c7q7defafeea.ap-south-1.rds.amazonaws.com
#DB_HOST=localhost
DB_PORT=1521
DB_USER=pacs_db
DB_PASSWORD=pacs_db

View File

@ -1,12 +1,36 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<property name="LOG_PATH" value="./logs" />
<property name="LOG_ARCHIVE" value="${LOG_PATH}/archive" />
<!-- file appender -->
<appender name="FILE-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender" >
<file>${LOG_PATH}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_ARCHIVE}/application.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<!-- console appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- <logger name="org.eclipse.jetty" level="WARN"/>-->
<!-- <logger name="io.netty" level="WARN"/>-->
<logger name="net.ipksindia" level="DEBUG" additivity="false">
<appender-ref ref="FILE-ROLLING"/>
<appender-ref ref="STDOUT" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.netty" level="INFO"/>
</configuration>