mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 11:06:49 +00:00
feature/stored_procedure_connector implemented stored procedure connector.
This commit is contained in:
parent
8a192a96b3
commit
d1f0edc835
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ obp-api/src/main/scripts/kafka/logs/
|
||||
obp-api/src/main/scripts/kafka/tmp/
|
||||
/obp-commons/src/main/resources/git.properties
|
||||
/obp-api2/
|
||||
/.java-version
|
||||
|
||||
@ -103,12 +103,12 @@
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>6.0.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>6.2.0.jre8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
@ -421,6 +421,26 @@
|
||||
<version>2.10.4</version>
|
||||
</dependency>
|
||||
<!-- grpc related end-->
|
||||
|
||||
<!-- scalikejdbc for call stored procedure start-->
|
||||
<dependency>
|
||||
<groupId>org.scalikejdbc</groupId>
|
||||
<artifactId>scalikejdbc_${scala.version}</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalikejdbc</groupId>
|
||||
<artifactId>scalikejdbc-config_${scala.version}</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>8.1.0.jre${java.version}-preview</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- scalikejdbc for call stored procedure end-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -15,6 +15,7 @@ import code.api.v2_1_0._
|
||||
import code.atms.Atms
|
||||
import code.bankconnectors.akka.AkkaConnector_vDec2018
|
||||
import code.bankconnectors.rest.RestConnector_vMar2019
|
||||
import code.bankconnectors.storedprocedure.MsStoredProcedureConnector_vDec2019
|
||||
import code.bankconnectors.vJune2017.KafkaMappedConnector_vJune2017
|
||||
import code.bankconnectors.vMar2017.KafkaMappedConnector_vMar2017
|
||||
import code.bankconnectors.vMay2019.KafkaMappedConnector_vMay2019
|
||||
@ -80,6 +81,7 @@ object Connector extends SimpleInjector {
|
||||
case "kafka_vSept2018" => KafkaMappedConnector_vSept2018
|
||||
case "kafka_vMay2019" => KafkaMappedConnector_vMay2019
|
||||
case "rest_vMar2019" => RestConnector_vMar2019
|
||||
case "msProc_vDec2019" => MsStoredProcedureConnector_vDec2019
|
||||
case "star" => StarConnector
|
||||
case _ => throw new RuntimeException(s"Do not Support this connector version: $connectorVersion")
|
||||
}
|
||||
|
||||
@ -5,8 +5,9 @@ import java.lang.reflect.Method
|
||||
import code.api.util.NewStyle
|
||||
import code.bankconnectors.akka.AkkaConnector_vDec2018
|
||||
import code.bankconnectors.rest.RestConnector_vMar2019
|
||||
import code.bankconnectors.storedprocedure.MsStoredProcedureConnector_vDec2019
|
||||
import code.bankconnectors.vSept2018.KafkaMappedConnector_vSept2018
|
||||
import code.methodrouting.{MethodRouting}
|
||||
import code.methodrouting.MethodRouting
|
||||
import com.openbankproject.commons.model.BankId
|
||||
import com.openbankproject.commons.util.ReflectUtils.{findMethodByArgs, getConstructorArgs}
|
||||
import net.liftweb.common.{Box, EmptyBox}
|
||||
@ -100,6 +101,7 @@ package object bankconnectors {
|
||||
connectorName.getOrElse("mapped") match {
|
||||
case "mapped" => LocalMappedConnector
|
||||
case "rest_vMar2019" => RestConnector_vMar2019
|
||||
case "msProc_vDec2019" => MsStoredProcedureConnector_vDec2019
|
||||
case "kafka_vSept2018" => KafkaMappedConnector_vSept2018
|
||||
case "akka_vDec2018" => AkkaConnector_vDec2018
|
||||
case _ => throw new IllegalStateException(s"config of connector.start.methodName.${methodName} have wrong value, not exists connector of name ${connectorName.get}")
|
||||
|
||||
@ -235,12 +235,10 @@ object RestConnectorBuilder extends App {
|
||||
val end = "//---------------- dynamic end ---------------------please don't modify this line"
|
||||
val placeHolderInSource = s"""(?s)$start.+$end"""
|
||||
val insertCode =
|
||||
s"""
|
||||
|$start
|
||||
s"""$start
|
||||
|// ---------- create on ${new Date()}
|
||||
|${nameSignature.map(_.toString).mkString}
|
||||
|$end
|
||||
""".stripMargin
|
||||
|$end """.stripMargin
|
||||
val newSource = source.replaceFirst(placeHolderInSource, insertCode)
|
||||
FileUtils.writeStringToFile(path, newSource)
|
||||
|
||||
|
||||
@ -0,0 +1,374 @@
|
||||
package code.bankconnectors.storedprocedure
|
||||
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.APIUtil.AdapterImplementation
|
||||
import code.api.util.CallContext
|
||||
import code.api.util.CodeGenerateUtils.createDocExample
|
||||
import code.bankconnectors.Connector
|
||||
import com.openbankproject.commons.util.ReflectUtils
|
||||
import net.liftweb.util.StringHelpers
|
||||
import org.apache.commons.io.FileUtils
|
||||
|
||||
import scala.collection.immutable.List
|
||||
import scala.language.postfixOps
|
||||
import scala.reflect.runtime.universe._
|
||||
import scala.reflect.runtime.{universe => ru}
|
||||
import scala.util.Random
|
||||
|
||||
object MsStoredProcedureConnectorBuilder extends App {
|
||||
// rewrite method code.webuiprops.MappedWebUiPropsProvider#getWebUiPropsValue, avoid access DB cause dataSource not found exception
|
||||
{
|
||||
import javassist.ClassPool
|
||||
val pool = ClassPool.getDefault
|
||||
val ct = pool.getCtClass("code.webuiprops.MappedWebUiPropsProvider$")
|
||||
val m = ct.getDeclaredMethod("getWebUiPropsValue")
|
||||
m.insertBefore("""return ""; """)
|
||||
ct.toClass
|
||||
}
|
||||
|
||||
val genMethodNames = List(
|
||||
"getAdapterInfo",
|
||||
"getChallengeThreshold",
|
||||
"getChargeLevel",
|
||||
"createChallenge",
|
||||
"getBank",
|
||||
"getBanks",
|
||||
"getBankAccountsForUser",
|
||||
"getUser",
|
||||
"getBankAccount",
|
||||
"getBankAccount",
|
||||
"getBankAccountsBalances",
|
||||
"getCoreBankAccounts",
|
||||
"getBankAccountsHeld",
|
||||
"checkBankAccountExists",
|
||||
"getCounterparty",
|
||||
"getCounterpartyTrait",
|
||||
"getCounterpartyByCounterpartyId",
|
||||
"getCounterpartyByIban",
|
||||
"getCounterparties",
|
||||
"getTransactions",
|
||||
"getTransactionsCore",
|
||||
"getTransaction",
|
||||
"getPhysicalCards",
|
||||
"getPhysicalCardForBank",
|
||||
"deletePhysicalCardForBank",
|
||||
"getPhysicalCardsForBank",
|
||||
"createPhysicalCard",
|
||||
"updatePhysicalCard",
|
||||
"makePayment",
|
||||
"makePaymentv200",
|
||||
"makePaymentv210",
|
||||
"makePaymentImpl",
|
||||
"createTransactionRequest",
|
||||
"createTransactionRequestv200",
|
||||
"createTransactionRequestv210",
|
||||
"createTransactionRequestImpl",
|
||||
"createTransactionRequestImpl210",
|
||||
"getTransactionRequests",
|
||||
"getTransactionRequests210",
|
||||
"getTransactionRequestsImpl",
|
||||
"getTransactionRequestsImpl210",
|
||||
"getTransactionRequestImpl",
|
||||
"getTransactionRequestTypesImpl",
|
||||
"createTransactionAfterChallenge",
|
||||
"createTransactionAfterChallengev200",
|
||||
"createTransactionAfterChallengeV210",
|
||||
"updateBankAccount",
|
||||
"createBankAccount",
|
||||
"getProducts",
|
||||
"getProduct",
|
||||
"createOrUpdateBank",
|
||||
"createOrUpdateProduct",
|
||||
"getBranch",
|
||||
"getBranches",
|
||||
"getAtm",
|
||||
"getAtms",
|
||||
"createTransactionAfterChallengev300",
|
||||
"makePaymentv300",
|
||||
"createTransactionRequestv300",
|
||||
"createCounterparty",
|
||||
"checkCustomerNumberAvailable",
|
||||
"createCustomer",
|
||||
"updateCustomerScaData",
|
||||
"updateCustomerCreditData",
|
||||
"updateCustomerGeneralData",
|
||||
"getCustomersByUserId",
|
||||
"getCustomerByCustomerId",
|
||||
"getCustomerByCustomerNumber",
|
||||
"getCustomerAddress",
|
||||
"createCustomerAddress",
|
||||
"updateCustomerAddress",
|
||||
"deleteCustomerAddress",
|
||||
"createTaxResidence",
|
||||
"getTaxResidence",
|
||||
"deleteTaxResidence",
|
||||
"getCustomers",
|
||||
"getCheckbookOrders",
|
||||
"getStatusOfCreditCardOrder",
|
||||
"createUserAuthContext",
|
||||
"createUserAuthContextUpdate",
|
||||
"deleteUserAuthContexts",
|
||||
"deleteUserAuthContextById",
|
||||
"getUserAuthContexts",
|
||||
"createOrUpdateProductAttribute",
|
||||
"getProductAttributeById",
|
||||
"getProductAttributesByBankAndCode",
|
||||
"deleteProductAttribute",
|
||||
"getAccountAttributeById",
|
||||
"createOrUpdateAccountAttribute",
|
||||
"createAccountAttributes",
|
||||
"getAccountAttributesByAccount",
|
||||
"createOrUpdateCardAttribute",
|
||||
"getCardAttributeById",
|
||||
"getCardAttributesFromProvider",
|
||||
"createAccountApplication",
|
||||
"getAllAccountApplication",
|
||||
"getAccountApplicationById",
|
||||
"updateAccountApplicationStatus",
|
||||
"getOrCreateProductCollection",
|
||||
"getProductCollection",
|
||||
"getOrCreateProductCollectionItem",
|
||||
"getProductCollectionItem",
|
||||
"getProductCollectionItemsTree",
|
||||
"createMeeting",
|
||||
"getMeetings",
|
||||
"getMeeting",
|
||||
"createOrUpdateKycCheck",
|
||||
"createOrUpdateKycDocument",
|
||||
"createOrUpdateKycMedia",
|
||||
"createOrUpdateKycStatus",
|
||||
"getKycChecks",
|
||||
"getKycDocuments",
|
||||
"getKycMedias",
|
||||
"getKycStatuses",
|
||||
"createMessage",
|
||||
"makeHistoricalPayment",
|
||||
"validateChallengeAnswer",
|
||||
"getBankLegacy",
|
||||
"getBanksLegacy",
|
||||
"getBankAccountsForUserLegacy",
|
||||
"getBankAccountLegacy",
|
||||
"getBankAccountByIban",
|
||||
"getBankAccountByRouting",
|
||||
"getBankAccounts",
|
||||
"getCoreBankAccountsLegacy",
|
||||
"getBankAccountsHeldLegacy",
|
||||
"checkBankAccountExistsLegacy",
|
||||
"getCounterpartyByCounterpartyIdLegacy",
|
||||
"getCounterpartiesLegacy",
|
||||
"getTransactionsLegacy",
|
||||
"getTransactionLegacy",
|
||||
"getPhysicalCardsForBankLegacy",
|
||||
"createPhysicalCardLegacy",
|
||||
"createBankAccountLegacy",
|
||||
"getBranchLegacy",
|
||||
"getAtmLegacy",
|
||||
"getCustomerByCustomerIdLegacy",
|
||||
|
||||
//** not support methods:
|
||||
//"getStatus",
|
||||
//"getChargeValue",
|
||||
//"saveTransactionRequestTransaction",
|
||||
//"saveTransactionRequestTransactionImpl",
|
||||
//"saveTransactionRequestChallenge",
|
||||
//"saveTransactionRequestChallengeImpl",
|
||||
//"saveTransactionRequestStatusImpl",
|
||||
//"getTransactionRequestStatuses",
|
||||
//"getTransactionRequestStatusesImpl",
|
||||
// "getTransactionRequestTypes", // final method cant be override
|
||||
//"answerTransactionRequestChallenge",
|
||||
// "createBankAndAccount",
|
||||
// "createSandboxBankAccount",
|
||||
// "setAccountHolder",
|
||||
// "accountExists",
|
||||
// "removeAccount",
|
||||
// "getMatchingTransactionCount",
|
||||
// "createImportedTransaction",
|
||||
// "updateAccountBalance",
|
||||
// "setBankAccountLastUpdated",
|
||||
// "updateAccountLabel",
|
||||
// "updateAccount",
|
||||
// "createOrUpdateBranch",
|
||||
// "createOrUpdateAtm",
|
||||
// "createOrUpdateFXRate",
|
||||
// "accountOwnerExists",
|
||||
// "createViews",
|
||||
// "getCurrentFxRate",
|
||||
// "getCurrentFxRateCached",
|
||||
// "getTransactionRequestTypeCharge",
|
||||
// "UpdateUserAccoutViewsByUsername",
|
||||
// "getTransactionRequestTypeCharges",
|
||||
//"updateUserAccountViewsOld",
|
||||
|
||||
// "getEmptyBankAccount", //not useful!
|
||||
// "getCounterpartyFromTransaction", //not useful!
|
||||
// "getCounterpartiesFromTransaction",//not useful!
|
||||
)
|
||||
|
||||
private val mirror: ru.Mirror = ru.runtimeMirror(getClass().getClassLoader)
|
||||
private val clazz: ru.ClassSymbol = ru.typeOf[Connector].typeSymbol.asClass
|
||||
private val classMirror: ru.ClassMirror = mirror.reflectClass(clazz)
|
||||
|
||||
/*
|
||||
find missing OutBound types
|
||||
val a = ru.typeOf[Connector].decls
|
||||
.filter(_.isMethod)
|
||||
.filter(it => genMethodNames.contains(it.name.toString))
|
||||
.map(_.name.toString)
|
||||
.map(it => s"com.openbankproject.commons.dto.OutBound${it.capitalize}")
|
||||
.filter(it => {
|
||||
try {
|
||||
ReflectUtils.getTypeByName(it)
|
||||
false
|
||||
} catch {
|
||||
case _: Throwable => true
|
||||
}
|
||||
}).foreach(it => println(it.replace("com.openbankproject.commons.dto.OutBound", "")))
|
||||
*/
|
||||
|
||||
private val nameSignature = ru.typeOf[Connector].decls
|
||||
.filter(_.isMethod)
|
||||
.filter(it => genMethodNames.contains(it.name.toString))
|
||||
.map(it => {
|
||||
val (methodName, typeSignature) = (it.name.toString, it.typeSignature)
|
||||
MethodBodyGenerator(methodName, typeSignature)
|
||||
})
|
||||
|
||||
|
||||
// private val types: Iterable[ru.Type] = symbols.map(_.typeSignature)
|
||||
// println(symbols)
|
||||
println("-------------------")
|
||||
nameSignature.map(_.toString).foreach(println(_))
|
||||
println("===================")
|
||||
|
||||
val path = new File(getClass.getResource("").toURI.toString.replaceFirst("target/.*", "").replace("file:", ""), "src/main/scala/code/bankconnectors/storedprocedure/MsStoredProcedureConnector_vDec2019.scala")
|
||||
val source = FileUtils.readFileToString(path, "utf-8")
|
||||
val start = "//---------------- dynamic start -------------------please don't modify this line"
|
||||
val end = "//---------------- dynamic end ---------------------please don't modify this line"
|
||||
val placeHolderInSource = s"""(?s)$start.+$end"""
|
||||
val insertCode =
|
||||
s"""$start
|
||||
|// ---------- create on ${new Date()}
|
||||
|${nameSignature.map(_.toString).mkString}
|
||||
|$end """.stripMargin
|
||||
val newSource = source.replaceFirst(placeHolderInSource, insertCode)
|
||||
FileUtils.writeStringToFile(path, newSource, "utf-8")
|
||||
|
||||
// to check whether example is correct.
|
||||
private val tp: ru.Type = ReflectUtils.getTypeByName("com.openbankproject.commons.dto.InBoundGetProductCollectionItemsTree")
|
||||
|
||||
println(createDocExample(tp))
|
||||
}
|
||||
|
||||
|
||||
case class MethodBodyGenerator(methodName: String, tp: Type) {
|
||||
private[this] def paramAnResult = tp.toString
|
||||
.replaceAll("(\\w+\\.)+", "")
|
||||
.replaceFirst("\\)", "): ")
|
||||
.replace("cardAttributeType: Value", "cardAttributeType: CardAttributeType.Value") // scala enum is bad for Reflection
|
||||
.replace("productAttributeType: Value", "productAttributeType: ProductAttributeType.Value") // scala enum is bad for Reflection
|
||||
.replace("accountAttributeType: Value", "accountAttributeType: AccountAttributeType.Value") // scala enum is bad for Reflection
|
||||
.replaceFirst("""\btype\b""", "`type`")
|
||||
|
||||
private[this] val params = tp.paramLists(0).filterNot(_.asTerm.info =:= ru.typeOf[Option[CallContext]]).map(_.name.toString).mkString(", ", ", ", "").replaceFirst("""\btype\b""", "`type`")
|
||||
|
||||
private val procedureName = StringHelpers.snakify(methodName)
|
||||
|
||||
private[this] val description = s"""
|
||||
|| |${methodName.replaceAll("([a-z])([A-Z])", "$1 $2").capitalize}
|
||||
|| |
|
||||
|| |The connector name is: msProc_vDec2019
|
||||
|| |The MS SQL Server stored procedure name is: $procedureName
|
||||
"""
|
||||
|
||||
|
||||
private[this] val entityName = methodName.replaceFirst("^[a-z]+(OrUpdate)?", "")
|
||||
|
||||
private[this] val resultType = tp.resultType.toString.replaceAll("(\\w+\\.)+", "")
|
||||
|
||||
private[this] val isOBPReturnType = resultType.startsWith("OBPReturnType[")
|
||||
|
||||
private[this] val outBoundExample = {
|
||||
var typeName = s"com.openbankproject.commons.dto.OutBound${methodName.capitalize}"
|
||||
val outBoundType = ReflectUtils.getTypeByName(typeName)
|
||||
createDocExample(outBoundType).replaceAll("(?m)^(\\S)", " $1")
|
||||
}
|
||||
private[this] val inBoundExample = {
|
||||
var typeName = s"com.openbankproject.commons.dto.InBound${methodName.capitalize}"
|
||||
val inBoundType = ReflectUtils.getTypeByName(typeName)
|
||||
createDocExample(inBoundType).replaceAll("(?m)^(\\S)", " $1")
|
||||
}
|
||||
|
||||
val signature = s"$methodName$paramAnResult"
|
||||
val urlDemo = s"/$methodName"
|
||||
|
||||
val lastMapStatement = if (isOBPReturnType) {
|
||||
"""|boxedResult match {
|
||||
| case Full(result) => (Full(result.data), buildCallContext(result.inboundAdapterCallContext, callContext))
|
||||
| case result: EmptyBox => (result, callContext) // Empty and Failure all match this case
|
||||
| }
|
||||
""".stripMargin
|
||||
} else {
|
||||
"""|boxedResult.map { result =>
|
||||
| (result.data, buildCallContext(result.inboundAdapterCallContext, callContext))
|
||||
| }
|
||||
""".stripMargin
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all the parameters name as a String from `typeSignature` object.
|
||||
* eg: it will return
|
||||
* , bankId, accountId, accountType, accountLabel, currency, initialBalance, accountHolderName, branchId, accountRoutingScheme, accountRoutingAddress
|
||||
*/
|
||||
private[this] val parametersNamesString = tp.paramLists(0)//paramLists will return all the curry parameters set.
|
||||
.filterNot(_.asTerm.info =:= ru.typeOf[Option[CallContext]]) // remove the `CallContext` field.
|
||||
.map(_.name.toString)//get all parameters name
|
||||
.map(it => if(it =="type") "`type`" else it)//This is special case for `type`, it is the keyword in scala.
|
||||
.map(it => if(it == "queryParams") "OBPQueryParam.getLimit(queryParams), OBPQueryParam.getOffset(queryParams), OBPQueryParam.getFromDate(queryParams), OBPQueryParam.getToDate(queryParams)" else it)
|
||||
match {
|
||||
case Nil => ""
|
||||
case list:List[String] => list.mkString(", ", ", ", "")
|
||||
}
|
||||
|
||||
val inboundDataFieldType = ReflectUtils.getTypeByName(s"com.openbankproject.commons.dto.InBound${methodName.capitalize}")
|
||||
.member(TermName("data")).asMethod
|
||||
.returnType.toString.replaceAll(
|
||||
"""(\w+\.)+(\w+\.Value)|(\w+\.)+(\w+)""", "$2$4"
|
||||
)
|
||||
|
||||
val callContextVal: String = if(tp.paramLists(0).find(_.asTerm.info =:= ru.typeOf[Option[CallContext]]).isEmpty) {
|
||||
"val callContext: Option[CallContext] = None"
|
||||
} else ""
|
||||
|
||||
val randomNum = Random.nextInt(100)
|
||||
override def toString =
|
||||
s"""
|
||||
| messageDocs += ${methodName}Doc$randomNum
|
||||
| private def ${methodName}Doc$randomNum = MessageDoc(
|
||||
| process = "obp.$methodName",
|
||||
| messageFormat = messageFormat,
|
||||
| description = \"\"\"${description}\"\"\".stripMargin,
|
||||
| outboundTopic = None,
|
||||
| inboundTopic = None,
|
||||
| exampleOutboundMessage = (
|
||||
| $outBoundExample
|
||||
| ),
|
||||
| exampleInboundMessage = (
|
||||
| $inBoundExample
|
||||
| ),
|
||||
| adapterImplementation = Some(AdapterImplementation("- Core", 1))
|
||||
| )
|
||||
| // stored procedure name: $procedureName
|
||||
| override def $signature = {
|
||||
| import com.openbankproject.commons.dto.{OutBound${methodName.capitalize} => OutBound, InBound${methodName.capitalize} => InBound}
|
||||
| val procedureName = "$procedureName"
|
||||
| $callContextVal
|
||||
| val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).orNull $parametersNamesString)
|
||||
| val result: OBPReturnType[Box[$inboundDataFieldType]] = sendRequest[InBound](procedureName, req, callContext).map(convertToTuple(callContext))
|
||||
| result
|
||||
| }
|
||||
""".stripMargin
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
||||
package code.bankconnectors.storedprocedure
|
||||
|
||||
import java.sql.PreparedStatement
|
||||
|
||||
import com.openbankproject.commons.model.TopicTrait
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json.JValue
|
||||
import net.liftweb.json.Serialization.write
|
||||
import scalikejdbc.{DB, _}
|
||||
import scalikejdbc.config.DBs
|
||||
|
||||
object MssqlDBUtils {
|
||||
DBs.setupAll()
|
||||
private implicit val formats = code.api.util.CustomJsonFormats.formats
|
||||
private val before: PreparedStatement => Unit = _ => ()
|
||||
|
||||
def callMsProcedure[T: Manifest](procedureName: String, outBound: TopicTrait): T = {
|
||||
val procedureParam: String = write(outBound) // convert OutBound to json string
|
||||
|
||||
var responseJson: String = ""
|
||||
DB autoCommit { implicit session =>
|
||||
|
||||
sql"{ CALL ? (?) }"
|
||||
.bind(procedureName, procedureParam)
|
||||
.executeWithFilters(before,
|
||||
statement => {
|
||||
val resultSet = statement.getResultSet()
|
||||
require(resultSet.next(), s"stored procedure $procedureName must return a json response")
|
||||
responseJson = resultSet.getString(1)
|
||||
}).apply()
|
||||
}
|
||||
if(classOf[JValue].isAssignableFrom(manifest[T].runtimeClass)) {
|
||||
json.parse(responseJson).asInstanceOf[T]
|
||||
} else {
|
||||
json.parse(responseJson).extract[T]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@ -29,7 +29,7 @@
|
||||
<vscaladoc.links.liftweb.baseurl>http://scala-tools.org/mvnsites/liftweb</vscaladoc.links.liftweb.baseurl>
|
||||
|
||||
<!--java version, can be: [8,9,10,11,12,13]-->
|
||||
<java.version>13</java.version>
|
||||
<java.version>8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user