Resolve pincode from local DB before external fallbacks
All checks were successful
build-and-deploy / build-deploy (push) Successful in 36s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 36s
This commit is contained in:
@@ -639,6 +639,13 @@ class DocumentExtractionService(
|
|||||||
tertiary.errorMessage?.let { results["geoTertiaryError"] = it.take(300) }
|
tertiary.errorMessage?.let { results["geoTertiaryError"] = it.take(300) }
|
||||||
tertiary.requestUrl?.let { results["geoTertiaryUrl"] = it.take(500) }
|
tertiary.requestUrl?.let { results["geoTertiaryUrl"] = it.take(500) }
|
||||||
}
|
}
|
||||||
|
resolvedResult.quaternary?.let { quaternary ->
|
||||||
|
results["geoQuaternarySource"] = quaternary.source
|
||||||
|
quaternary.status?.let { results["geoQuaternaryStatus"] = it }
|
||||||
|
quaternary.rawResponse?.let { results["geoQuaternaryResponse"] = it.take(4000) }
|
||||||
|
quaternary.errorMessage?.let { results["geoQuaternaryError"] = it.take(300) }
|
||||||
|
quaternary.requestUrl?.let { results["geoQuaternaryUrl"] = it.take(500) }
|
||||||
|
}
|
||||||
val resolved = resolvedResult.resolved()?.resolvedCityState ?: return
|
val resolved = resolvedResult.resolved()?.resolvedCityState ?: return
|
||||||
results["geoResolved"] = resolved
|
results["geoResolved"] = resolved
|
||||||
results["geoSource"] = resolvedResult.resolved()?.source ?: ""
|
results["geoSource"] = resolvedResult.resolved()?.source ?: ""
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package com.android.trisolarisserver.component.geo
|
||||||
|
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class LocalPincodeDirectoryClient(
|
||||||
|
private val jdbcTemplate: JdbcTemplate
|
||||||
|
) {
|
||||||
|
private val logger = LoggerFactory.getLogger(LocalPincodeDirectoryClient::class.java)
|
||||||
|
|
||||||
|
fun resolve(pinCode: String): PincodeLookupResult {
|
||||||
|
val normalizedPin = pinCode.trim()
|
||||||
|
if (!PIN_REGEX.matches(normalizedPin)) {
|
||||||
|
return PincodeLookupResult(
|
||||||
|
resolvedCityState = null,
|
||||||
|
rawResponse = null,
|
||||||
|
status = "INVALID_PIN",
|
||||||
|
source = "local-db",
|
||||||
|
errorMessage = "PIN must be 6 digits"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
val rows = jdbcTemplate.query(
|
||||||
|
"""
|
||||||
|
select city, state
|
||||||
|
from india_pincode_city_state
|
||||||
|
where pincode = ?
|
||||||
|
and nullif(trim(city), '') is not null
|
||||||
|
and nullif(trim(state), '') is not null
|
||||||
|
group by city, state
|
||||||
|
order by count(*) desc, city asc, state asc
|
||||||
|
limit 1
|
||||||
|
""".trimIndent(),
|
||||||
|
{ rs, _ ->
|
||||||
|
val city = rs.getString("city")?.trim()?.ifBlank { null }
|
||||||
|
val state = rs.getString("state")?.trim()?.ifBlank { null }
|
||||||
|
if (city == null || state == null) null else "$city, $state"
|
||||||
|
},
|
||||||
|
normalizedPin.toInt()
|
||||||
|
).filterNotNull()
|
||||||
|
|
||||||
|
val resolved = rows.firstOrNull()
|
||||||
|
if (resolved != null) {
|
||||||
|
PincodeLookupResult(
|
||||||
|
resolvedCityState = resolved,
|
||||||
|
rawResponse = null,
|
||||||
|
status = "OK",
|
||||||
|
source = "local-db"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PincodeLookupResult(
|
||||||
|
resolvedCityState = null,
|
||||||
|
rawResponse = null,
|
||||||
|
status = "ZERO_RESULTS",
|
||||||
|
source = "local-db"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
logger.warn("Local pincode lookup failed: {}", ex.message)
|
||||||
|
PincodeLookupResult(
|
||||||
|
resolvedCityState = null,
|
||||||
|
rawResponse = null,
|
||||||
|
status = "ERROR",
|
||||||
|
source = "local-db",
|
||||||
|
errorMessage = ex.message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val PIN_REGEX = Regex("\\d{6}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,38 +4,45 @@ import org.springframework.stereotype.Component
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
class PincodeResolver(
|
class PincodeResolver(
|
||||||
|
private val localPincodeDirectoryClient: LocalPincodeDirectoryClient,
|
||||||
private val dataGovPincodeClient: DataGovPincodeClient,
|
private val dataGovPincodeClient: DataGovPincodeClient,
|
||||||
private val postalPincodeClient: PostalPincodeClient,
|
private val postalPincodeClient: PostalPincodeClient,
|
||||||
private val googleGeocodingClient: GoogleGeocodingClient
|
private val googleGeocodingClient: GoogleGeocodingClient
|
||||||
) {
|
) {
|
||||||
fun resolve(pinCode: String): PincodeResolveResult {
|
fun resolve(pinCode: String): PincodeResolveResult {
|
||||||
val primary = dataGovPincodeClient.resolve(pinCode)
|
val primary = localPincodeDirectoryClient.resolve(pinCode)
|
||||||
if (primary.status == "OK" && primary.resolvedCityState != null) {
|
if (primary.status == "OK" && primary.resolvedCityState != null) {
|
||||||
return PincodeResolveResult(primary, null, null)
|
return PincodeResolveResult(primary, null, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val secondary = postalPincodeClient.resolve(pinCode)
|
val secondary = dataGovPincodeClient.resolve(pinCode)
|
||||||
if (secondary.status == "OK" && secondary.resolvedCityState != null) {
|
if (secondary.status == "OK" && secondary.resolvedCityState != null) {
|
||||||
return PincodeResolveResult(primary, secondary, null)
|
return PincodeResolveResult(primary, secondary, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tertiary = postalPincodeClient.resolve(pinCode)
|
||||||
|
if (tertiary.status == "OK" && tertiary.resolvedCityState != null) {
|
||||||
|
return PincodeResolveResult(primary, secondary, tertiary, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val google = googleGeocodingClient.resolveCityState(pinCode)
|
val google = googleGeocodingClient.resolveCityState(pinCode)
|
||||||
val tertiary = PincodeLookupResult(
|
val quaternary = PincodeLookupResult(
|
||||||
google.resolvedCityState,
|
google.resolvedCityState,
|
||||||
google.rawResponse,
|
google.rawResponse,
|
||||||
google.status,
|
google.status,
|
||||||
"google"
|
"google"
|
||||||
)
|
)
|
||||||
return PincodeResolveResult(primary, secondary, tertiary)
|
return PincodeResolveResult(primary, secondary, tertiary, quaternary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PincodeResolveResult(
|
data class PincodeResolveResult(
|
||||||
val primary: PincodeLookupResult,
|
val primary: PincodeLookupResult,
|
||||||
val secondary: PincodeLookupResult?,
|
val secondary: PincodeLookupResult?,
|
||||||
val tertiary: PincodeLookupResult?
|
val tertiary: PincodeLookupResult?,
|
||||||
|
val quaternary: PincodeLookupResult?
|
||||||
) {
|
) {
|
||||||
fun resolved(): PincodeLookupResult? {
|
fun resolved(): PincodeLookupResult? {
|
||||||
return sequenceOf(primary, secondary, tertiary).firstOrNull { it?.resolvedCityState != null }
|
return sequenceOf(primary, secondary, tertiary, quaternary).firstOrNull { it?.resolvedCityState != null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user